*** /tmp/SIM.doc Tue May 18 01:40:05 1993 --- ./SIM.doc Sat May 8 21:13:53 1993 *************** *** 1,3002 **** ! ------------------------------------------------------------------------------- ! ******* **** ****** * * ******* ! * * * ** ** ** ** ** * * * ! ***** *** ** *** *** ***** ! * * *** ** ******* * * ! *** *** ** ** * ** *** ! * ** ** ** ** ** ** ** ** * ! * **** ** ****** ** ** ** ** * - System-Independent Monitor - Copyright © by Stefan Walter, ALL RIGHTS RESERVED ! ------------------------------------------------------------------------------- - The User Manual, refering to version 1.65 of S.I.M. - beta test version ! -------------- ! READ IT OR DIE ! -------------- - CONTENTS - ======== - 1. Introduction - 1.1 Welcome to SIM - 1.2 About this Documentation - 2. Getting aquainted with SIM - 2.1 What is SIM? - 2.2 Qualifications, Requirements and Limitations - 2.3 Configurating SIM - 2.4 The SIM Program ! 3. Some words about... ! 3.1 The Display ! 3.2 Breakpoints ! 3.3 Trace ! 3.4 The Keyboard ! 3.5 Disk Access ! 3.6 Files ! 3.7 Breaking ! 3.8 The Actual Address ! 3.9 The Matchbuffer ! 3.10 Command History ! 3.11 Traps ! 3.12 Functionkeys ! 3.13 SIM and the Hardware ! 3.14 The Color Red ! 3.15 Printer Support ! 3.16 Memory Managing ! 3.17 Screen Blanker ! 3.18 Effective Address Calculation ! 3.19 Symbols ! 4. Communication between YOU and SIM ! 4.1 The SIM Environement ! 4.2 The Monitor ! 4.3 The Commands and Their Syntax ! 4.4 The Debugger Window ! 4.5 Debugger Window Shortcuts ! 5. Additional Information ! 5.1 Assembler and Calculator Syntax ! 5.2 Line Forms ! 5.3 The Debug Server Entrance ! 5.4 The SIM Base ! 5.5 Errors ! 5.6 Footer Messages ! 6. Greetings, Thanks, Support and about Future Releases ! 6.1 Thanks ! 6.2 Greetings ! 6.3 Support ! 6.4 About Future Releases - Appendix A Functionkeys definition - Appendix B My Address ! ******************************************************************************* ! 1. Introduction ! ******************************************************************************* ! 1.1 Welcome to SIM ! ================== ! Congratulations dear user. You have just become owner of the second release ! of 'S.I.M.', the high performance monitor and debugger for the Commodore ! Amiga, probably the best, the mightiest and the only of its kind. - Version 0.50 of 'S.I.M.' was freeware. This version of 'S.I.M.' is now a - shareware program. This means that it can be used, copied and distributed - freely, provided that: - 1) No fee is charged for copying and distribution. - 2) It is distributed ONLY in its original, unmodified state. - 3) This document is copied along with the program. - If you don't respect these three rules I wish you all the bad things you'd - wish somebody that steals, adds to or misuses something created by yourself - in hours of hard work. So be fair! Only happy programers are good - programers. ! If you copied this version from somebody else and you like it and keep using ! it, you should send me (if you did not yet) 20 SFr or 20DM or 15$ (well, 1g ! gold or half a barrel of oil will also be accepted) shareware fee. This has ! for you the advantage that I will send you the final version on another disk ! as soon as it's finished. - Note: The entire risk of using SIM is to the user himself. In NO event - will the author be liable for direct or indirect damage or loss - resulting from the use of this program. - 1.2 About this Documentation - ============================ ! There exist two very good reasons why you must at least have a look at ! this text: ! 1. I do not question your qualifications and your knowledge of the Amigas ! hardware. But SIM bases on a new concept that offers an universe of ! possibilities but also demands a lot of the user. There are a lot of ! details that will get important at a certain moment, details you'll never ! find out about on your own. It is in your own interest if you read this ! manual. You will then be able to use 90% of the possibilities this ! program offers (sorry, the only one that knows everything about this ! tool, that's me). - 2. It was fun programming SIM, but it was HELL writing this damn manual. - Writing it in german would have been hard enough, but writing it in - a foreign language made it a torture. Good old Woodbird (my former english - teacher) may forgive me all the bad mistakes I did in this text. So you - may honour my sacrifice by reading this, since I do not like to do write - manuals that no one reads. ! ******************************************************************************* ! 2. Getting aquainted with SIM ! ******************************************************************************* - 2.1 What is SIM? - ================ - A good question, isn't it? Well, it's not as easy to give a straight answer - then to ask the question. As you could read in the title, 'S.I.M.' stands - for (S)ystem (I)ndependent (M)onitor. I presume that nearly every programer - working on the AMIGA (intromakers excluded) knows what a 'monitor' is (I do - not mean the device you stare at in this moment!). ! There have been several before, like good old C-Monitor, A-Mon, RomCrack and ! a lot more. During the developement of SIM they served as examples for how to ! do it and how not to do it and how to do it better. I hope that does not ! cause any trouble with copyrights and so on. The result of this compiling ! is an unmatched variety and complexity of commands. This is only a short ! selection of the more spectacular features of SIM: ! - comfortable command editing ! - integrated assembler, disassembler and calculator ! - very powerfull findmechanisms ! - superb breakpoint and trace possibilities ! - parallel printer support ! - freely defineable functionkeys ! - exception control ! - DOS-track and sector read/write operations ! - one-bitplane graphic searcher ! - diskformat ! - file LOAD, SAVE, DELETE and DIR operation ! - copperlist finder and disassembler ! Additionally to the monitor commands, this version disposes of what I call ! 'Debugger Window'. People that are used to Monam2 will welcome it because ! it provides a similarly easy and effective way to overview a program. ! So far nothing new. What makes SIM so powerfull is the way it interacts ! with the AMIGAs hardware and system. SIM tries to be as discreete and as ! independent as it is possible. - On one hand this means that SIM will run under all circumstances. It - does not need anything, no exec, no DOS, no nothing. This capability leaves - a wide field of usages. You could use SIM as last hope to salvage data from - the memory before reset. Or for virus-secure diskoperations since SIM - does it without DOS. - On the other hand discreetion means that S.I.M. will do as less changes in - the software environement (ram, custom registers etc.) as it can. It does - neither use blitter nor copper. This 'invisibility' of SIM makes it - possible to monitor and track a programs to unknown depthts. You can debug - directly into graphic routines, interrupt handlers, diskroutines, task - and memory handling routines without any difficulties and resulting problems. ! I have made some bonebreaking tests with SIM, but it passed them all. ! There is no absolute protection from SIM, it can only be made very hard ! to keep control of a program with SIM, but if you are clever enough, you ! will allways find a way around the problem. ! 2.2 Qualifications, Requirements and Limitations ! ================================================ ! To use SIM efficiently, detailed knowledge of the AMIGAs hardware, ! the 68000 processor and assembler language is ABSOLUTELY neccessary. ! SIM is designed to be used by professionals. ! SIM will work on practically every normal PAL machine, as long as its ! processor is a Motorola 68ooo/7.14 MHz. Other processors (68010/20/30/...) ! are not supported yet, I am sorry about that. These processors are much more ! complicated in their assembler language and exception handling and I do not ! have one of them. ! Different memory configurations and Big/Fat Agnus do not bother SIM. ! Theoretically you'd not even need a kickstart ROM/WOM to run SIM. ! I recommend a fastmem memory expansion of at least half a megabyte at $200000 ! or $c00000. This gets usefull when you want to debug a program that uses the ! entier chip ram. You can then put SIM in fastram which you have disabled ! with one of those resetting nofastmems. ! 2.3 Configurating SIM ! ===================== ! You cant use SIM right away. You have probably noticed that there is ! no file called 'sim' in the package. This has to be created first. ! Therefor you have to use 'SIM-CONFIG'. This program configurates SIM ! with a custom keymap, a font and installs the memory manager. ! The program is selfexplaining except when it comes to define the ! memory pages. Here you shall not joke. First think about what must ! be viewable. That is: ! - chipmem ! - all fastmem expansions ! - kickstart rom ! Get all start and endaddresses and sort them from lowest to highest. ! If you can merge pages then do so. do not define overlapping pages. ! pages must also start and end at even addresses. The program ! 'SIM-CONFIG' does not check for correctness of what you enter. ! If you define incorrect pages, SIM may crash later. In case you do not ! want any memory managing enter $1000000 as first page endaddress. ! You can exit this tool anytime by entering 'exit'. - 2.4 The SIM Program - =================== - SIM is not a conventional program (it has no hunkstructure, so you cannot - simply start it from the CLI or workbench) but a simple PC-relative file - that can be loaded somewhere into the memory or included in one of your - own programs. ! When you work with SIM you must change your way of thinking. The Amiga has ! multitasking. Most debuggers are 'taskoriented'. This means that they debug a ! certain task, and only that one. If another task crashes, they do not notice ! this. SIM is a monotasking debugger. In the eyes of SIM there is only one ! program running on your machine. This one program may splitt up into several ! seperated programs that are 'switched' (the tasks), but it is still one whole ! program. This concept enables you to debug different tasks at a time, and ! even newly generated ones i.e. by createproc(). ! ******************************************************************************* ! 3. Some words about... ! ******************************************************************************* - 3.1 The Display - =============== - The display creates some of the more tricky problems for SIM and you. - As you know, you need 20480/$5000 bytes of chipmem for a medres PAL-bitplane - you want to display. SIM uses a 640*256 bitplane for it's display. But at a - certain moment, there may be no 20480 bytes chipmem available. ! The solution is the backup. When you have an area of $5000 free chipmem ! that will stay free for sure (that means it is allocated with allocmem or ! will never be used), you simply set the display address to the start ! of that area and the backup address to zero (this means no backup). SIM will ! then concider these $5000 bytes its own and use it as display. When you enter ! SIM, the data in this area are then destroyed. ! In case there is not enough free chipmem or the chipmem will be used entierly ! in near future and you have enough (that means $5000 bytes) unused fastmem ! that won't be used for sure (disable fastmem...), you set the backup address ! to the start of a free $5000 block of fastmem and the display address just to ! somewhere in the chipmem. When SIM is activated, It copies the content of the ! $5000 bytes display- to the backupmem and uses the displaymem. When you leave ! SIM again, it copies the $5000 bytes back from the backup- to the displaymem. ! That way, the chip ram is unchanged. ! The memory manager I claimed to be missing in earlier versions ! is now integrated in all functions. If you have defined a backup area ! the memory manager automatically fades it in at the location of the display. ! Because the interrupt vectors are used, you may not specify a display below ! $70 or above $7b000 when you have the normal amount of chipmem (the chipmem ! is reflected at $80000, except if you have fastmem there). ! Both the display- and the backupaddress are entered in the SIM-basearea ! before starting SIM or set by the 's' command while working. - 3.2 Breakpoints - =============== ! A breakpoint is basically a change in the program that is monitored that ! stops it and gives control to the debugger that set it. In other terms, you ! can run the program at full speed until it arrives at a certain instruction. ! This is a very important feature when you have to control the flow of a ! program. Therefore the breakpoint system of SIM is very sophisticated. SIM ! can handle three kinds of breakpoints: - - ILLEGAL breakpoints - - JSR breakpoints - - STACK breakpoints ! Each kind is used for different problems and has its advantages and ! disadvantages. ! SIM is able to handle 16 different breakpoints at a time. When you enter ! SIM, it removes the breakpoints from the memory, so the memory looks like it ! would look with no breakpoints set. That enables you to change instructions ! that are at a breakpoint without first removing the breakpoint before ! changeing and putting it back afterwards. ! A critical situation occurs when the breakpoint is overwritten by a ! program (i.e. by a copyroutine). Such a breakpoint is in 'modified' state ! When SIM removes the breakpoints at entry, it checks if they are still there. ! Modified breakpoints are not removed and not restored, when you leave SIM ! again. If you want to have the modified breakpoint set again, you must first ! 'forget' it (this means that SIM simply frees the place in the breakpoint ! list but does not put the original opcode or words back). Then you can set ! it again. ! You cannot set breakpoints everywhere. SIM tests if there is ram at the ! location where you want to set a breakpoint. If there is none, this causes ! an error. SIM also prohibits to set breakpoints in the SIM codesegment. ! 1. ILLEGAL breakpoints ! ---------------------- - Illegal breakpoints are normally the most used ones and offer the most - possibilities. When you set an ILLEGAL breakpoint at a certain instruction, - SIM replaces the opcode word of that instruction by the ILLEGAL opcode $4afc. - When the ILLEGAL instruction is executed instead of the original instruction, - an ILLEGAL INSTRUCTION exception happens. ! Therefore it is neccessary that the ILLEGAL INSTRUCTION vector somehow jumps ! to SIM, either directly, set by the 'w' command, or indirectly by the task ! traphandle, set by 'SIM-BUG' or another SIM-loader. If this is not so, your ! machine crashes. ! Illegal breakpoints have the advantage that they can be 'conditioned'. ! This means that this breakpoint only forces entry when one or one of several ! conditions are fullfilled. The following criterias can decide whether or ! not the breakpoint forces entry: ! - condition term: - You can specify a formula that is calculated each time when the program - arrives at the breakpoint. When the result of the term is zero, the - program continues, if it is nonzero, SIM is entered. ! You can use that feature to i.e. break a program at a certain point if ! a register contains a certain value. ! - counter breakpoint: ! A counter breakpoint will enter SIM if the program has passed the ! breakpoint a certain number of times. - This way you can i.e. break a subroutine after it was called a certain - number of times. ! - button breakpoint: ! When the program arrives at a button breakpoint, SIM will look if the ! left or right mousebutton or the firebutton of a joystick in port 1 is ! pressed and enter SIM if one is pressed. You can specify what buttons ! are concidered. - Button breakpoints can i.e. be set in a vertical blanking interrupt. - every fiftieth/sixtieth of a second, SIM can check if you want to enter - or not. ! Additionally you can make resident Illegal breakpoints. A nonresident ! breakpoint will be removed after it caused entry. A resident breakpoint ! will stay active until you remove it. A resident breakpoint can be used ! in situations when you want to stop a program several times at the same ! address. ! SIMs breakpoint system enables to combine all these elements, to make ! resident breakpoinst that break at SEVERAL conditions. You can set a resident ! breakpoint at $70000 that either breaks when d3 is 3245 or the left or right ! mousebutton is pressed and that is limited to 1000 passes. The command line ! to set that breakpoint would look like that: 'b 70000 * ?d3=3245 lr 1000'. - You may ask the question how to go over a breakpoint. SIM does this in three - steps: ! - remove the Illegal opcode and put back the original one. ! - do a tracestep to execute the instruction. ! - remember the (possibly new) opcode and set the $4afc again. - As you see, SIM uses the TRACE vector to ignore a breakpoint. This means - that you must not only set the ILLEGAL INSTRUCTION vector but also the - TRACE vector. This is neccessary as soon as you have set a conditioned or - a resident breakpoint. ! 2. JSR breakpoints ! ------------------ ! The second type of breakpoint is a rather a 'heavy duty' one. When you ! set a JSR breakpoint, SIM remembers the 6 bytes at the breakpoint address ! and puts a JSR instruction there that jumps absolutely into SIM (i.e. ! 'JSR $c50726'). When the breakpoint is reached, the program jumps ! directly into SIM which then puts back the 6 bytes. ! This breakpoint has two advantages. The first is that you do not need any ! vectors to be set. The second is that a JSR breakpoint can be transfered. ! When you have an Illegal breakpoint in a routine and that routine is ! transfered to another location and the breakpoint is reached in the ! copied routine, SIM will not know that that illegal is a breakpoint ! because it is not at any of the addresses at which a breakpoint was set, ! so it will not be replaced by the original opcode. ! JSR breakpoints are recognized at their entrance, because each of the 16 ! possible JSR breakpoints has another entrance. That way, SIM can recognize ! that breakpoint whereever it is. But be carefull, never enter SIM by ! these entrances on your own. You must also see to it that after the ! transfered breakpoint forced entry and was removed, the original one is ! NOT reached too. ! Because of these two advantages, you can use JSR breakpoints in delicate ! situations, where you are not sure if the vectors are not changed. - A disadvantage of JSR breakpoints is that they use not one but three - words. The minimum size for an instruction is a word, an Illegal - breakpoint can be set at any instruction because the instruction ILLEGAL - uses one word. A JSR breakpoint may replace three instructions. Therefore - you have to set the JSR breakpoint in a 'linearly' executed part of the - program. Here are two examples where the JSR breakpoint is not set - correctly. The breakpoint is always set at the label 'bkpt': ! 1. . ! . ! . ! bsr.s label ;this bsr would jump in the middle of the breakpoint! ! bkpt: ! bra.s label2 ;JSR opcode ! label: ! nop ;HIword of entrance ! nop ;LO word of entrance ! . ! . ! . ! 2. . ! . ! . ! bkpt: ! moveq #1,d0 ;JSR opcode ! label: ! moveq #0,d1 ;HI word of entrance ! rts ;LO word of entrance ! . ! . ! . ! moveq #-1,d0 ! bra.s label ;again in the middle... ! 3. Stack breakpoints ! -------------------- ! Contrarily to the Illegal and JSR breakpoint, the Stack breakpoint is ! not a change in the program but a change on the Stack. When SIM sets a ! Stack breakpoint, it replaces a returnaddress on the stack by the address ! of an entrance of SIM. When the appropriate rts, rtr or rte that would ! return to that address is reached, it returns to SIM instead. SIM sets the ! pc to the returnaddress and replaces the SIM entrance address on the stack ! (should now be at a7-4!) by the original address for security. ! For SIM, it does not differe, if the Stack breakpoint is set in the ! supervisor or userstack (in earlier versions it did, this is no longer ! so). - Use this feature wisely! SIM cannot test if the Stack breakpoint you set - is put in a stack and is taken off stack by a rts. Its upon you to set Stack - breakpoints at the right position. - Stack breakpoints are also used by for the nextstep and the leave - subroutine command. ! 3.3 Trace ! ========= ! Tracing is the second way of keeping a program under control. SIM can ! singlestep a program. Therefore you must see that the TRACE exception caused ! by that somehow ends up in SIM, either set it directly or set the ! tasktraphandle. It can also let a program run step by step and stop when ! one or several conditions are fullfilled, much like the illegal breakpoints: ! - condition term: ! You can specify a formula that is calculated after each step. When the ! result of the term is zero, the trace continues, if it is nonzero, ! SIM is entered. - You can use that feature to i.e. break a program as soon as a certain - register is changed. ! - counter trace: ! You can specify a maximum number of steps to do. When that amount of steps ! is done, SIM is entered. - Counter trace is mostly use to just get back after a routine is done. ! - button trace: ! After each step, SIM will look if the left or right mousebutton or the ! firebutton of a joystick in port 1 is pressed and enter SIM if one is ! pressed. You can specify what buttons are concidered. - Button trace can i.e. be used for stoping a program by hand at any moment. ! - trace breakpoint: ! You can define an address that is compared to the PC after each step. ! If the program has arrived at that address, SIM is entered. - This feature is used when you cannot use breakpoints for some reasons. ! - 68020 emulation: - This is also a condition. SIM is only entered when a change in the flow - would happen, this means that the pc points on a BRA, JMP etc. ! I do not know what this is for, but people like it. ! SIM uses the trace flag to do single steps. What some people do not know is ! that you can trace over some instructions that may clear that flag. These are ! RTE ! MOVE to SR ! ORI #x,SR ! EORI #x,SR ! ANDI #x,SR ! Additionally you can enter the TRAP #x exception routines with the trace. - Tracing has one weak spot: if you are tracing and an interrupt happens that - somehow causes entry in SIM (i.e. by a breakpoint), SIM loses the control - over the trace. When you exit SIM again and the interrupt ends, a TRACE - exception happens. You must then start to trace again or clear the trace flag - by hand. - Some words about the speed: It is clear that the more conditions you allow, - the slower the program runs. Additionally some conditions cause longer delays - than others. Condition trace is slower than button trace because it has to - call the calculator which is relatively complex and slow. - 3.4 The Keyboard - ================ ! The most difficult problems are imposed by the keyboard. The Amigas keyboard ! hardware cannot tell you which keys are pressed at a certain moment, it ! reports only key changes. This makes it difficult for systemindependent ! programs. When you press a key under system and release it in a program ! that has its own keyboardhandler, the system will never know that you ! released that key, it will report repeats of that key all the time until you ! press another key. To prevent this, SIM will look that all keys are in the ! same state when you leave SIM as they were in when you entered SIM. When you ! leave SIM and a key is not in the same state, SIM will ask you to either ! press that key or to release it. Therefore, in the headline you will find the ! keys rawkey number and if in the keymap there is a printable char, that char ! too. You can only exit SIM if you press or release all keys that it wants ! you to. - If you leave SIM by accident (hit wrong key?) and you are requested to - press/release a key, you can do the following operation to return to the - monitor: ! - press another key that is not a qualifier (shift etc.), not 'r', 'e', 't', ! 'u', 'n' or one that you must press to exit (esc is a good choice). ! - release all other keys ! - type 'return' ! - release the keys you pressed for that operation - If you are tired to press keys again and again to exit, you can use the - flush keystatefield shortcut. SIM will then clear the internal list of - keys that were pressed when SIM was activated. ! As you know, the keyboard can store upto ten rawkeys on its own if ! the CPU has no time or need to get keyboard events. It is possible ! that several key hits are waiting to be replied. When SIM is activated ! then, it would recieve all those old keys that may invoke shortcuts or ! commands that are not desired. Similar problems occur when you link SIM ! in the CIA-A interrupt and it is invoked before the key is replied. The ! keyboardbuffer killer is used to reply to all possibly waiting keys and ! to flush the keyboard buffer. This feature can be toggled on or off. ! - 3.5 Disk Access - =============== ! Because ram is a too transitory datacarier, SIM can read and write ! DOS-tracks and sectors. It does this by directly accessing the hardware. ! Unfortunately, I know only one way to find out if a drive is running or ! not: To activate the drive and look if its on full speed with no delay. ! This system is only working when the running drives have a disk inserted. ! If no disk is in a running drive and you access disk, it will be stoped ! after disk access. - When SIM is writing or reading, the display is used as buffer. You still - see it, but it contains chaos. The top line is used to give you status - information about the track that is operated or errors occured. ! When an error occures, you can either break with CTRL, retry with SHIFT ! or ignore the error with ALT (when file operation, ALT=CTRL). ! When a track is not correct, SIM tries to read it three times. Then it ! reports the error but displays also which sectors were okay. It is ! possible that only one sector is damaged, press SHIFT several times, SIM ! may find some sectores more that are okay and simply were after the damaged ! sector last time. ! SIM is tollerant concerning the integrity of the sectors. Checksums are ! calculated and SIM reports an error if one is wrong, but it decodes the ! sector anyway. This enables SIM to reapair partially destroyed tracks. ! 3.6 Files ! ========= - The capabilitys of SIM to read, list and write files are some of its newest - and most usefull features. You can load any files of a DOS disk, also - from user directories to memory. You can list the files and their length - contained in any directory. And you can save any area of memory as a file - on a disk. ! The file save system is quite sophisticated. It writes files in a way ! that they can be loaded and listed fast. Info- and extension blocks are ! located on track 79 and higher, data blocks from 79 down to 0 and from 159 ! to 79. Additionally, SIM will first look if a file fits the disk before ! it begins to save. The bad sideeffect of this is that saving takes some time. - One thing you must remember is to be carefull with saving files when you - work with the normal operating system afterwards. When you save a file, - the bitmap on the disk is changed. The system keeps its own copy of the - bitmap of a disk in memory. When it accesses that disk again, it possibly - discovers a totally different bitmap. When it comes to the worst, the DOS - crashes with the guru 07000007 (bitmap corrupt). To prevent this, you - simply remove that disk from its drive and put it back again. The DOS - then rereads the bitmap and everything's okay. ! 3.7 Breaking ! ============ - In certain situations, it may be neccessary to break an operation or to - pause it. SIM can both. You can break the dump commands, find and compare - by shortly hitting CTRL. If you press it longer, SIM only pauses and - continues when you release CTRL. When you press SHIFT-CTRL or additionaly - hit the SHIFT key when you pause, SIM locks until you release, press and - relese CTRL again. This enables you i.e. to make notes without holding - CTRL all the time. ! While locked or paused, you can press the ALT key. When you release CTRL ! (if locked, press it first), SIM breaks also. This is used when you have ! paused and want to stop immediately. - ALT-CTRL is used to break command execution in general. Before SIM looks - for a new command in a command line, it tests for ALT-CTRL. If that's so, - it breaks. This enables you to break a commandline like 'P0:X' since you - cannot break the 'P' and 'X' commands. ! An exception to this rules are the disk operation and the list directory ! command. These commands can only be broken. Therefore simply keep the CTRL ! key pressed until SIM gets it. ! 3.8 The Actual Address ! ====================== - The dump and edit commands share a default address variable that is used - each time, you do not give a startaddress. This address has the name '@' - for the calculator. It contains the endaddress of the last dump or edit - command or it is set by find and compare. ! 3.9 The Matchbuffer ! =================== - The matchbuffer is used to collect addresses. You can force the find and - compare commands to put the addresses they report into this buffer. Well, - this is nothing special. But you can also say under what conditions an - address is put in the buffer or one that is allready in buffer stays there. - There are three possible conditions: - - old: If an address that was allready in buffer did not match with any - reported by the find or compare command, it only stays in the - buffer when you enable oldies. ! - match: If an address that is reported is allready somewhere in the buffer, ! it stays only when you enable matches. - - new: If an address is new, it is only put in the buffer when you enable - new ones. ! You can combine the three conditions in any way (there are eight possible), ! some may make not much sence. ! This feature enables you to search for counters or changes. ! To show the addresses in the buffer, the 'k' command is used. ! An example: you are searching for the livecounter in a game. You have five ! lives: ! 1. define matchbuffer, i.e. 'k c00000 c10000' ! 2. search for 5, i.e. 'f 0 20000 !n 05' ! 3. exit and die once ! 4. search for 4, i.e. 'f 0 20000 !m 04' ! If you are lucky, one address stays in the matchbuffer ! 5. list addresse(s) in matchbuffer, i.e. 'k 0' ! 6. if neccessary go to step 3 and search for one live less ! 3.10 Command History ! ==================== ! SIM remembers the last commands executed in the monitor. I reserved 128 bytes ! for that. These 128 bytes contain the last packed command lines that fit. ! If you get an old command line back by the command history shortcuts and ! execute it, it is not remembered as the newest executed command. ! 3.11 Traps ! ========== ! The traps are one of the major connections of sim to the outer world. They are ! used for breakpoints and to handle crashes. You can set the ten basic ! exception vectors directly. When you enter SIM, it puts back the original ! vectors, so you can edit them. When exited, SIM sets the set traps again. ! Problems occure when the program that is debugged sets the traps itself. ! When the program changes a vector previously set by SIM, this is handled the ! same way as it is done with changed breakpoints. ! Additionally you can force SIM to set traps again if they are modified by ! toggeling 'Auto Unmodify Traps' on. ! 3.12 Functionkeys ! ================= ! You can define all ten functionkeys with a text or command line. If you define ! a text, it is copied at the location of the cursor. If you define a command ! line, it is executed directly. - The system used bases much on the one used by the Sharp PC-1500, thanks to - Sharp for that. - The functionkeys share 300 bytes of 'intelligent' textbuffer with the - condition breakpoints and linkterms. ! 3.13 SIM and the Hardware ! ========================= ! SIM does only use a very limited part of the hardware registers, the ones ! that are indispensable or must be set on fix values to provide security. ! Some of these registers can be read, some not. The values of the readable ! ones are remembered in a special part of SIM called 'SIM base' when SIM is ! activated. The SIM base is located, as its name says, at the start of SIM. ! In chapter 6.1 you find the structure of the base. ! These are the registers that are read out and stored in the base at entry. ! When you exit SIM, it copies the remembered values back: - - DMACON - - INTENA - - INTREQ *) ! - Level 2 interrupt ! - Level 3 interrupt - - CIA-A: CRA - - CIA-A: CRB - - CIA-B: CRA - - CIA-B: CRB ! - CIA-A: PRA write buffer ! - CIA-A: PRB write buffer ! - CIA-A: DDRA ! - CIA-A: DDRB ! - CIA-B: DDRA - - CIA-A: SR write buffer ! - VPOS **) ! All these registers are used by SIM when working. If you have to know ! what vaule was in one of those, you have to look in the SIM base where SIM ! remembered them. ! *) This register is handled in a special way. While SIM is active, it leaves ! the disk-DMA switched on. If it wouldn't, this would possibly destroy your ! disks. Now since the disk-DMA is left on, remember that when the disk-DMA is ! terminated, bit 1 in the INTREQ is set. But this may happen during SIM is ! active because the DMA was still transfering when the INTREQ was read. Therefore ! you will find only the interrupt requests in the backup that were waiting ! when SIM was activated. If you want to know abaout the actual ones, you must ! read out INTREQR using the calculator command '?[$dff09c].w'. ! When you exit and didn't edit the INTREQ backup, SIM does not restore ! the bits EXTER, DSKSYN, RBF, AUDX, DSKBLK and TBE from the backup. If you ! edited the backup, the bits that are changed are restored , even if they ! contain some of the bits named above. ! **) This value is not written back. SIM rather waits for the rasterbeam ! to be aproximately at that position that it was on when the register was ! read. The register is read at a late point of time when SIM is activated, ! quite some instructions have been executed then, so it is not very precise. ! I hope I can improve that. - As I quoted, some of the custom register contain information that is lost - because SIM cannot read from these registers. For the more important - ones, SIM disposes of an editable list of 'reentry' values which it puts - back when exiting. Those registers are: ! - DIWSTRT ! - DIWSTOP ! - DDFSTRT ! - DDFSTOP ! - BPLCON0 ! - BPLCON1 ! - BPLMOD1 ! - COLOR00 ! - COLOR01 ! As you see, these registers all concern the display. In most cases, they ! are reset anyway by a copperlist. If not, you have to look in the program ! where it sets them for the initial value and enter it in the base or decide ! on your own what value to use. ! Some of the registers are modified but do not have a reentry value, ! because they are either too temporary (DSKPTX for example) or compleetely ! unimportant (BPL1PTX). If it becomes neccessary, you can edit some with ! the 'e' command: ! - CLXDAT ! - DSKBTR *) ! - DSKPTX *) ! - DSKLEN *) ! - DSKSYNC *) ! - BPL1PTX ! - BPL1DAT ! - SPRXDATA/B ! - CIAA: ICR state and mask ! *) these registers are only used and changed when you read or write from or ! to disk. ! 3.14 The Color Red ! ================== ! When you start to use SIM quite often and in critical situations, it may ! happen that the text color of SIM, which normally is green, turns red. ! This means that the SIM code has been partially changed. SIM calculates ! a checksum over its main code segment and looks if it is the same each time. ! If not, it changes the color to red. ! When the color is red you must be rather carefull. SIM seems to run well but ! it may crash when you execute a certain command or do something else. If ! you can, load a new copy and don't keep using the destroyed one. ! 3.15 Printer Support ! ==================== - SIM allows you to send all output on the monitor to the printer. Therefor it - simply sends the text as ASCII codes to the parallel port. This should allow - you to use practically any parallel printer. If you want to send ESC codes - (to select NLQ, reset etc.) you can do this by entering CTRL-[ and the rest - of the ESC code as a command and press return. Remember to use the printer - specific codes and not the AMIGA specific ones. ! 3.16 Memory Managing ! ==================== ! SIM now disposes of the memory manager that was missing in v1.51. It does ! these things: - It fades in the backup of the display at the location of the display. ! If there is no backup it zeroes the display. ! - At $68 and $6c it inserts the level 2 and level 3 vectors. ! - It handles five pages of memory that can be read and written to. Other areas are zeroed. ! The memory manager is supported by all functions that access memory. ! - 3.17 Screen Blanker - =================== - When you do not press any key during 10 minutes and SIM is not doing any - operation, it automatically darkens the monitor. - 3.18 Effective Address Calculation - ================================== - SIM can now calculate effective addresses. The source EA of the command at - the PC is displayed below A6 of the registerlist, the destination EA below - A7. Further use of this new capability has not yet been made, but it sure - leaves a wide field of powerfull features to be made. - 3.19 Symbols - ============ ! SIM supports no a symbol list generated by SIMBUG. If a program contains ! symbol hunks, the symbols contained inthere are put into a list. Symbols ! are used in the calculator and the disassembler. ! ******************************************************************************* 4. Communication between YOU and SIM ! ******************************************************************************* - 4.1 The SIM Environement - ======================== - As I quoted in the chapter about the display, SIM provides its own. It is - basically used for all output SIM produces (leave alone the printer and - disk). ! You have a PAL display of 256*640 pixels or 32 lines and 80 rows. The ! screens colors are green and dark blue but may be set by you to any colors ! you like. The screen is devided in header, worktable/debugger window and ! footer, all seperated by a line of '­'. ! The header normally contains the title and copyrights but serves also as ! statusline when accessing disk and keyboard cleanup. ! The worktable and the debugger window share 28 lines. ! - In the worktable, actually the monitor, you can move the cursor around ! and enter commands and get output. ! - The debugger window shows you one or two views of the memory in different ! forms at different addresses, read more about that feature in the ! appropriate chapter. ! The footer contains the cause of SIM's entry, a status and result field ! and the addresses of SIM itself, the display- and backupaddresses. - 4.2 The Monitor - =============== ! On the worktable, several basic features are provided: - - What you see on the monitor (the text) is stored in SIM, when you leave - and enter again, the display will be the same. ! - SIM has two entier keymaps for not qualified, ! shifted, alternated and shifted+alternated keys, one USA and one custom. ! In the original version, the custom one is Swiss. ! - Ctrl+chars with ascii values from $40-$60 will cause a char from ! $0-$20 (i.e. 'J' (=$4a) => (=$a)) ! - Ctrl+chars with ascii values from $60-$80 will cause a char from ! $80-$a0 ! - The cursor can be moved around one char by pressing the cursor keys. ! - The cursor can be moved to the extreme positions by pressing ! +cursor keys (i.e. +cursor right => cursor in row 79) - - will delete the char above the cursor and shift all chars right - of the cursor one row left, inserting a space at row 79 - - will clear the char left of the cursor and shift all chars - above and right of the cursor one row left. - - + will insert a space at the cursor position and shift all - chars above and right of the cursor one row right. ! - + will clear the char above the cursor move the ! cursor one row left ! - + will clear the monitor part and put the cursor in the left ! upper corner next to a point. ! - + will clear the line in which the cursor is, put a '.' in ! row 1 and the cursor in row 2. ! - prints the first helppage, starting in the line below the line the ! cursor is in actually. ! - prints the second helppage. ! - : you can freely define the ten function keys. ! - + copies the last executed command in the line of the ! cursor. ! - + copies the line of the cursor in the command ! buffer. It can then be inserted anywhere by +. - - will execute the commands in the actual line (the one in which - the cursor is). - - goes one step back in command history and fill the actual - line with the actuall command in history. - - goes one step forth in command history. ! You can execute commands by entering them in one line and pressing ! return. When all commands are executed, SIM looks if a point '.' is in ! row 0 of the actual line. If so, the cursor is set left of it and the ! line is not cleared. If no point is found there, SIM puts one there ! and clears the rest of the line. That way, the point signals wheather or ! not a line is a previous command line. That enables to use again the ! commands that have been entered earlier and are still visible on the ! screen. - 4.3 The Commands and Their Syntax - ================================= - As mentioned earlier, SIM understands a vast number of commands. - While working in SIM, you can get a little overview of them in the two - helppages: - n (s)(i) :assemble | t [s][e][t] :transfer mem | A (s) :set viewstart - e (s)(d) :edit mem | o [s][e][d] :occupy mem | w (x) :CPU traps - d (s)(e) :disassemble | c (s)(e)(t) :compare mem | v (x) :create trap - a (s)(e) :show ascii | f (sejd)(m) :find data | h (n) :history - m (s)(e) :show hex | f (sej'i'i) :find disasm | g [s] :go sub - l (s)(e) :show copper | s (p)(b)(c) :set SIM-adrs | i (n) :leave out - p (s)(e) :show text | F (n)(c){@} :edit F-keys | u :next step - k (s)(e) :matchbuffer | z (n*n?cb) :trace steps | r (rs):edit regs - P (s)(m) :show plane | b (s)(*n?b) :breakpoints | q/Q :quit prog - ? (expr) :calculate | T (expr){@} :set linkterm | x/X :exit and go - and - >f(n) :format disk | s [s][b](n) :write secs - D?(n) :find head | t [s][t](n) :write tracks - K [s] :blockchksum | L [fs](n)(s):load file - V (path) :directory | S [f][s][e] :save file - In the helppage and the explanations, the following shortenings are used for - options: ! s: (start)address/seek e: endaddress t: targetaddress/track ! i: assembler instructions d: dataline c: a text or SIM commands ! n: decimal number x: hexadecimal number m: mask/modulo ! r: register p: plane b: backup/breakmode/block ! ?: condition term f: file j: jokers - Options in '[]' are neccessary. - Options in '()' are optional. - Chars in '{}' serve as sign or flag. ! Because space in SIM is limited, these helppages tell only the basic ! syntax of a command. Here comes a short but detailed list of all commands ! and what they do: ! Dump Commands ! ------------- ! m (s)(e) : print memory as hexdump ! a (s)(e) : print memory as asciidump ! d (s)(e) : disassemble memory ! l (s)(e) : interprete memory as copperlist ! p (s)(e) : print memory as text - Dump commands have all the same options, only the output changes: ! command (startaddress) (endaddress) ! If you give both addresses, SIM starts to dump from the startaddress and ! stops when the endaddress is reached or passed over. ! If you give only the startaddress, SIM starts to dump from that address ! and calculates an endaddress. That endaddress will be: - for 'm': start+128 - for 'a': start+512 - for 'd': start+32 - for 'l': start+32 - for 'p': start+eight lines - If you do not give any address, SIM takes the actual address as - startaddress. - Do not try to dump the customregisters area. ! In the disassembly, the instructions BSR,JSR and TRAP #x are indented ! and after the instructions JMP, BRA, ILLEGAL, RTS, RTE, RTR and RESET a ! line of '-' is printed for seperation. Additionally, breakpoints are ! marked by an asterix. - EXAMPLES: ! m 0 100 ! a 100 ! d ! l 51236 !+60 ! p $25364 ! Edit Commands ! ------------- - e (s)(d) : edit memory - n (s)(n) : assemle ! You can modify the memory with these two commands. They both ignore the ! memory manager and write diectly to memory. ! The edit command can write data at a location in the memory (see chapter ! 'line forms' for details) - The assemle command can assemble one or more instructions seperated by a - ',' at a location in memory (see chapter 'Assembler and Calculator' for - info) - If you give both startaddress and data/instructions, SIM simply edits - the memory. - If you only give the startaddress, SIM will start to assemble or edit in - a continuous mode where it allways prepares the next line for further data - or instructions. To stop this simply give no instruction or data. The - system is as clever as it recognices if in the line it prepares for a new - data or assemble line, there is already a data or assemble line that was - prepared for continuous mode. If that is so, it only updates the address - but does not clear the line. That enables you to i.e. correct a program - assembled in continuous mode and to insert instructions. ! If you do not give any option, SIM starts to edit/assemble in continuous ! mode at the actual address. - EXAMPLES: ! e 70000 ! e>00070000: 0121 ! n 100 nop ! Transfer and Occupy ! ------------------- ! t (s)(e)(t) : Transfer memory ! o (s)(e)(d) : Occupy memory - Transfer: ! This command simply copies a part of the memory to another location smartly. ! This means that SIM uses as- or descending mode for copying, not to destroy ! the memory: ! - t [s][e][t] : Transfers memory from s to e at new address t ! Occpuy: ! Occupy is generaly used to clear the memory or to fill it with repeated data: ! - o [s][e][d] : Occupy memory from s to e with data d - EXAMPLES: - t 0 10000 c00000 - o 12564 !+60 nnop ! Find and Compare ! ---------------- ! f (s)(e)(j)(d)(m) - find data ! f (s)(e)(j) i (i) - find disassembly ! c (s)(e)(t)(j) - compare memory ! k {@}(s)(e) - show/set matchbuffer - SIM disposes of a sophisticated find and compare system. For any of the - three you can specify some jokers: - - +/-n : Sets a step, only at every nth address is searched or compared. - - '*' : To say that all addresses where nothing was found or two bytes - are the same are reported. - - '@' : When you do not want a list of addresses but to have them reported - one by one, set this joker. SIM will then execute F9 each time - something is reported and put the active view of the debugger - window at that address. - - '!' : If you want to collect and filter addresses with the matchbuffer, - set this flag. After the '!' you can enter an 'o' to say that old - ones stay, a 'm' to say that same addresses stay, or a 'n' to say - that new ones stay. Combinations are allowed. ! Find data: - You can search in a defined area in the memory for a certain bytecombination - with this command. Depending of how many options you enter, the command does - different things: ! - f [s][e](j)[d][m] : Starts to find from s to e with the jokers j for ! the bytes d that are masked by the mask m. Only the bits that are set in m ! are concidered when comparing. If the mask is shorter than the data, the ! rest of the mask will be set to $ff - - f [s][e](j)[d] :Starts to search for data with all bits set in the mask. ! - f [s][e](j) : Starts to find for the same data with the same mask as last ! time in the area from s to e with new jokers j. ! - f [s][e] : Searches again in the area from s to e. - - f [s] : Starts to search from s to the last e. ! - f : Continues to find after the last address reported. ! Find disassembly: ! You can find an instruction or a fragment of it in a defined are in the ! memory. Like find data, find disassembly does not need all options: - - f [s][e](j) i [i] : Starts to find from s to e with jokers j for the - instruction i. ! - f [s][e](j) : Starts to find for the same instruction in the area ! from s to e with new jokers j. - - f [s][e] : Searches again in the area from s to e. ! - f [s] : Starts to search from s to the last e. ! - f : Continues to find after the last address reported. ! The instruction i can be only a fragment like '4(a6)' or an entier ! instruction like 'moveq #3,d0'. Several things must be made right: ! - When you have entered a space, SIM will concider what is before the ! space to be the mnemonic. Because the disassembler leaves an eight ! chars large field for the mnemonic where the rest is filled with ! spaces, SIM does tabulate your entries. 'clr.l d0' will internally ! made to 'clr.l d0'. ! - The char '*' is used as joker. It says that this char is not compared. ! I.e. '(a*)' searches for all indirect accesses with any address register. ! - The char '_' is replaced by a space. I.e. '_d0' searches for ! all accesses on d0 as source ea. - - The char '@' at the start or the end of your fragment limits the - search on the start or end of the fragment. I.e. '@st' finds only - 'st.b d0' but not 'tst.l d3'. - Compare: - You can compare two areas in the memory. Different amount of options for - different results: - - c [s][e][t](j) : Compares area from s to e with area t to (t+(e-s)) with - jokers j. ! - c [s][e][t] : Compares with no jokers. ! - c [s][t] : Continues to compare from s with t. ! - c [s] : Compares from s to last e with last t ! - c : Continues to compare after last address reported. ! Matchbuffer: ! You can read out or define the matchbuffer: - - k [s][e] : Defines a new matchbuffer from s to e and clears it. ! - k * : Clears matchbuffer. ! - k ? : Shows you where the matchbuffer is. ! - k @ [s] : Shows all matchbuffer entries larger than s by reporting ! them one by one over F9. - - k [s] : Lists all entries higher than s - - k : Lists or shows next entrie(s) ! EXAMPLES: ! f 0 100 00 ! f 10000 20000 !nm 05 ! f 0 20000 @ imoveq #*,d* ! c 0 100 200 * ! k 100 ! k@ 0 ! Processor Commands ! ------------------ - r (r)(x) : set/view registers - w (x) : set/view traps - v (x) : create trap ! Registers: ! The 'r' command is used to either set a register d0-d7, a0-a7, ssp, usp, pc, ! sr, m0-m7 or to view them: - - r [r][x] : Sets register r vith new value x - - r : Views registers - - r? : Views memories m0-m7 ! Trapsetting: - The 'w' command is used to either set or clear the ten basic CPU exception - vectors or to view their status: - - w [x] : Sets or clears Vector x - - w : Lists status of vectors - - wk : Clears all traps - You can set or clear several vectors at a time by seperating the vector - numbers by kommas. The vector numbers correspond to the exception numbers, 2 - for bus error upto $b for linef. ! Trapcreating: - The 'v' command is used to simulate the occurence of an exception or to - remove one from the stack: - - v [x] : Simulates exception x - - v [-x] : Removes exception x from stack - - v : Simulates occurence of same exception that forced entry - - v? : Gives information about trap that forced entry - SIM can simulate exceptions 2 upto $40. When you simulate an address or bus - error, SIM takes either the ssw, ir and aa from the last bus or address - error or zero for all when none happened yet. - When you simulate an exception 2 upto $b, which is set by the 'w' command, - SIM takes the old vector as new pc. - When you simulate an interrupt, the sr will also contain the interrupt - level. - The 'v' command without options is used to put an exception back on the - stack when i.e. you want the old vector to handle the problem. This works - only if SIM was entered by one of the exceptions. - You can only remove traps from the stack when you are in supervisor mode. - The vector number is only used to know how much has to be taken from the - stack (14 bytes when 2 or 3, 6 for the rest). ! The 'v?' command is used to know more about the exception, especially ! address and bus errors. ! EXAMPLES: - r pc pc+20 - r m7 d0 - r? - w 4,9 - wk - v 3 - v -3 - v? ! Breakpoints and Trace ! --------------------- ! b (s)(j) : set/clear breakpoints ! u : nextstep ! z (j) : tracestep ! i (n) : leave out instructions ! Breakpoints: - The 'b' command is used to handle breakpoints. Different options are - available: - - b [s][j] : Sets a breakpoint at address s with the options: - - 'l' or 'r' or 'f' : button breakpoint - - [n] : counter breakpoint - - '?' [n] : condition breakpoint - - '*' : resident breakpoint ! - b [s] : Sets a simple breakpoint ! - b : Lists all breakpoints - - bj [s] : Sets a JSR breakpoint at s ! - bs [s] : Sets a STACK breakpoint at s ! - bk : Kills all breakpoints - You can seperate several breakpoints at a time by seperating the next - address from the previous address or options by a komma. - Trace: - The 'z' command executes tracesteps. It either stops after one step or when - a certain condition is fullfilled: - - z [j] : Does trace until: ! - 'l' or 'r' or 'f' : trace until button pressed ! - [n] : trace n steps ! - '?' [n] : trace until n not zero ! - '*' [s] : trace until pc=s ! - 'c' : emulate 68020 trace ! - z : Does one tracestep ! Nextstep: ! The 'u' command does either one tracestep or when it is done at a JSR, BSR ! or TRAP #x, it does also a tracestep and sets a stack breakpoint at a7 ! (or a7+2 when TRAP) and exits: - - u : Do one nextstep ! Leave Out: - This simply leaves instructions away: - - i [n] : Leaves out n instructions - - i : Leaves out one instruction ! EXAMPLES: - b 100 *j100 ?[4]<>$c00276 - bj 100,200 - bssp - z *pc - z j - n - i 2 ! Flow ! ---- - x : Exit - X : Exit directly - q : Quit - Q : Quit directly - g [s] : go to subroutine - h (n) : history ! Exit: - The 'x' or 'X' commands are used to simply continue the program at full - speed. 'x' asks first if you are sure, 'X' simply exits: - - x : Exits, but asks for confirmation first - - X : Exits directly ! Quit: - The 'q' or 'Q' commands are used to return control to the debug server. - 'q' asks first if you are sure, 'Q' simply returs directly: - - q : Quits, but asks for confirmation first - - Q : Quits directly - Gosub: - The 'g' command is used to execute a little program from SIM: - - g [s] : goes to subroutine at s ! - gw [s] : goes to subroutine at s but does not exit yet - When SIM goes to subroutine, it first pushes the old pc on the stack and then - the return address for the rts. ! The 'gw' command does only prepare the stack for the operation but does not ! exit yet. This is i.e. used to trace a subroutine. ! History: ! SIM remembers the last five sets of registers as they were when SIM was left ! for the last five times. The list is also updated after each step when doing ! conditioned trace: - - h [n] : Print nth last history ! - h : Print all five histories ! SIM does not only remember the registers d0-a6, usp, ssp, sr and pc but ! also the instruction at the pc because of selfmodifying code. ! EXAMPLES: - h 3 - X - q - g 100 - gw 200 - Diskoperations - -------------- - D (n) : set drive - t (s)(s)(n) : write track - s (s)(s)(n) : write sector - >f (n) : format disk - B (s) : bootchecksum - K (s) : blockchecksum - Set Drive: ! The 'D' command is used to set the drive number that is used for further ! diskoperations (tracks, sectors or format, but not fot file operations!) ! or to ask for the actually used drive or to ask for the position of the ! head of a drive: ! - D [n] : Takes drive n (0-3) as actual drive - - D : Shows actual drive ! - D? [n] : finds position of head of drive n ! - D? : finds position of head of actual drive - The headposition is reported as logical track, the sideselect bit will be - concidered when calculating the position. In most cases (DOS included) - the sideselect bit will be set directly before DMA access and put to an - undefined state afterwards. If that is so when you use this command, you - must find the side that is used on your own, analyze the diskroutines. - Read Track: - The 't' command writes an area of the memory as logical tracks on disk: ! - >t [s][t][n] : Writes n tracks starting with t, data start at s - - >t [s][t] : Writes one track t, data start at s - Read Sector: ! With the 's' command you can write single sectors from disk to memory: ! - f' command is used to format and initialize a disk: - - >f [n] : Formats disk in drive n ! - >f : Formats disk in actual drive ! You can't yet enter a name for the disk, it will automatically be ! 'DATA-DISK'. The creation date is zeroed too. But the DOS cannot seperate ! disks with the same name and same date. So never keep two datadisks ! in two drives simultaneously, your machine would crash if you do so. - If you format a disk that was previously in a drive and you return to DOS, - remove and reinsert that disk for the DOS must know the new name and new - bitmap. - Bootchecksum: - When you want to save a bootblock on a disk, you may have to update the - checksum with this command: - - B [s] : Sets new checksum of bootblock that starts at s ! Blockchecksum: - When you want to save an edited datablock on a disk, you may have to update - the checksum with this command: ! - K [s] : Sets new checksum of block that starts at s ! EXAMPLES: ! t c00000 0 80 ! >s 70000 0 2 ! f 0 ! B 60000 ! K 70000 - Fileoperations - -------------- - L [f][s](n)(s) : Load file - S [f][s][e] : Save file - V (path) : List directory ! Paths and filenames can either be given plainly or between ' or ". ! The only devices known are DF0:, DF1:, DF2: and DF3:, disknames ! are not supported. ! Load File: - This command loads a file directly into memory: - - L [f][s] : Loads file f to s - - L [f][s](n) : Loads n bytes from file f to s ! - L [f][s](n)(s) : Loads n bytes from file f to s, s bytes from the ! start of the file ! Just make sure that you don't load files over SIM or the display. ! Save file: - With this command you can save an area of the memory as file: - - S [f][s][e] : Saves memory from s to e as file f - This command is also used to delete files. To do so simply save a file - with the name of the file you want to delete and the same start- and - endaddress (filelength=0). ! List Directory: - This command is used to list the directory of a disk or a user directory. - - V [path] : Lists directory of directory specified by path. - - V : Lists directory of last drive used for fileoperations. - SIM reads the directory page by page because the display is used as buffer. - If a page is full or the directory is read, it displays it. If there stays - stuff to be displayed, SIM writes 'more' in the footer. You can then continue - by pressing . - EXAMPLES: - L 'df0:c/dir' 60000 - S df1:data 0 100 - V df0:c ! Miscellaneous ! ------------- - ? [n]{,}(n) : Calculate - F (n)(c){@} : Define functionkeys - P (s)(m) : Start graphic searcher - H [s][e](p) : Hear sound - s (p)(b)(c) : Set display, backup and program addresses - l* : Show copperlist - l? (s)(e) : Find active copperlist - l= [n] : Find copperlist one or two - Calculator: ! If you need to calculate something, you can do it with the '?' command. ! SIM will calculate the result of one or several terms and return the ! result(s) as hexadecimal, signed hexadecimal, decimal and binary number ! and as ascii chars: ! - ? [n] : calculate result of n - You can calculate the result of several terms at the same time by seperating - the terms by a komma. ! Functionkeys: ! The 'F' command is used to set and view the functionkeys functions: - - F [n][c] @ : Occupies Fkey n with commandline c that is executed directly - - F [n][c] : Occupies Fkey n with text c - - F [n] : Clears Fkey n - - F : Lists Fkeys ! When you set a functionkey, the entier rest of the commandline will be ! taken for the command or text. - When you list the functionkeys, the ones that are locked by Amiga-Fx are - marked by an asterix, the directly executable have an '@' at the end. - Graphic Searcher: ! The 'P' command starts the graphic searcher: ! - P [s][m] : Starts at address s with modulo m ! - P [s] : Starts at address s with last modulo ! - P : Starts at last address with last modulo - When you have activated the graphic searcher, several keys are used for - display modifications: ! Cursor up: Scrolls plane one line down - Cursor down: Scrolls plane one line up ! Cursor left: Scrolls plane one line right ! Cursor right: Scrolls plane one line left - Shift+Cursor up: Scrolls plane one screen down - Shift+Cursor down: Scrolls plane one screen up - Help: Modulo=modulo+2 ! Del: Modulo=modulo-2 ! Shift+Help: Modulo=modulo+16 - Shift+Del: Modulo=modulo-16 ! Backspace: Modulo=0 ! Return: Switches between hires and lores - Control: Ends graphic searcher - Since the graphic searcher also supports the memory manager a further - improvement has been made. It is now possible not only to look at the - chipmem but at the entier 16 MBytes of addressable memory including fastmem - and rom. - Because of technical reasons the status bar is now located at the bottom. - It has also become neccessary to limit the modulo. It can now range from - $ffb2 to $7ffe for a hires and from $ffda to $7ffe for a lores plane. ! Hear Sound: ! The 'H' command makes you listen to parts of the memory. - H [s][e](p) : Hear memory from s to e with period p - H [s][e] : Hear memory from s to e with last period - Memory manager is supported. - SIM Addresses: - The 's' command is used to transfer the display and backup and the SIM - code itself: - s [p][b][c] : New display at p, new backup at b and SIM copied to c - s [p][b] : New display at p, new backup at b and SIM stays where it is - s [p] : New display at p, backup and program stay where they are - s : Repaints the display - Be carefull when you transfer the SIM code. SIM does adjust breakpoint and - traps to the new address. But a possible debug server will only know - about the new location when you quit. The old copy of SIM will still work, - but its breakpoint and trap system will be confused. The same problem - occurs when the tasktraphandle is set to SIM. Use this command only when - the system is dead. Also do not copy SIM below $70! - Copperlist: ! The 'l' command is basically used to disassemble a copperlist. The ! following variations are used for different actions: - - l* : Shows the active copperlist ! - l? [s][e] : Starts to search for the copperlist from s to e ! - l? [s] : Starts to search for the copperlist from s to $80000 - - l? : Starts to search for the copperlist from $70 to $80000 ! - l= [n] : Starts to search quickly for copperlist 1 or 2 - To end copperlist display or searching, press . ! When you search quickly, the copperlist you are looking for will be ! activated. If this one is not the running one, search again for the other to ! set the other copperlist again. This kind of searching has the risk that you ! may search for a copperlist that does not exist. - EXAMPLES: - ? 256*5,52*56 - F10 r:dpc pc@ - F - P 12356 52 - s 70000 c50000 c40000 - l* - l=1 - l? 20000 ! Debugger Window Support ! ----------------------- - A [s] : Set new startaddress - T [s]{@} : Set linkterm ! These two commands are used to set new startaddresses for the views of ! the debugger window. ! Startaddress: - With this command you can directly set the startaddress of the active view: ! - A [s] : Set new startaddress of view to s - Linkterm: - To set a linkterm for a view, you use the 'T' command. SIM will calculate - the result of this formula and use it as new startaddress each time it is - entered: - - T [s] @ : Set smart linkterm for active view ! - T [s] : Set simple linkterm for active view ! When SIM calculates a simple linkterm, it takes the result as new ! startaddress. The result of a smart linkterm is only used as new startaddress ! if it is not in the frame of the view. Normally this is only used to link ! a view to the PC. ! EXAMPLES: ! A a0+56 ! T a0+d0 ! T pc @ ! 4.4 The Debugger Window ! ======================= ! This is one of the later achievements done. You can switch it on or off by ! pressing . When you do so, a part of the worktable is locked for the ! cursor and used to print out the registers and one or two different ! views of the memory in different forms (hex, ascii etc.). The window is ! updated as soon as you execute a command that may change the memory and ! at entry of SIM. ! The two views have two startaddresses that are stored in m0 and m1. ! m1 is unused when you did not splitt the window and use only one view. ! You can link the two views to two formulas, the socalled 'linkterms'. ! 4.5 Debugger Window Shortcuts ! ============================= ! If you have to deal with the window, you do this by use of shortcuts that ! are qualified by either left or right Amiga. If you splitted the window, ! you can select the view that recieves the command by pressing . ! Window Handling ! --------------- ! Decreases the views startaddress and scrolls the ! content one line down. How much the startaddress is decreased ! depends on what the window output form is: ! - disassembly: the length of the instruction above the ! startaddress. ! - hexdump: 16 bytes. ! - asciidump: 64 bytes. ! - copperdump: 4 bytes. ! - text: one line. ! Increases the views startaddress and scrolls the ! content one line up. How much the startaddress is decreased ! depends on what the window output form is: - - disassembly: the length of the instruction at the - actual startaddress. - - hexdump: 16 bytes. - - asciidump: 64 bytes. - - copperdump: 4 bytes. - - text: one line. ! Decreases the views startaddress one or two bytes: ! - disassembly: two bytes. ! - hexdump: one byte. ! - asciidump: one byte. ! - copperdump: two bytes. ! - text: one byte. - Increases the views startaddress one or two bytes: - - disassembly: two bytes. - - hexdump: one byte. - - asciidump: one byte. - - copperdump: two bytes. - - text: one byte. - Decreases the views startaddress and moves back to last - page, depending on the output form: ! - disassembly: the sum of instruction lengths of the number ! of instructions fitting the window back from the actual ! startaddress. ! - hexdump: *16 bytes. ! - asciidump: *64 bytes. ! - copperdump: *4 bytes. ! - text: one page. ! Increases the views startaddress and moves to next ! page, depending on the output form: - - disassembly: sets startaddress to the address of the - instruction following the last one visible. - - hexdump: *16 bytes. - - asciidump: *64 bytes. - - copperdump: *4 bytes. - - text: one page. ! Decreases the size of the debugger window by one line. ! The minimum size is one line. The space that becomes free ! for the monitor is cleared with spaces. ! Increases the size of the debugger window by one line. ! The maximum size is as large as there stays one line for the ! monitor. If the cursor was in the line now belonging to the ! debugger window, it is moved to the line below which is then ! initialized. - Works only when you splitted the window. This moves the bar - seperating the two views one line up, which decreases the - upper view and increases the lower view one line. ! Works only when you splitted the window. This moves the bar ! seperating the two views one line down, which increases the ! upper view and decreases the lower view one line. - Splitts or unsplitts the window into two views. When you - unsplitt, the startaddress and linkterm of the active view - are taken as the one of the now single view, the ones of the - inactive view are stored and taken as the ones for the second - view when you splitt again. - This recalculates the linkterm(s) and sets the - views startaddresses again. ! Output Form Selection ! --------------------- ! Selects asciidump for the active view. ! Selects hexdump for the active view. ! Selects copperdump for the active view. ! Selects disassembly for the active view. !

Selects text for the active view. - disassemble with symbols. ! set symbols also for $xxxx(An) - Breakpoints - ----------- - Sets a simple Illegal breakpoint at the startaddress of - the active view. - Sets a resident Illegal breakpoint at the startaddress of - the active view. ! Sets a JSR-breakpoint at the startaddress of the active view. - Flow - ---- ! Does a tracestep. - Does a nextstep that does not follow into subroutines. ! Leaves out one instruction/puts pc to next instruction. ! Exits SIM. ! Exits SIM and goes back to debug server. ! Leaves a subroutine. Therefore SIM puts a STACK-breakpoint at ! the actual stackpointer and exits. Do not use this when the ! subroutine has allready put more data on the stack. This ! corresponds to the command 'bssp:X'. - Sets the pc to the startaddress of the active view. ! Edit ! ---- ! Starts to edit in loopmode at the startaddress of the ! active view. - Starts to assemble in loopmode at the startaddress of the - active view. - Replaces the Instruction at the startaddress of the active - view by NOPs. ! Indirects ! --------- ! <[> Goes to next higher indirectlevel and takes the longword ! at the startaddress of the active view as the new ! startaddress and stores the old one. - <]> Goes to last indirectlevel and takes the stored - startaddress as the new one. ! <{> Same as <[> but the longword will be taken as BCPL and ! multiplied by four. - <}> Goes to next higher indirectlevel and takes the stored - address of that one as the new startaddress. - Find - ---- ! Continues to search at the startaddress of the active ! view. ! Continues to compare. The source address will be the ! startaddress of the first view , the destination address ! the startaddress of the second view. - Miscellaneous - ------------- -

Toggles the printer on/off. The printer can only be - activated if there is an active one connected to the parallel - port. - Makes a hardcopy of the actual display by printing it as - text. You do not have to activate the printer first. - Toggles between US keymap and custom keymap (originally CH) - Flushes keystatefield, see chapter 'the keyboard'. ! Toggles keyboardbuffer killer, see chapter 'the keyboard' - <+> Toggles fully printable charset. When switched on (full), the - chars $0-$1f and $80-$9f are not replaced by a point in - asciidump, hexdump etc. Switch it off (semi) when using the - printer because else these chars would trouble it. ! <\> Toggles Auto-Unmodify Traps. When this feature is switched ! on, all modified traps are set again when you leave SIM. - Toggles availability of funktionkeys. ! <0-9> Takes one of the ten position memories as the startaddress ! of the active view. ! Works only with the keypad! Stores the startaddress of the ! active view in one of the ten position memories. - Most of these shortcuts are only functioning when the debugger window is - activated. Only ,

,,,,,,,, and - are allways functioning. - ******************************************************************************* - 5. Additional Information - ******************************************************************************* ! 5.1 Assembler and Calculator Syntax ! =================================== ! The assembler used in SIM is entierly home-made and is fully ! motorola compatible. Anyway, some special features have been added ! to increase userfriendlyness: - - You can use 'add' instead of 'addi', 'adda' and 'addx -(ax),-(ay)' - This is also valuable for 'sub'. - - 'cmpm', 'cmpi' and 'cmpa' can be replaced by 'cmp' - - You can use 'eor' instead of 'eori'. This also works with 'and' and 'or' ! - Bcc xxxx, DBcc Dx,xxxx, xxxx(PC) and xx(PC,Rx) use absoulute addresses. ! This means that when you want to have a code like ! 60010: bra $60000 - you can enter 'bra $60000'. If you want to give the offset directly, - you have to put a '+' or a '-' in front of it: - 60010: bra -$12 - But remember: The Offset has allways to be: - (targetaddress-instructionaddress+2) - - If no size is given, Bcc will be short if possible. - - If no size given, direct addresses are word if possible. - - DC.W or DC.L can be used, but only one value is allowed. - - If you do not give an instruction size, the default size is - taken, which in most cases is WORD. ! - The interpreter is very tollerant, even a line like - move.l ( $75 ) ( PC , D7.l ) , ( $4 ).w ! will be accepted and assembled correctly. - ------------------- - The calculator used in SIM is also entierly home-made. It disposes - of several very useful operations and value forms. The calculator is used - when you have to enter a number. Just have an overview of the operations - supported, sorted by their priority: ! [] - A value in these brackets will be used as an address and the ! content of the memory at that address will be taken. - A size directly after the closing bracket will define if - the value will be taken as a BYTE, WORD or LONG and extended - to LONG. For example: [4].l gets the execbase ($676 or $c00276) - [$dff002].w reads out the actual DMACON as a WORD. - - - Prefix change: Changes a positive value to a negative and vice - versa. - ~ - Logical NOT: Changes the state of all 32 bits of the value. - For example: ~5 is -6. - .s - Size a value: Any value will be extended to LONG from the size you - define. For example: $89.b will then be made to $ffffff89. - The size given is also important for the assembler when using direct - long or short address. - *,/ - Multiply or divide long, considering if the values are positiv - or negativ. For example: -$56*5 is fffffe52. - \ - Gets the modulo of a long division. For example: 11\4 is 3. ! +,- - Addition or Subtraction, allways long. - << - Shift value left: this corresponds to a multiplication with 2 - to the nth power, whereas n is the numer of bits to be shifted. - For example: $20<<8 is $2000. ! >> - Shift value right: this corresponds to a division by 2 ! to the nth power, whereas n is the numer of bits to be shifted. ! For example: $2000>>8 is $20. ! & - Logical AND. ! ! - Logical Exlusive OR ! | - Logical OR ! <> - Not equal: If the two values are not equal, this returns true ! (=$ffffffff), otherwise false (=0). ! = - Equal: If two vales are equal, this returns true. ! <= - Less or equal: Returns true, if the first value is less than ! the other or at least equal. ! => - Higher or equal: Returns true, if the first value is higher than ! the other or at least equal. ! > - Higher: Returns true, if the first value is higher than the other. ! < - Less: Returns true, if the first value is less than the other. ! As for the forms of values, SIM understands these: - $x - Hexadecimal number: A number in hexadecimal form - consisting of max. 8 digits 0-9 and a-f. - #x - Decimal number: A number in decimal form - consisting of digits 0-9. - %x - Binary number: A number in binary form - consisting of max. 32 digits 0 and 1. - "/' - ASCII chars: A number consisting of max. 4 ASCII chars. - f.e.: "SIM!" or '!MIS' - ! - Stands for the last result. This enables you to do things - like: m 61f35 !+39dc = "Show memory from $61f35 to $61f35 - plus 39dc". ! @ - Stands for the actual address. This is the address, SIM uses as ! standart workaddress for dump commands. - SIM - The program and base address of SIM ! D0-D7,A0-A7,PC,SP,SSP,USP,SR,CCR and M0-M7 - The registers. The calculator ! can directly use the content of these registers. SSP is the supervisor ! stack pointer, USP the userstack pointer SP and A7 the actual stack ! pointer. I.E. when you are tracing a program, and you want to know, ! what is at the address 56(a0,d7.w), you can use 'm 56+a0+d7.w'. ! The end of a term is usualy set by a space, a komma, a semikolon, a ! doubble point or a . Actually, when you have opened a bracket, you ! can have spaces between operators and values, but ONLY then. Otherwise, the ! end of the term will not be there where you wanted. ! Not to forget: some 120 brackets are allowed, more than you will ever use. ! Actually the calculator can work in decimal or hexadecimal mode. ! In decimal mode you do not have to write the '#' before a decimal number, ! but for hexadecimal numbers, the '$' is neccessary. ! In hexadecimal mode you do not have to write the '$' before a hexadecimal ! number, but for decimal numbers, the '#' is neccessary. ! Hexadecimal mode is usually used to get addresses (s,e,t,b,p) ! or hexnumbers (x). For all other cases decimal mode is used, also for ! assembler. - 5.2 Line Forms - ============== - There are two types of lines you have to differe: the command line - and the data line. - - The command line is the one that contains the different commands - you want to execute. This line has usualy that form: - . (: ...) ! You see, you can enter several commands in one line, seperated by a ! doubble point. The doubble point is needed, except if the next char is ! the same as of the last executed command (i.e. 'mmmm' is allowed and shows ! $200 bytes at once, starting at the actual address). ! - The data line is of another kind. Whenever you have to enter datas ! directly, for edit, find, occupy etc., you enter a data line. This ! dataline can consist of this four elements, allways seperated by a komma: ! - Hexnumbers: Are introduced with or without '$'. They can be as long as ! you want. The hexnumber is ended by a char that is no number and ! not 'A','B','C','D','E' or 'F' (lower case letters also included) ! If you enter an odd number of digits, the last digit will be taken as ! byte, its higher nibble zeroed. Spaces are allowed between digits. ! - Assembler instructions: Are initiated by a 'n', then the instruction ! follows. - - Calculator terms: Are initiated by a '?', then the term follows. - The size of the result will be considered (LONG=4 bytes,WORD=2 bytes - and BYTE=1 byte). - - Ascii chars: Are either initiated by ' or " and closed with the - same or a . - Now an example, using all the elements from above. You enter: - 45,"BDH",njmp $60000,?[$fc0000].w,6666 - And the result are these 14 bytes: - 45 42 44 48 4e f9 00 06 00 00 11 11 66 66 - |- |------- |---------------- |---- |---- - | | | | | - 45 "BDH" jmp $60000 [$fc0000].w 6666 - A dataline ends at a space or an illegal char. Between the komma that - seperates two datatypes and the next datatype there can be spaces. also - between hexdigits (only when editing, not find and occupy). ! 5.3 The Debug Server Entrance ! ============================= ! The debug server entrance is specially concieved for the cooperation ! between SIM and another debugger or loader, i.e. SIM-BUG. It enables ! The debug server to give control over a program to SIM and SIM to return ! control to the debug server. ! How this is done? Well, in a part of the SIM base, there is space to store ! the registers d0-a6, USP and SSP, SR and PC of the program that is ! monitored. The debug server can fill in this table. Additionally, It can ! specify a reentry PC, SR, USP and SSP. When it enters SIM by the debug ! server entrance, SIM takes the registers out of the table and copies them ! into the workregister buffer. SIM has now the control over the program. ! Now, when you are in SIM and want to give control back to the debug ! server, you can use the 'q' command (or 'Q' or AMIGA-q). SIM does then ! copy the workregisters back into the base area and takes the reentry PC, SR ! USP and SSP as the actual ones. To be sure that the debug server is still ! there, SIM looks at the address if the longword $4f4b4159 ! ("OKAY") is there. If the longword is there, it exits. That way, it returns ! to the address specified by the reentry PC with reentry stacks and a reentry ! SR. The registers do not contain sencefull information, appart a6 which ! contains the base/codeaddress of SIM. In case you transfered SIM, the ! debug server knows where you put it. ! The debug server can now read out the table with the registers and use ! them for itself. - 5.4 The SIM Base - ================ - At the start of the SIM program, the differente entrances are located, - the backups and reentry values and the debug server datastructure. The - structure of this base is documented here. The offsets described won't - be changed in higher versions, I hope, but I feel free to extend it at - the upper end. - -------------------------------------------------------------------------------- - The S.I.M. Base Structure - -------------------------------------------------------------------------------- ;--- Base --------- ! struct toolbase ;+0 The startadress of S.I.M. in memory ;--- Display ------ ! aptr plane ;+0 The startaddress of the $5000 bytes display ram ! (must be chipmem!) ! aptr backup ;+4 The startaddress of the backup of the display. ! When not zero, S.I.M. will copy what is in the ! memory of the future display to this part of memory when entered and copy it back when left. ;--- Entrances ---- ! jmp entrance1 ;+8 Entrance for JSR. Here you can simply enter S.I.M. by a 'JSR' to this address. ! jmp entrance2 ;+12 Entrance for Exec's traphandle. When you want to ! use S.I.M. as traphandler of your task, write this address to . ! jmp entrance3 ;+16 Debug server entrance. ! long 0 ;+20 *** RESERVED FOR EXPANSION *** ! ;--- Our Traps ---- ;When a trap is set directly, its vector is set to ! the corresponding entrance in here. ! jmp entrance22 ;+24 Bus error ! jmp entrance23 ;+28 Address error ! jmp entrance24 ;+32 Illegal instruction ! jmp entrance25 ;+36 Divide-by-zero ! jmp entrance26 ;+40 CHK instruction ! jmp entrance27 ;+44 TRAPV instruction ! jmp entrance28 ;+48 Privilege violation ! jmp entrance29 ;+52 Trace ! jmp entrance2a ;+56 Op Code 1010 ! jmp entrance2b ;+60 Op Code 1111 ;--- Signal ------- ! long "SIM!" ;+64 This Long signals that this is S.I.M. ! long version ;+68 Version of S.I.M. as 4 ASCII chars ! ;--- Backups ------ ;when S.I.M. is entered it backups some customregisters ! and vectors here. ! word dmacon ;+72 $DFF096/002 ! word intena ;+74 $DFF09A/01C ! word intreq ;+76 $DFF09C/01E ! long level2 ;+78 $68 ! long level3 ;+82 $6C ! ! byte ciaacra ;+86 $BFEE01 ! byte ciaacrb ;+87 $BFEF01 ! byte ciabcra ;+88 $BFDE00 ! byte ciabcrb ;+89 $BFDF00 ! byte ciaapra ;+90 $BFE001 ! byte ciaaprb ;+91 $BFE101 ! byte ciaaddra ;+92 $BFE201 ! byte ciaaddrb ;+93 $BFE301 ! byte ciabddra ;+94 $BFD200 ! byte ciaasp ;+95 $BFEC01 ! long vpos ;+96 $DFF004 ;--- Reentry ------ ;Reentry values of things that can't be saved. ! When S.I.M. is left, it inits the registers named ! with the values in this list. - word $2981 ;+100 DIWSTRT - word $29c1 ;+102 DIWSTOP - word $0038 ;+104 DDFSTRT - word $00d0 ;+106 DDFSTOP - word $5200 ;+108 BPLCON0 - word $0000 ;+110 BPLCON1 - word $0000 ;+112 BPLMOD1 - word $0000 ;+114 COLOR00 - word $0000 ;+116 COLOR01 ;--- ICR Special -- ;The ICR data and mask. ! byte lasticr ;+118 $BFED00 read ! byte reentryicrmask ;+119 $BFED00 write ;--- Distances ---- ;Distances to internal structures. ! long disasscalc-base ;+120 Distance to disasscalc module ! long preferences-base;+124 Distance to preference structure ;--- Debug -------- ;Debug server structure for entrance 3. ! long 0 ;+128 Offset from base to end of inited part ! long "????" ;+132 Sign of server ;--- Program ------ ;The registers of the program that is debugged. ! long 0 ;+136 Register d0 ! long 0 ;+140 Register d1 ! long 0 ;+144 Register d2 ! long 0 ;+148 Register d3 ! long 0 ;+152 Register d4 ! long 0 ;+156 Register d5 ! long 0 ;+160 Register d6 ! long 0 ;+164 Register d7 ! long 0 ;+168 Register a0 ! long 0 ;+172 Register a1 ! long 0 ;+176 Register a2 ! long 0 ;+180 Register a3 ! long 0 ;+184 Register a4 ! long 0 ;+188 Register a5 ! long 0 ;+192 Register a6 ! long 0 ;+196 User stack pointer ! long 0 ;+200 Supervisor stack pointer ! long 0 ;+204 PC of program ! word 0 ;+208 SR of program ;--- Server data -- ! long 0 ;+210 Reentry routine of server ! long 0 ;+214 Reentry usp of server ! long 0 ;+218 Reentry ssp of server ! long 0 ;+222 Reentry sr of server ;--- Extension ---- ! aptr 0 ;+224 Pointer to zero ended list of aptrs that point to zero ended texts. The texts in this list are printed and the pointer is cleared ! aptr 0 ;+228 Pointer to task structure, currently unused ! aptr 0 ;+232 Segmentlist, currently unused ! aptr 0 ;+236 Symbollist with labels, currently unused ! ;--- End ---------- ;+240 This is the end of the actual structure ! -------------------------------------------------------------------------------- ! 5.5 Errors ! ========== ! SIM is a flexible tool. Therefore the user can do many mistakes. ! In this chapter, all errors are explained. When an error occurs that ! bases on an error in the command line (which in fact is in most cases so) ! SIM prints the error text in the line of the cursor and copies the command ! line in the next line. The cursor is in the line of the copied command line ! below the char or the word that probably caused the error. ! Assembler errors: ! illegal instruction: ! The assembler does not know this instruction. - illegal value: - An number is higher or less than it should be. - illegal ea: - This 'effective address' is not allowed. In fact it has not allways - to be an effective address for the assembler uses the same routine for - all source- and destinationterms. - illegal size: - An instruction has either no size at all or does not support the - one you have given. - illegal operator: - An operator is not just as it should be. - line malformed: - Something is undefinably wrong. - too few info: - Some part of this instruction is missing. - illegal sea: - An illegal effective address as source. ! illegal tea: ! An illegal effective address as destination. - illegal char: - The assembler is suprised to find that char. ! illegal condition: ! The condition of a Bcc, DBcc or Scc is inexistent. ! illegal direction: ! The direction for bitshifting is neither left nor right. ! Calculator errors: ! bracketerror: ! You have opened more brackets than you closed or vice versa. ! overflow: ! The result is larger than $ffffffff or ±$8000000, or you ! have divided by zero or you do more than 30 operations. ! illegal value: ! The calculator cannot interprete that as a number. ! illegal operator: ! This is no operator for mathematical operations supported by the ! calculator. ! no value given: ! You have forgotten to give a term, or the very first value of an ! expected term is of an unknown type. ! SIM errors: ! too much: ! The startaddres given for a command is higher than the endaddress. - breakpointerror: - SIM has no more breakpoints free or it could not set a breakpoint there, - either because ROM is read only or it is not possible to put breakpoints - in the memory presently occupied by the SIM code. - Diskaccess errors: - disk error: - Something went wrong with the diskaccess, either the track that is read - is damaged or the disk was writeprotected. In most cases you will get a - warning in the statusline of the diskaccess display. - file not found: - SIM could not locate the file you want to load or a directory in its path. - not enough space: - When you want to save a file, SIM first checks if the file would fit. - If it wouldn't, this error is returned. ! disk full: ! That error should not occure. - directory error: - If something goes wrong in the line of the listing of the directory, - i.e. bad hashes or disk damaged, this error is returned. ! illegal path: ! SIM cannot locate the directory you want to list. ! 5.6 Footer Messages ! =================== - As mentioned earlier there is a status field in the footer line. This - space is used to transmit messages to the user that are not as important as - to be printed in the monitor or serve as additional information. - Currently the following texts can appear down there when something happens: - - busy : As soon as SIM is doing something this text is printed. - This shows you If SIM is working or not. - - break : When you break the execution of a command SIM replys with - this message. ! - pause : When you pause. - - lock : When you press SHIFT-CTRL to stop all output for some time. ! - Fx on/off : When you toggle function keys SIM returns the new state ! to you this way. - - flushed : When you flush the keystatefield. ! - prt err : when the printer has troubble (paper out/select...) ! - cnd err : when an error occurs while calculating the condition terms ! of breakpoints or trace, SIM is entered and this text ! appears ! - prt on/off : When you toggle the printer and it is available. ! - AUT on/off : When you toggle Auto Unmodify Traps ! - US kmap : When you select the secondary (USA) keymap ! - xx kmap : When you select the primary (custom) keymap ! - indir x : When you use indirects the current indirect level ! is told you so. ! - return : When you return from the keyboard restoring routine ! by entering 'return'. ! - KBF on/off : When you toggle the Keyboard Buffer Killer. ! - more : When the directory of a disk does not fit in the monitor ! part SIM writes that message to tell you that there is more. ! ******************************************************************************* ! 6. Greetings, Thanks, Support and about Future Releases ! ******************************************************************************* ! 6.1 Thanks ! ========== ! Big thanks must go to my friend Daniel Weber for continuous testing of all ! new features I inserted, some good and some bad ideas and severe criticism ! of all the work I did. ! Thanks must also go to all the other people who reported me their ideas ! and gave bugreports: Christian Schneider, André Dietisheim, Oliver Ferlin, ! Stefan Strasser. ! Also to Yello, Depeche Mode, Kitaro, Star Inc., Mike Oldfield, Guru Josh, ! Enigma, New Order, Vangelis, J.M. Jarre, Harold Faltermeyer, Art of Noise, ! Alan Parson Project, Die Toten Hosen and Megatron for cool background music. ! 6.2 Greetings ! ============= ! Greetings go to all members of my crew, to my few contacts, to the makers of ! Amiga Action Replay (especially Lord Olaf), to SCA (for the RomCrack), ! to Graftgold for converting Rainbow Islands and to all Beerbrewers (for ! beeing). - 6.3 Support - =========== - The following is a short list of products supporting SIM. - - FlyMon (assembler monitor) ! - NOG2 (trap- and exceptionhandler) - - ProAsm (integrated editor/assembler/debugger) ! - SIM-BUG (SIM loader) - - SysOp (System Monitor) ! You are welcome to contact me if you want detailed information about how to ! support SIM correctly in your own programs. If you code a program that will ! support SIM, you are also welcome to tell me so, not only because the list ! would become longer, but also because the tools that may dispose of SIM ! support are surely of a kind I like and will use. ! 6.4 About Future Releases ! ========================= ! Version 1.63 is definitely not the ultimate release of SIM, there is a lot ! of room for improvements and new features. My intention is to make a version ! 2.00, a realy final one that will be PERFECT. Unfortunately, I will not have ! much time for that until October 1991, it may take quite some time for it to ! be released. The People who send me the money for this version, and only ! those, will get it as soon as its finished. ! ******************************************************************************* ! Appendix A Functionkeys definition ! ******************************************************************************* - The ten functionkeys are partially allready defined in the original - SIM version. These are the definitions: ! F1: z@ ;for easy tracing ! F2: u@ ;also for easy tracing ! F3: i@ ;dito ! F4: f@ ;for repeated finding ! F5: c@ ;for repeated comparing ! F8: v:X@ ;when exceptionvectors are set and an exception happens ! and has to be handled by the original vector ! F9: dm0 m0@ ;for finding disassembly without debugger window. Initially ! deselected ! F10: r:dpc pc@ ;for tracing without debugger window. Initially deselected ! ******************************************************************************* ! Appendix B Registered Users ! ******************************************************************************* - Thanks go to the following people who paid the shareware fee and persuaded - me that some people use this tool: ! Kay Temirel (Germany) ! Niel Ericson (Canada) ! Roby Leemann (Switzerland) ! Steve Anderson (Canada) ! Jörn Körner (Germany) ! ! ******************************************************************************* ! Appendix C My Address ! ******************************************************************************* - If you have questions, bugreports, ideas for new features or complaints or - if you simply want to contact me, write to: ! Stefan Walter ! Finsterruetistr. 57 ! 8135 Langnau ! SWITZERLAND - Or dial Switzerland/01/713 01 46, from 18.oo to 20.oo. - Enjoy! ! Stefan Walter 27.Jan.1991 --- 1,3564 ---- + ----------------------------------------------------------------------------- + S.I.M. + System-Independent Monitor + Version 1.72 ! Copyright © 1990/1991/1992 by Stefan Walter ! ALL RIGHTS RESERVED ! ----------------------------------------------------------------------------- ! The User Manual, refering to version 1.72 of S.I.M. + WARNING + ======= ! This version of SIM is not really official. It was ! released because some developers and programers have ! requested it and because it currently serves for ! debugging Amiga Mach. It is beta test ware and not ! complete by any means. A completely rewritten version ! is halveway finished and will be out soon. + SIM will now work on all existing Amigas running with + MC60000 or MC68020/30/40, on later with some + limitations. It works now on both PAL and NTSC machines + with OCS/ECS/AGA. + This program is still shareware, only Amiga Mach + developers and owners of NOG2 automatically become + registered users. No warranty for functionality is + given. ! CONTENTS ! ======== ! ! 1. Introduction ! -------------------- ! ! 1.1 Welcome to SIM ! 1.3 Disclaimer ! 1.2 About this Documentation ! ! ! 2. Getting used to SIM ! --------------------------- ! ! 2.1 What Is SIM? ! 2.2 Who Can Use It ! 2.3 Qualifications, Requirements and Limitations ! 2.4 The 68020+ Version ! 2.5 Configuring SIM ! 2.6 The SIM Program ! ! ! 3. Some words about... ! --------------------------- ! ! 3.1 The Display ! 3.2 Breakpoints ! 3.3 Trace ! 3.4 The Keyboard ! 3.5 Disk Access ! 3.6 Files ! 3.7 Breaking ! 3.8 The Actual Address ! 3.9 The matchbuffer ! 3.10 Command History ! 3.11 Traps ! 3.12 Function Keys ! 3.13 SIM and the Hardware ! 3.14 The Colors Red and Yellow ! 3.15 Printer Support ! 3.16 Memory Managing ! 3.17 Screen Blanker ! 3.18 Effective Address Calculation ! 3.19 Symbols ! 3.20 PAL/NTSC ! 3.21 Interrupt Lockup ! ! ! 4. Communication between YOU and SIM ! ----------------------------------------- ! ! 4.1 The SIM Environement ! 4.2 The Monitor ! 4.3 The Commands and their Syntax ! 4.4 The Debugger Window ! 4.5 Debugger Window Shortcuts ! ! ! 5. Additional Information ! ------------------------------ ! ! 5.1 Assembler Usage ! 5.2 Calculator Usage ! 5.3 Data Line ! 5.4 The Debug Server Entrance ! 5.5 The SIM Base ! 5.6 Errors ! 5.7 Footer Messages ! ! ! 6. Appendix ! ---------------- ! ! 6.1 Acknowledgements ! 6.2 Registered Users ! 6.3 Contacting Me ! ! ! ! ! ***************************************************************************** ! 1. Introduction ! ***************************************************************************** ! ! ! ! ! 1.1 Welcome to SIM ! ====================== ! ! ! Congratulations dear user. You have just obtained the third release of ! 'S.I.M.', a high performance monitor and debugger for the Commodore Amiga. ! ! 'S.I.M.' is a shareware product. This means that it can be used, copied and ! distributed freely, provided that: ! 1) No fee is charged for copying and distribution. ! 2) It is distributed ONLY in its original, unmodified state. ! 3) This document is copied along with the program. ! If you copied this program from somebody else and you like it and keep using ! it, you are asked to send a little contribution of 15 US$ to the author in ! order to get registered and to obtain support and the final version when it's ! finished. + 1.2 Disclaimer + ================== ! This program is provided "as is" without warranty of any kind. The entier ! risk of using it is to the user himself. In no event I (the author) will be ! liable for direct or indirect damage, loss of data or criminal actions done ! due to the use of this program. If you do not agree with this, you may not ! use SIM. ! 1.3 About this Documentation ! ================================ ! You should carefully skim this documentation if you are not used to SIM yet. ! SIM bases on a concept that especially programers lacking detailed knowledge ! of assembly language or C will first need to get used to. ! ***************************************************************************** ! 2. Getting used to SIM ! ***************************************************************************** + 2.1 What Is SIM? + ==================== + SIM is a very powerful debugger and monitor. It was designed to work under + all circumstances and especially to supervise rather unconventional programs + which do not make much use of the operating system or do completely disable + it for more or less long time. ! SIM works below the operating system and does not interact with any of its ! facilities or routines. It disposes of ways to enable you relatively ! comfortable debugging of any piece of machine language. Be it a task list ! manipulating routine, an interrupt or direct access on hardware like disk ! drives or the blitter, routines you can't monitor with an ordinary system ! based debugger. There are practically no limits. You can invoke SIM at any ! moment and it will pop up and work properly. ! SIM will do as less changes to the software and hardware (ram, custom/cia ! registers) as it can. When you exit SIM, it will try to leave everything the ! way it was when SIM was started. SIM does neiter use blitter nor copper, so ! any 'interrupted' program can continue to run with no defects due to a call ! to SIM, no matter when it was stopped. + 2.2 Who Can Use It + ====================== + SIM was written to be used by both serious programers of nice and clean + applications, who follow the guide lines of Commodore, as well as by the + socalled 'democoders' who write programms which directly access the hardware + and disable multitasking (and who lately have become deprived to do so by + Commodore :). It was originally mainly intended for the later, but it has + proven to be very useful for debugging applications too. ! It is distributed with the neccessary utilities to apply it on any kind of ! program that need to be debugged at a given time. They are not too ! comfortable yet, intuition based 'V36+ only' versions are planned. + SIM will be very useful for you if you need to debug programs which + temporarily disable multitasking. If you only need to debug 'ordinary' + programs with no critical or nonmultitasking routines, you are better served + with a full system debugger. There are plenty of good debuggers of that kind + available, also in the Public Domain. + 2.3 Qualifications, Requirements and Limitations + ==================================================== ! To use SIM efficiently, detailed knowledge of the Amigas hardware, the 680x0 ! processors and assembly language is ABSOLUTELY neccessary. If you lack this ! knowledge, get Commodores 'Amiga Technical Reference Series' and Motorolas ! documentations of the 68000 family. ! SIM is completely independent of the OS the Amiga uses. There is a certain ! support for the normal OS, but no dependancy. ! SIM does several things by directly accessing the hardware, especially the ! part that deals with the display. This however is no longer allowed by ! Commodore and will probably cause SIM not to work on Amigas of the next ! generation(s). If an incompatibility occurs, an update will be released. ! You should not invoke SIM while doing any kind of timed access to hardware, ! i.e. serial transfer. Because SIM shuts down everything, data transfer will ! be interrupted. You should also not invoke SIM from within a level 2 ! interrupt before it has dealt with keyboard events or keystrokes will be ! lost. ! 2.4 The 68020+ Version ! ========================== + The 68020+ version is only an 68000 version with the neccessary changes to + get it working on better CPUs. Special features of these processors + (additional exception vectors, instructions, registers, etc.) are not + supported yet if not absolutely neccessary. ! There is currently no version working on 68010 Amigas because I have no ! access on any machine to try out any adaption to this CPU. If anybody out ! there feels she/he needs a version of SIM for 68010 and is willing to do some ! beta testing, I will write a 68010 version. + The 68020+ version however works only with some limitations: ! - VBR must be at a known position. Default location $0, if vectorbase ! is not at 0, the real location must be stored in the base of SIM ! (offset 264). The tools supplied with SIM do this before they invoke ! SIM. ! - The 'v' command can only push stackframes back, not generate ! artificial ones. ! - The disassembler and assembler do not support any instructions added ! in the 68010+ processors, except Bcc.B/W/L and EXT.B. ! - MMU activities are not dealt with yet. SIM deactivates the MMU by ! default. You can activate the MMU again, SIM will then install a ! primitive bus error handler which prevents craches in case of a tree ! containing illegal descriptors. ! 2.5 Configuring SIM ! ======================= ! You can't use SIM right away, you need to configure a copy to your Amiga ! first, that is for the CPU and the memory configuration it uses. Therefore ! you have to use 'SIMConfig'. This program configurates SIM for your machine ! and your personal needs. ! The program is selfexplaining except when it comes to define the memory ! pages. Here you shall make no mistake or the copy generated will not work ! properly. First think about what must be viewable. That is: ! - All memory ! - Kickstart image ! Get all start- and end addresses and sort them from lowest to highest. If ! neccessary use some system information tool to get the start and end ! addresses of all your memory blocks. ! If you can merge pages then do so for same memory types. Do not define ! overlapping pages. Pages must also start and end at even addresses. The ! program 'SIMConfig' does not check for correctness of what you enter. If you ! define incorrect pages, SIM may crash later. In case you do not want any ! memory managing enter $1000000 as first page end address for the 68000 ! version, $80000000 for the 68020+ version. + You can exit this program anytime by entering 'exit'. + 2.6 The SIM Program + ======================= ! SIM is not an executable (it has no hunkstructure, so you cannot simply start ! it from the CLI or workbench) but a simple PC-relative file that can be ! loaded somewhere into the memory or included in one of your own programs. + SIM is a nonmultitasking debugger. When it is activated, Multitasking is + immediately stopped, much like by Disable(). ! ***************************************************************************** ! 3. Some words about... ! ***************************************************************************** + 3.1 The Display + =================== ! The display creates some of the more tricky problems for SIM and you. ! 20480/$5000 bytes of graphic memory are needed for a 640*256 bitplane. But ! at a certain moment, there may be no 20480 bytes graphic memory available. ! The solution is the backup. When you have an area of $5000 free graphic ! memory that will stay free for sure (that means it is allocated with ! AllocMem() or will never be used), you simply set the display address to the ! start of that area and the backup address to zero (this means no backup). ! SIM will then concider these $5000 bytes its own and use it as display. When ! you enter SIM, the data in this area are then destroyed. ! In case there is not enough free graphic memory or it will be used entierly ! in near future and you have enough (that is $5000 bytes) unused other memory ! that won't be used for sure, you set the backup address to the start of a ! free $5000 bytes block of other memory and the display address just to ! somewhere in the graphic memory. When SIM is activated, It copies the ! content of the $5000 bytes display- to the backup memory and uses the display ! memory. When you leave SIM again, it copies the $5000 bytes back from the ! backup- to the display memory. That way, the graphic memory is unchanged. ! The memory manager claimed to be missing in earlier versions ! is now integrated in several functions. If you have defined a backup area ! the memory manager automatically fades it in at the location of the display. ! Because the interrupt vectors are used, you may not specify a display below ! $70 or above the end of the graphics memory minus $5000. + Both the display- and the backup address are entered in the SIM basearea + before starting SIM or set by the 's' command while working. + NTSC users please note that although a 640*200 plane only uses 16000 bytes, + you too need $5000 display memory because it is also used as MFM buffer for + all disk operations. ! 3.2 Breakpoints ! =================== ! A breakpoint is basically a change in the program that is monitored which ! stops it and gives control to the debugger that set it. In other terms, you ! can run the program at full speed until it executes a certain instruction. ! This is a very important feature when you have to control the flow of a ! program. Therefore the breakpoint system of SIM is very sophisticated. SIM ! can handle three kinds of breakpoints: ! - ILLEGAL breakpoints ! - JSR breakpoints ! - STACK breakpoints ! Each kind is used for different problems and has its advantages and ! disadvantages. ! SIM is able to handle 16 different breakpoints at a time. When you enter ! SIM, it removes the breakpoints from the memory, so the memory looks like it ! would look with no breakpoints set. That enables you to change instructions ! that are at a breakpoint without first removing the breakpoint before ! changeing and putting it back afterwards. + A critical situation occurs when the breakpoint is overwritten by a program + (i.e. by a copyroutine). Such a breakpoint is in 'modified' state When SIM + removes the breakpoints at entry, it checks if they are still there. + Modified breakpoints are not removed and not restored, when you leave SIM + again. If you want to have the modified breakpoint set again, you must first + remove it (SIM simply frees the place in the breakpoint list but does not put + the original opcode or words back). Then you can set it again. ! You cannot set breakpoints everywhere. SIM tests if there is ram at the ! location where you want to set a breakpoint. If there is none, this causes ! an error. SIM also prohibits to set breakpoints in the SIM codesegment. ! 1. ILLEGAL breakpoints ! ---------------------- ! Illegal breakpoints are normally the most used ones and offer the most ! possibilities. When you set an ILLEGAL breakpoint at a certain instruction, ! SIM replaces the opcode word of that instruction by the ILLEGAL opcode $4afc. ! When the ILLEGAL instruction is executed instead of the original instruction, ! an ILLEGAL INSTRUCTION exception happens. + Therefore it is neccessary that the ILLEGAL INSTRUCTION vector somehow jumps + to SIM, either directly, set by the 'w' command, or indirectly via the task + traphandle, set by 'SIMBug' or another SIM-loader. If this is not so, your + machine crashes. ! Illegal breakpoints have the advantage that they can be 'conditioned'. This ! means that this breakpoint only forces entry when one or one of several ! conditions are fullfilled. The following criterias can decide whether or not ! the breakpoint forces entry: ! - condition term: + You can specify a term that is calculated each time when the program + arrives at the breakpoint. When the result of the term is zero, the + program continues, if it is nonzero, SIM is entered. ! You can use that feature to i.e. break a program at a certain point ! if a register contains a certain value. ! The use of SEA, TEA, SX and TX is allowed, but you must first toggle ! on EA calculation using the AMIGA-Z shortcut. + - counter breakpoint: ! A counter breakpoint will enter SIM if the program has passed the ! breakpoint a certain number of times. ! This way you can i.e. break a subroutine after it was called a ! certain number of times. + - button breakpoint: ! When the program arrives at a button breakpoint, SIM will look if the ! left or right mousebutton or the firebutton of a joystick in port 1 ! is pressed and enter SIM if one is pressed. You can specify what ! buttons are concidered. ! Button breakpoints can i.e. be set in a vertical blanking interrupt. ! every fiftieth/sixtieth of a second, SIM can check if you want to ! enter or not. ! Additionally you can make resident illegal breakpoints. A nonresident ! breakpoint will be removed after it caused entry. A resident breakpoint will ! stay active until it is removed. A resident breakpoint can be used in ! situations when you want to stop a program several times at the same address. ! SIMs breakpoint system enables to combine all these elements, to make ! resident breakpoinst that break at SEVERAL conditions. You can set a ! resident breakpoint at $70000 that either breaks when d3 is 3245 or the left ! or right mousebutton is pressed and that is limited to 1000 passes. The ! command line to set that breakpoint would look like that: 'b 70000 * ! ?d3=3245 lr 1000'. ! SIM uses the TRACE vector to skip a resident or conditioned breakpoint if it ! has not caused entry into SIM. This means that you must not only set the ! ILLEGAL INSTRUCTION vector but also the TRACE vector. This is neccessary as ! soon as you have set a conditioned or a resident breakpoint. + 2. JSR breakpoints + ------------------ ! The second type of breakpoint is a rather a 'heavy duty' one. When you set a ! JSR breakpoint, SIM remembers the 6 bytes at the breakpoint address and puts ! a JSR instruction there that jumps absolutely into SIM (i.e. 'JSR $c50726'). ! When the breakpoint is reached, the program jumps directly into SIM which ! then puts back the 6 bytes. ! This breakpoint has two advantages. The first is that you do not need any ! vectors to be set. The second is that a JSR breakpoint can be transfered. ! When you have an illegal breakpoint in a routine and that routine is ! transfered to another location and the breakpoint is reached in the copied ! routine, SIM will not know that that illegal is a breakpoint because it is ! not at any of the addresses at which a breakpoint was set, so it will not be ! replaced by the original opcode. JSR breakpoints are recognized at their ! entrance, because each of the 16 possible JSR breakpoints has another ! entrance. That way, SIM can recognize that breakpoint whereever it is. But ! be carefull, never enter SIM by these entrances on your own. You must also ! see to it that after the transfered breakpoint forced entry and was removed, ! the original one is NOT reached too. ! Because of these two advantages, you can use JSR breakpoints in delicate ! situations, where you are not sure if the vectors are not changed, i.e. in ! routines accessed by multiple tasks or places where the illegal vector or ! task traphandle is changed. ! A disadvantage of JSR breakpoints is that they use not one but three words. ! The minimum size for an instruction is a word, an illegal breakpoint can be ! set at any instruction because the instruction ILLEGAL uses one word. A JSR ! breakpoint may replace three instructions. Therefore you have to set the JSR ! breakpoint in a 'linearly' executed part of the program. Here are two ! examples where the JSR breakpoint is not set correctly. The breakpoint is ! always set at the label 'bkpt': ! 1. . ! . ! . ! bsr.s label ;this will cause problems! ! bkpt: ! bra.s label2 ;JSR opcode ! label: ! nop ;HIword of entrance ! nop ;LO word of entrance ! . ! . ! . ! 2. . ! . ! . ! bkpt: ! moveq #1,d0 ;JSR opcode ! label: ! moveq #0,d1 ;HI word of entrance ! rts ;LO word of entrance ! . ! . ! . ! moveq #-1,d0 ! bra.s label ;again in the middle... ! 3. Stack breakpoints ! -------------------- + Contrarily to the illegal and JSR breakpoint, the Stack breakpoint is not a + change in the program but a change on the stack. When SIM sets a Stack + breakpoint, it replaces a returnaddress on the stack by the address of an + entrance of SIM. When the appropriate rts, rtr or rte that would return to + that address is reached, it returns to SIM instead. SIM sets the pc to the + returnaddress and replaces the SIM entrance address on the stack (should now + be at a7-4 for rts!) by the original address for security. ! For SIM, it does not differe, if the Stack breakpoint is set in the ! supervisor or userstack (in earlier versions it did, this is no longer so). ! Use this feature wisely! SIM cannot test if the Stack breakpoint you set is ! put in a stack and is taken off stack by a 'Return From ...' instruction. ! Its upon you to set Stack breakpoints at the right position. ! Stack breakpoints are also used by for the nextstep and the leave subroutine ! command. + 3.3 Trace + ============= ! Tracing is the second way of keeping a program under control. SIM can ! singlestep a program. Therefore you must see that the TRACE exception caused ! by that somehow ends up in SIM, either set it directly or set the ! tasktraphandle. It can also let a program run step by step and stop when one ! or several conditions are fullfilled, much like the illegal breakpoints: ! - condition term: + You can specify a term that is calculated after each step. When the + result of the term is zero, the trace continues, if it is nonzero, + SIM is entered. ! You can use that feature to i.e. break a program as soon as a ! certain register is changed. ! The use of SEA, TEA, SX and TX is allowed, but you must first toggle ! on EA calculation using the AMIGA-Z shortcut. + - counter trace: ! You can specify a maximum number of steps to do. When that amount of ! steps is done, SIM is entered. ! Counter trace is mostly use to just get back after a routine is done. + - button trace: ! After each step, SIM will look if the left or right mousebutton or ! the firebutton of a joystick in port 1 is pressed and enter SIM if ! one is pressed. You can specify what buttons are concidered. ! Button trace can i.e. be used for stoping a program by hand at any ! moment. + - trace breakpoint: ! You can define an address that is compared to the PC after each step. ! If the program has arrived at that address, SIM is entered. ! This feature is used when you cannot use breakpoints for some ! reasons. + - 68020 emulation: ! This is also a condition. SIM is only entered when a change in the ! flow would happen, this means that the pc points on a BRA, JMP etc. ! SIM uses the trace flag to do single steps. What some people do not know is ! that you can trace over some instructions that may clear that flag. These ! are + RTE + MOVE to SR + ORI #x,SR + EORI #x,SR + ANDI #x,SR ! Additionally you can enter the TRAP #x exception routines with the trace. ! Tracing has one weak spot: if you are tracing and an interrupt happens that ! somehow causes entry in SIM (i.e. by a breakpoint), SIM loses the control ! over the trace. When you exit SIM again and the interrupt ends, a TRACE ! exception happens. You must then start to trace again or clear the trace ! flag by hand. ! Some words about the speed: It is clear that the more conditions you allow, ! the slower the program runs. Additionally some conditions cause longer ! delays than others. Condition trace is slower than button trace because it ! has to call the calculator which is relatively complex and slow. + 3.4 The Keyboard + ==================== + The most difficult problems are imposed by the keyboard. The Amigas keyboard + hardware cannot tell you which keys are pressed at a certain moment, it + reports only key changes. This makes it difficult for systemindependent + programs. When you press a key under system and release it in a program that + has its own keyboardhandler, the system will never know that you released + that key, it will report repeats of that key all the time until you press + another key. To prevent this, SIM will look that all keys are in the same + state when you leave SIM as they were in when you entered SIM. When you + leave SIM and a key is not in the same state, SIM will ask you to either + press that key or to release it. Therefore, in the headline you will find + the keys rawkey number and if in the keymap there is a printable character, + that character too. You can only exit SIM if you press or release all keys + that it wants you to. ! If you leave SIM by accident (hit wrong key?) and you are requested to ! press/release a key, you can do the following operation to return to the ! monitor: ! - Press another key that is not a qualifier (SHIFT etc.), not 'r', 'e', ! 't', 'u', 'n' or one that you must press to exit (esc is a good ! choice). ! - Release all other keys. ! - Type 'return'. ! - Release the keys you pressed for that operation. ! If you are tired to press keys again and again to exit, you can use the flush ! keystatefield shortcut. SIM will then clear the internal list of keys that ! were pressed when SIM was activated. + The keyboard can store upto ten rawkeys on its own if the CPU has no time or + need to get keyboard events. It is possible that several key hits are + waiting to be replied. When SIM is activated then, it would recieve all + those old keys that may invoke shortcuts or commands that are not desired. + Similar problems occur when you link SIM in the CIA-A interrupt and it is + invoked before the key is replied. The keyboardbuffer killer is used to + reply to all possibly waiting keys and to flush the keyboard buffer. This + feature can be toggled on or off and is off by default. ! 3.5 Disk Access ! =================== ! Because ram is a too transitory datacarier, SIM can read and write DOS-tracks ! and sectors. It does this by directly accessing the hardware. If you are ! using disk commands, make sure a disk is always inserted or the drive motor ! will be stoped after the command has completed although it was on. This is ! because SIM needs a disk to be inserted in a drive to find out if its motor ! is turning. ! When SIM is writing or reading, the display is used as buffer. You still see ! it, but it contains chaos. The top line is used to give you status ! information about the track that is operated or errors occured. ! When an error occures, you can either break with CTRL, retry with SHIFT or ! ignore the error with ALT (when file operation, ALT=CTRL). + When a track is not correct, SIM tries to read it three times. Then it + reports the error but displays also which sectors were okay. It is possible + that only one sector is damaged, press SHIFT several times, SIM may find some + sectors more that are okay and simply were after the damaged sector last + time. + SIM is tollerant concerning the integrity of the sectors. Checksums are + calculated and SIM reports an error if one is wrong, but it decodes the + sector anyway. This enables SIM to repair partially destroyed tracks. ! 5 1/4" and HD drives as used in the A4000 are not supported yet. ! 3.6 Files ! ============= + You can load any files of an OFS DOS disk to memory. You can list the files + and their length contained in any directory. And you can save any area of + memory as a file on a disk. + The file save system is quite sophisticated. It writes files in a way that + they can be loaded and listed fast. Info- and extension blocks are located + on track 79 and higher, data blocks from 79 down to 0 and from 159 to 79. + Additionally, SIM will first look if a file fits the disk before it begins to + save. The bad sideeffect of this is that saving takes some time. ! One thing you must remember is to be carefull with saving files when you work ! with the normal operating system afterwards. When you save a file, the ! bitmap on the disk is changed. The system keeps its own copy of the bitmap ! of a disk in memory. When it accesses that disk again, it possibly discovers ! a totally different bitmap. When it comes to the worst, the DOS crashes with ! the guru 07000007 (bitmap corrupt). To prevent this, you simply remove that ! disk from its drive and put it back again. The DOS then rereads the bitmap ! and everything's okay. ! 3.7 Breaking ! ================ ! In certain situations, it may be neccessary to break a command or to pause ! it. SIM can do both. You can break the dump commands, find and compare by ! shortly hitting CTRL. If you press it longer, SIM only pauses and continues ! when you release CTRL. When you press SHIFT-CTRL or additionaly hit the ! SHIFT key when you pause, SIM locks until you release, press and relese CTRL ! again. This enables you i.e. to make notes without holding CTRL all the ! time. + While locked or paused, you can press the ALT key. When you release CTRL (if + locked, press it first), SIM breaks th command execution also. This is used + when you have paused and want to stop immediately. + ALT-CTRL is used to break command execution in general. Before SIM looks for + a new command in a command line, it tests for ALT-CTRL. If that's so, it + breaks. This enables you to break a command line like 'P0:X' since you + cannot break the 'P' and 'X' commands. ! An exception to this rules are the disk operation and the list directory ! command. These commands can only be broken. Therefore simply keep the CTRL ! key pressed. + 3.8 The Actual Address + ========================== ! The dump and edit commands share a default address variable that is used each ! time, you do not give a start address. This address has the name '@' for the ! calculator. It contains the end address of the last dump or edit command or ! it is set by find and compare. + 3.9 The matchbuffer + ======================= ! The matchbuffer is used to collect addresses. You can force the find and ! compare commands to send addresses to this buffer. You can also also specify ! under what conditions an address is put in the buffer or one that is already ! in buffer stays there. There are three possible conditions: ! - old: ! If an address that was already in buffer did not match with any ! reported by the find or compare command, it only stays in the buffer ! when you enable old ones. ! - match: ! If an address that is reported is already somewhere in the buffer, it ! stays only when you enable matches. ! - new: + If an address is new, it is only put in the buffer when you enable + new ones. ! You can combine the three conditions in any way (there are eight possible), ! some may make not much sence. + This feature is mainly integrated to search for counters. ! To show the addresses in the buffer, the 'k' command is used. + An example: You are searching for the address of a counter. You know that + the counter is currently 10: ! 1. Define matchbuffer, i.e. 'k c00000 c10000' + 2. Search for 10, i.e. 'f 0 20000 !n 0a' ! 3. Exit, perform any neccessary operation to change the counter to ! another known value, i.e. 15 ! 4. Search for 15, i.e. 'f 0 20000 !m 0f' ! 5. List addresse(s) in matchbuffer, i.e. 'k 0' if more than one ! address stays in the buffer, go to step 3 and search again until ! one address stays. ! 3.10 Command History ! ======================= ! SIM remembers the last commands executed in the monitor. 128 bytes are ! reserved for that. These 128 bytes contain the last command lines. If you ! get an old command line back by the command history shortcuts and execute it, ! it is not remembered as the newest executed command. + 3.11 Traps + ============= ! The traps are one of the major connections between SIM to the outer world. ! They are used for breakpoints and to handle crashes. You can set the ten ! basic exception vectors directly. When you enter SIM, it puts back the ! original vectors, so you can edit them. When exited, SIM sets the set traps ! again. + Problems occur when the program that is debugged sets the traps itself. When + the program changes a vector previously set by SIM, this is handled the same + way as it is done with changed breakpoints. ! Additionally you can force SIM to set traps again if they are modified by ! toggeling 'Auto Unmodify Traps' on. If traps set by SIM are changed, the ! display color of SIM turns yellow in order to inform you of this. ! While working under operating system, it is not recomended to set the ! exception vectors directly to SIM, except if it becomes neccessary due to ! breakpoints in library vectors or other places where multiple tasks access. ! 3.12 Function Keys ! ===================== ! The ten function keys can be loaded with a text or command line. If you ! define a text, it is copied at the location of the cursor when you press the ! function key. If you define a command line, it is executed directly. ! The ten function keys are partially allready defined in the original SIM ! version. These are the definitions: ! F1: z@ For easy tracing. + F2: u@ " " ! F3: i@ " " + F4: f@ For repeated finding. ! F5: c@ For repeated comparing. ! F8: v:X@ When an exception vector is set and an exception of ! that kind happens and has to be dealt with by the ! original vector. ! F9: dm0 m0@ For finding disassembly without using the debugger ! window. Initially deselected: + F10: r:dpc pc@ For tracing without using the debugger window. + Initially deselected. ! 3.13 SIM and the Hardware ! ============================ ! SIM does only use a very limited part of the hardware registers, the ones ! that are indispensable or must be set on fix values to provide security. ! Some of these registers can be read, some not. The values of the readable ! ones are remembered in a special part of SIM called 'SIM base' when SIM is ! activated. The SIM base is located, as its name says, at the start of SIM. ! In chapter 6.1 you find the structure of the base. ! These are the registers that are read out and stored in the base at entry. ! When you exit SIM, it copies the remembered values back: ! DMACON ! INTENA ! INTREQ *) + CIA-A: CRA + CIA-A: CRB + CIA-B: CRA + CIA-B: CRB ! CIA-A: PRA write buffer ! CIA-A: PRB write buffer ! CIA-A: DDRA ! CIA-A: DDRB + CIA-B: DDRA + CIA-A: SR write buffer ! VPOS **) ! *) This register is handled in a special way. While SIM is active, it leaves ! the disk-DMA switched on. If it wouldn't, this would possibly destroy your ! disks. Since the disk-DMA is left on, remember that when the disk-DMA is ! terminated, bit 1 in the INTREQ is set. This may happen during SIM is active ! because the DMA was still transfering when the INTREQ was read. Therefore ! you will find only the interrupt requests in the backup that were waiting ! when SIM was activated. If you want to know about the actual contents, you ! must read out INTREQ using the calculator command '?[$dff09c].w'. ! When you exit and didn't edit the INTREQ backup, SIM does not restore the ! bits EXTER, DSKSYN, RBF, AUDX, DSKBLK and TBE from the backup. If you edited ! the backup, the bits that are changed are restored , even if they contain ! some of the bits named above. + **) This value is not written back. SIM rather waits for the rasterbeam to + be aproximately at that position that it was on when the register was read. + The register is read at a late point of time when SIM is activated, quite + some instructions have been executed then, so it is not very precise. + hopefully this can be improved. ! All these registers are used by SIM when working. If you have to know what ! vaule was in one of those, you have to look in the SIM base where SIM ! remembered them. If you need to change one of them, you must change the ! value stored in the base. + As quoted, some of the custom register contain information that is lost + because SIM cannot read from these registers. For the more important ones, + SIM disposes of an editable list of 'reentry' values which are put back when + SIM exits. Those registers are: + DIWSTRT + DIWSTOP + DDFSTRT + DDFSTOP + BPLCON0 + BPLCON1 + BPLMOD1 + COLOR00 + COLOR01 + BEAMCON0*) ! *) The BEAMCON0 register is only accessed under ECS or AGA. Unter OS, this ! register is only updated at calls to LoadView(), not in the copperlist. You ! may need to concider that if you are using an advanced resolution (i.e. VGA) ! on your Workbench screen and don't access SIM via SIMBug or PostSIM which ! both update the BEAMCON0 reentry value to the value used by the OS. ! These registers all concern the display. In most cases, they ! are reset anyway by a copperlist. If not, you have to look in the program ! where it sets them for the initial value and enter it in the base or decide ! on your own what value to use. + Some of the registers are modified but do not have a reentry value, because + they are either too temporary (DSKPTX for example) or completely unimportant + (BPL1PTX). If it becomes neccessary, you can edit some with the 'e' command: + + + CLXDAT + DSKBTR *) + DSKPTX *) + DSKLEN *) + DSKSYNC *) + BPL1PTX + BPL1DAT + SPRXDATA/B + CIAA: ICR state and mask + + + *) These registers are only used and changed when you read or write from or + to disk. + + If AGA is present, SIM also writes directly to some undocumented registers to + build up its display: + + + $DFF106: $0c40 + $DFF1E4: $0000 + $DFF1FC: $0000 + + + + 3.14 The Colors Red and Yellow + ================================= + + + When you start to use SIM quite often and in critical situations, it may + happen that the text color of SIM, which normally is green, turns red. This + means that the SIM code has been partially changed. SIM calculates a + checksum over its main code segment and looks if it is the same each time. + If not, it changes the color to red. + + When the color is red you must be rather carefull. SIM seems to run well but + it may crash when you execute a certain command or do something else. If you + can, load a new copy and don't keep using the destroyed one. + + A yellow text color means that one or more of the traps set have been + modified and overwritten. In that case you should either reset the vectors + that have been changed or remove then. + + + + 3.15 Printer Support + ======================= + + + SIM allows you to send all output on the monitor to the printer. Therefore + it simply sends the text as ASCII codes to the parallel port. This should + allow you to use practically any parallel printer. If you want to send ESC + codes (to select NLQ, reset etc.), you can do this by entering CTRL-[ and the + rest of the ESC code as a command and press return. Remember to use the + printer specific codes and not the AMIGA specific ones. + + Printer support does not work quite right with laser printers and certain + other non-matrix printers which need a FF before printing or which demand + both LF and CR. + + + + 3.16 Memory Managing + ======================= + + + SIM now disposes of the memory manager that was missing in v1.51. It + controls memory access by certain commands and forbids read and write + accesses to addresses where no memory is located: + + - It fades in the backup of the display at the location of the display. ! If there is no backup the display is zeroed. ! - At VBR+$68 and VBR+$6c it inserts the level 2 and level 3 interrupt ! vectors. ! - It handles five pages of memory that can be read and written to. Other areas are zeroed. ! ! The memory manager is currently not supported by all functions. Only the ! 'm', 'a', 'd', 'p' and 'l' commands (and the corresponding debugger window ! output forms), 'c', 't', 'o', 'P', 'H', 'L', 'S', 'e', 'n' and 'q' commands ! use it, the rest still doesn't. + 3.17 Screen Blanker + ====================== + When you do not press any key during 10 minutes and SIM is not doing any + operation, it automatically darkens the monitor. To continue to work, press + any key, best would be a qualifier. + 3.18 Effective Address Calculation + ===================================== + SIM can calculate effective addresses. The source EA of the command at the + PC is displayed below A6 of the small register list, the destination EA below + A7. In the large register list, the last line contains a 6 byte hexdump of + both the asource and destination EA. + EAs can be used in calculator terms. The source EA is named 'SEA', the + destination EA is 'TEA'. For both exists also a register 'SX' and 'TX' which + is 0 if the corresponding EA is not used by the instruction at the PC, and 1 + if it is used. ! 3.19 Symbols ! =============== + SIM now supports a symbol list generated by an external program. The symbols + can't be edited yet or new ones added. Symbols are used in the calculator + and the disassembler. The shortcut AMIGA-SHIFT-d toggles use of the symbols. ! ! ! 3.20 PAL/NTSC ! ================ ! ! ! When SIM is invoked on any PAL/NTSC machine for the first time, it adapts its ! display to the machine type. If ECS (or AGA) chipset is available, you are ! allowed to toggle between PAL/NTSC. NTSC users also can use an NTSC overscan ! display with 28 lines. The shortcuts used to toggle is is AMIGA-L. ! ! ! ! 3.21 Interrupt Lockup ! ======================== ! ! ! SIM uses the VB interrupt for its display setup and the PORTS interrupt to ! handle the keyboard. The concept of the Amiga allows external devices ! connected to the expansion port or the Zorro bus to generate interrupts. ! Most harddisk controlers use this feature and generate Level 2 and 3 ! interrupts. The basic problem for SIM is that if such a device generates an ! interrupt, it does not neccessarily clear the request by clearing a bit in ! the INTREQ register. Many devices have their own interrupt request register, ! located somewhere in the Zorro address space. Only the interrupt handler ! that is installed when the device is mounted knows about the address of that ! register. Therefore SIM cannot cancel such an interrupt and the result would ! be that the machine either locks up or that the device fails. ! ! To prevent this, SIM will detect if a level 2 or 3 interrupt was generated by ! an external device. If it is, SIM will automatically exit, execute the ! interrupt routine for the pending interrupt and return through the JSR ! entrance. ! ! ! ! ! ***************************************************************************** 4. Communication between YOU and SIM ! ***************************************************************************** ! ! ! ! 4.1 The SIM Environement ! ============================ ! ! ! SIM provides a display of 200|224|256*640 pixels or 25|28|32 lines and 80 ! rows, depending on the resolution you use. The screens colors are green and ! dark blue. The screen is devided in header, worktable/debugger window and ! footer, all separated by a bar of '­' chars. ! ! The header normally contains the title and copyright notice but serves also ! as statusline when accessing disk and at keyboard cleanup. ! ! The worktable and the debugger window share 21|24|28 lines. In the ! worktable, actually the monitor, you can move the cursor around and enter ! commands. Output of commands is also displayed in this part. The debugger ! window shows you one or two views of the memory in different forms at ! different addresses, read more about that feature in the appropriate chapter. ! The contents of the part of the worktable covered by the debugger window is ! remembered and restored if the window is removed. ! ! The footer contains the cause of SIM's entry, a status and result field and ! the addresses of SIM itself, the display- and backup address. ! ! ! ! 4.2 The Monitor ! =================== ! ! ! On the worktable, several basic features are provided: ! ! ! - What you see on the monitor (the text) is stored in SIM when you ! leave. it is available again if you enter SIM again, the display ! will be the same. ! ! - SIM has two entier keymaps for not qualified, shifted, alternated and ! shifted+alternated keys, one one custom and one USA. ! ! - CTRL-keys with assigned chars with ascii values from $40-$5f will ! result in a char with the ascii value from $0-$1f (i.e. CTRL-J ! (=$4a) => (=$a)) ! ! - CTRL-keys with assigned chars with ascii values from $60-$7f will ! result in a char with the ascii value from $0-$1f. ! ! - Cursor keys move the cursor by one step. ! ! - SHIFT-Cursors key moves the cursor in the extreme positions. ! ! - DEL will delete the char above the cursor and shift all chars right ! of the cursor one row left, inserting a space at row 79. ! ! - BACKSPACE will clear the char left of the cursor and shift all chars ! above and right of the cursor one row left. ! ! - SHIFT-DEL will insert a space at the cursor position and shift all ! chars above and right of the cursor one row right. ! ! - SHIFT-BACKSPACE will clear the char above the cursor move the cursor ! one row left. ! ! - ALT-DEL will clear the visible worktable and put the cursor in the ! left upper corner next to a period. ! ! - ALT-BACKSPACE will clear the line in which the cursor is, put a '.' ! in row 1 and the cursor in row 2. ! ! - HELP prints the first help page, starting in the line below the line ! the cursor is in actually. ! ! - SHIFT-HELP prints the second help page. ! ! - F1 to F10 either execute the command line stored or print the text ! stored. ! ! - SHIFT-ESC copies the last executed command in the line of the cursor. ! ! - ALT-ESC copies the line of the cursor in the command buffer. It can ! then be inserted anywhere with SHIFT-ESC. ! ! - CR will execute the commands in the line where the cursor is. ! ! - ALT-CURSOR UP goes one step back in command history and fill the ! actual line with the actual command in history. ! ! - ALT-CURSOR DOWN goes one step forth in command history. ! ! ! ! 4.3 The Commands and their Syntax ! ===================================== ! ! ! The command line contains the different commands to be executed. Its form is ! as follows: ! ! ! . (: ...) ! ! ! You can enter several commands in one line, separated by a colon. The colon ! is needed, except if the next char is the same as of the last executed ! command (i.e. 'mmmm' is allowed and shows $200 bytes at once, starting at ! the actual address). ! ! While working with SIM, you can get a little list of all commands with the ! two help pages by pressing HELP or SHIFT-HELP: ! ! ! n (s)(i) :assemble | t [s][e][t] :transfer mem | A (s) :set viewstart ! e (s)(d) :edit mem | o [s][e][d] :occupy mem | w (x) :CPU traps ! d (s)(e) :disassemble | c (s)(e)(t) :compare mem | v :recreate trap ! a (s)(e) :show ascii | f (sejd)(m) :find data | h (n) :history ! m (s)(e) :show hex | f (sej'i'i) :find disasm | g [s] :go sub ! l (s)(e) :show copper | s (p)(b)(c) :set SIM-adrs | i (n) :leave out ! p (s)(e) :show text | F (n)(c){@} :edit F-keys | u :next step ! k (s)(e) :matchbuffer | z (n*n?cb) :trace steps | r (rs):edit regs ! P (s)(m) :show plane | b (s)(*n?b) :breakpoints | q/Q :quit prog ! ? (expr) :calculate | T (expr){@} :set linkterm | x/X :exit and go ! ! ! >f(n) :format disk | s [s][s](n) :write secs ! D?(n) :find head | t [s][t](n) :write tracks ! K [s] :blockchksum | L [fs](n)(s):load file ! V (path) :directory | S [f][s][e] :save file ! R [s] :set range | H [s][e](p) :hear memory ! ! ! In the help page and the explanations, the following shortenings are used for ! options: ! ! ! s: start address|seek value e: end address ! i: assembly instructions d: data line ! n: decimal number x: hexadecimal number ! r: register p: plane address ! ?: condition term f: file name ! t: destination address|track number c: text|command line ! m: mask|modulo b: backup/breakmode/block ! j: options|flags ! ! ! Options in '[]' are neccessary. ! Options in '()' are optional. ! Chars in '{}' are optional flags. ! ! ! Because space in SIM is limited, these help pages tell only the basic syntax ! of a command. In the rest of this chapter all commands with all their ! possibilities and what you can do with them are listed. ! ! ! ! ! ! ! ! ! Dump Commands ! ------------- ! ! ! m (s)(e) Print memory as hexdump ! a (s)(e) Print memory as asciidump ! d (s)(e) Disassemble memory ! l (s)(e) Disassemble memory as copperlist ! p (s)(e) Print memory as text ! ! ! Dump commands have all the same options, only the output form changes: ! ! command (start address) (end address) ! ! If you give both addresses, SIM starts to dump from the start address and ! stops when the end address is reached or passed over. ! ! If you give only the start address, SIM starts to dump from that address and ! displays eight lines. ! ! If you do not give any address, SIM takes the actual address as start address ! and displays eight lines. ! ! Adress spaces which are not defined are read zero. ! ! In disassembly, the instructions BSR,JSR and TRAP #x are indented and after ! the instructions JMP, BRA, ILLEGAL, RTS, RTE, RTR and RESET a separating line ! of '-' is printed. Additionally, resident breakpoints are marked by an ! asterix, JSR breakpoints with a plus sign amd normal breakoints with a cross. ! ! ! ! EXAMPLES: ! ! m 0 100 ! a 100 ! d ! l 51236 !+60 ! p $25364 ! ! ! ! ! ! ! ! ! Edit Commands ! ------------- ! ! ! e (s)(d) Edit memory ! n (s)(n) Assemle ! ! ! You can modify the memory with these two commands. They both ignore the ! memory manager and write directly to memory. The edit command can write data ! to memory (see chapter 'Data Line' for details) The assemle command can ! assemble one or several instructions separated by a ',' to memory (see ! chapter 'Assembler Usage' for info) ! ! If you give both start address and data/instructions, SIM writes the ! data/instructions to memory. ! ! If you only give the start address, SIM will start to assemble or edit in a ! continuous mode where it always prepares the next line for further data or ! instructions. To stop this simply give no instruction or data. The system ! is as clever as it recognices if in the line it prepares for a new data or ! assemble line, there is already a data or assembly line that was prepared for ! continuous mode. If that is so, it only updates the address but does not ! clear the line. That enables you to i.e. correct a program assembled in ! continuous mode and to insert instructions. ! ! If you do not give any option, SIM starts to edit/assemble in continuous mode ! at the actual address. ! ! ! ! EXAMPLES: ! ! e 70000 ! e>00070000: 0121 ! e>00070000: ! n 100 nop ! ! ! ! ! ! ! ! Transfer and Occupy ! ------------------- ! ! ! t (s)(e)(t) Transfer memory ! o (s)(e)(d) Occupy memory ! ! ! Transfer: ! ! This command simply copies a part of the memory to another location smartly. ! This means that SIM uses as- or descending mode for copying. Memory managing ! is used, undefined memory is read zero and not written to. ! ! t [s][e][t] Transfers memory from s to e to new address t. ! ! ! ! ! Occupy: ! ! The 'o' command will fill a defined area of memory with a byte pattern. ! ! o [s][e][d] Occupy memory from s to e with data d. ! ! ! ! ! EXAMPLES: ! ! t 0 10000 00c00000 ! o 12564 !+60 nnop ! ! ! ! ! ! ! ! Find and Compare ! ---------------- ! ! ! f (s)(e)(j)(d)(m) Find data ! f (s)(e)(j) i (i) Find disassembly ! c (s)(e)(t)(j) Compare memory ! k {@}(s)(e) Show/set matchbuffer ! ! ! SIM disposes of sophisticated data search and compare commands. For any of ! the find or compare commands you can specify the following options after the ! end address: ! ! ! - +/-n Sets the step rate. Only at every nth address is the data ! are compared. ! ! - '*' Specifies that addresses where nothing was found or two bytes ! are the same are reported. ! ! - '@' When you do not want a list of addresses but to have them ! reported one by one, set this options. SIM will then execute ! F9 each time something is reported and put the start of the ! active view of the debugger window to that address. ! ! - '!' If you want to collect and filter addresses with the ! matchbuffer, set this flag. After the '!', an 'o' specifies ! that old ones stay, a 'm' that same addresses stay, or a 'n' ! that new ones stay. Combinations are allowed. ! ! ! ! ! Find data: ! ! You can search in a defined area in the memory for a certain byte pattern ! with this command. Depending of how many options you enter, the command does ! different things: ! ! ! f [s][e](j)[d][m] Starts to find from s to e with the options j ! for the byte pattern d that is masked by the mask m. ! Only the bits that are set in m are concidered when ! comparing. If the mask is shorter than the data, the ! rest of the mask will be set to $ff. ! ! f [s][e](j)[d] Starts to search for data with all bits set in the ! mask. ! ! f [s][e](j) Starts to find for the same data with the same mask ! as last time in the area from s to e with new options ! j. ! ! f [s][e] Searches again in the area from s to e. ! ! f [s] Starts to search from s. ! ! f Continues to search after the last address reported. ! ! ! ! ! Find disassembly: ! ! This command searches an instruction or a fragment of it in a defined area of ! the memory. Like the 'find data' command, 'find disassembly' does not need ! all options: ! ! f [s][e](j) i [i] Starts to find from s to e with options j for ! the instruction i. ! ! f [s][e](j) Starts to find for the same instruction in the area ! from s to e with new options j. ! ! f [s][e] Searches again in the area from s to e. + f [s] Starts to search from s. + f Continues to search after the last address reported. + The instruction i can be only a fragment like '4(a6)' or '@su*' or an entier + instruction like 'moveq #3,d0'. Because the disassembler calculates the + addresses of PC relative addressing modes, this command can also be used to + track down accesses to addresses. Several rules must be concidered when + designing the search text: ! - If there is a space in your text, SIM will concider what is before ! the space to be the mnemonic. Because the disassembler leaves an ! eight chars large field for the mnemonic where the rest is filled ! with spaces, SIM does tabulate your entries. 'clr.l d0' will ! internally made to 'clr.l d0'. ! - The char '*' is used as wildcard. It replaces one char. I.e. ! '(a*)' searches for all indirect accesses with any address register. ! - The char '_' is replaced by a space. I.e. '_d0' searches for all ! accesses on d0 as source ea. ! - The char '@' at the start or the end of your fragment limits the ! search on the start or end of the fragment. I.e. '@st' finds only ! 'st.b d0' but not 'tst.l d3'. + Compare: ! This command will compare two areas of memory and report addresses where ! bytes differe or are the same: ! c [s][e][t](j) Compares area from s to e with area t to (t+(e-s)) ! with options j. ! c [s][e][t] Compares with no options. ! c [s][t] Continues to compare from s and t. ! c [s] Compares from s. ! c : Continues to compare after last address reported. ! Matchbuffer: ! This command allows you to manipulate and view the matchbuffer. Refere to ! the chapter 'The Matchbuffer' for further information. ! k [s][e] Locates the matchbuffer from s to e and clears it. ! k * Clears matchbuffer. ! k ? Shows the location and number of entries. ! k @ [s] Shows all matchbuffer entries larger than s by ! reporting them one by one using F9 and the debugger ! windows active view. ! k [s] Lists all entries higher than s ! k Lists or shows next entries. + EXAMPLES: ! f 0 100 00 ! f 10000 20000 !nm 05 ! f 0 20000 @ imoveq #* ! c 0 100 200 * ! k 100 ! k@ 0 ! Processor Commands ! ------------------ ! r (r)(x) Set/view registers ! w (x) Set/view traps ! v (x) Create trap ! Registers: ! The 'r' command is used to either set a register d0-d7, a0-a7, ssp, usp, pc, ! sr, m0-m7 and isp/msp or vbr (68020+ only) or to view them: ! r [r][x] Sets register r vith new value x. ! r Views registers. ! r? Views memories m0-m7. ! Traps: + The 'w' command is used to either set or clear the ten basic CPU exception + vectors or to view their status: ! w [x] Sets or clears vector x. + w Lists status of all ten vectors. ! wk Clears all traps. ! You can set or clear several vectors at a time by separating the vector ! numbers by kommas. The vector numbers correspond to the exception numbers, 2 ! for bus error upto $b for linef. ! Refere to the chapter 'Traps' for further information. ! Create Traps: + The 'v' command is used to simulate the occurence of an exception or to + remove one from the stack: ! v [x] Simulates exception x. + v [-x] Removes exception x from stack. ! v Simulates occurence exception that forced entry. ! v? Gives information about the trap that forced entry. ! SIM can simulate exceptions 2 upto $40. When you simulate an address or bus ! error, SIM takes either the ssw, ir and aa from the last bus or address error ! or zero for all when none happened yet. ! When you simulate an exception 2 upto $b, which is set by the 'w' command, ! SIM takes the old vector as new pc. + When you simulate an interrupt, the sr will also contain the interrupt level. ! The 'v' command without options is used to put an exception back on the stack ! when i.e. you want the old vector to handle the problem. This works only if ! SIM was entered due to an exception. ! You can only remove traps from the stack when you are in supervisor mode. ! The vector number is only used to know how much has to be taken from the ! stack (14 bytes when 2 or 3, 6 for the rest). ! The 'v?' command is used to know more about the exception, especially address ! and bus errors. + In the 68020+ version, the 'v' command can only be called without options and + puts the old stackframe back. ! EXAMPLES: ! r pc pc+20 ! r m7 d0 ! r? ! w 4,9 ! wk ! v 3 ! v -3 ! v? ! Breakpoint and Trace ! -------------------- ! b (s)(j) Set/clear and view breakpoints ! u next step ! z (j) trace step ! i (n) leave out instructions ! Breakpoints: ! The 'b' command is used to handle breakpoints. When you set an illegal ! breakpoint, you can specify the trigger conditions after the address. The ! following conditions are accepted: ! - 'l', 'r', 'j' Breaks when left, right or joystick button pressed. + - [n] Breaks after breakpoint is reached n times. ! - '?'[n] Breaks when term n is true (<>0). ! - * Breakpoint is resident. ! Refere to the chapter 'Breakpoints' for more information. ! b [s][j] Sets a breakpoint at address s with the options j. ! b [s] Sets a simple breakpoint at s or clears one. ! b Lists all breakpoints. ! bj [s] Sets a JSR breakpoint at s. ! bs [s] Sets a STACK breakpoint at s. ! bk Kills all breakpoints. + You can set or remove several breakpoints at a time by separating the next + address from the previous address or options by a komma. ! Trace Step: ! The 'z' command executes trace steps. It either stops after one step or when ! a certain condition is fullfilled: ! - 'l', 'r' or 'j' Traces until button pressed. ! - [n] Traces n steps. + - '?' [n] Traces until term n is true (<>0). ! - '*' [s] Traces until pc=s. ! - 'c' Emulates 68020 trace steps. ! Refere to the chapter 'Trace' for more information. ! z [j] Traces until a condition j is fullfilled. ! z Does one trace step. ! Next Step: ! The 'u' command does either one trace step or when the instruction at the PC ! is a JSR, BSR or TRAP #x, it does a trace step and then sets a stack ! breakpoint at a7 (or a7+2 when the instruction was TRAP #x) and exits: ! u Do one step. ! Leave Out Instruction: ! This command simply sets the PC one or n instructions further: + i [n] Leaves out n instructions. ! i Leaves out one instruction. + EXAMPLES: ! b 100 *j100 ?[4]<>$c00276 ! bj 100,200 ! bssp ! z *pc ! z j ! n ! i 2 ! Flow ! ---- ! x Exit ! X Exit directly ! q Quit ! Q Quit directly ! g [s] Go to subroutine ! h (n) History + Exit: ! The 'x' or 'X' commands are used to simply continue the program at full ! speed. 'x' asks first if you are sure, reply with 'y' or 'n'. 'X' simply ! exits: ! x Exits, but asks for confirmation first. ! X Exits directly. ! Quit: ! The 'q' or 'Q' commands are used to return control over the program to the ! debug server. 'q' asks first if you are sure, 'Q' simply returs directly: ! q Quits, but asks for confirmation first. ! Q Quits directly. + Note the difference between the exit and the quit command. The exit command + lets the program continue. The quit command calls the debug server and lets + it deal with the situation. The program is not continued. Refere to the + chapter 'The Debug Server Entrance' for more information. ! Go Subroutine: ! The 'g' command is used to execute a little subroutine from within SIM: ! g [s] Call subroutine at s. ! gw [s] Prepare stack for subroutine call but do not exit. + When SIM calls a subroutine, it first pushes the old pc on the stack and then + the return address for the rts. If the subroutine completes with a RTS + instruction, SIM is invoked again. ! The 'gw' command does only prepare the stack for the operation, that is it ! pushes the return address and the old PC value on the stack, but does not ! exit yet. This is i.e. used to trace a subroutine. + History: ! SIM remembers the last five sets of registers as they were when SIM was left ! for the last five times. The list is also updated after each step when doing ! conditioned trace and each time a conditioned breakpoint is reached: + h [n] Display nth last history. ! h Display all five history entries. ! SIM does not only remember the registers d0-a6, usp, ssp (isp/msp), sr and pc ! but also the instruction at the pc because of selfmodifying code. + EXAMPLES: ! h 3 ! X ! q ! g 100 ! gw 200 ! Diskoperations ! -------------- ! D (n) Set drive for disk operations ! t (s)(s)(n) Write tracks ! s (s)(s)(n) Write sector ! >f (n) Format disk ! B (s) Calculate bootblock checksum ! K (s) Calculate block checksum ! Set Drive: ! The 'D' command is used to set the drive number that is used for further ! diskoperations (tracks, sectors or format, but not for file operations!) or ! to ask for the actually used drive or to ask for the position of the head of ! a drive: ! D [n] Uses drive n (0-3) as actual drive. ! D Shows actual drive. + D? [n] Finds position of head of drive n. ! D? Finds position of head of actual drive. + The headposition is reported as logical track, the sideselect bit will be + concidered when calculating the position. In most cases (DOS included) the + sideselect bit will be set directly before DMA access and put to an undefined + state afterwards. If that is so when you use this command, you must find the + side that is used on your own. ! Read Track: ! The 't' command writes an area of the memory as logical tracks on disk: + >t [s][t][n] Writes n tracks starting with t, data start at s. ! >t [s][t] Writes one track t, data start at s. ! This command does not support memory managing yet. ! Read Sector: ! With the 's' command you can write single sectors from disk to memory: ! f' command is used to format and initialize a disk with OFS: ! >f [n] Formats disk in drive n. + >f Formats disk in actual drive. ! You can't yet enter a name for the disk, it will automatically be ! 'DATA-DISK'. The creation date is zeroed too. AmigaDOS cannot separate ! disks with the same name and same date. So never keep two datadisks in two ! drives simultaneously, or DOS will get into troubble. ! If you format a disk that was previously in a drive and you return to DOS, ! remove and reinsert that disk for DOS must know the new name and new bitmap. + Bootchecksum: ! When you want to save a bootblock to a disk, you may have to update the ! checksum with this command: ! B [s] Sets new checksum of bootblock that starts at s. ! Blockchecksum: ! When you want to save an edited datablock on a disk, you may have to update ! the checksum with this command: ! K [s] Sets new checksum of block that starts at s. + EXAMPLES: ! t c00000 0 80 ! >s 70000 0 2 ! f 0 ! B 60000 ! K 70000 + Fileoperations + -------------- ! L [f][s](n)(s) Load file ! S [f][s][e] Save file ! V (path) List directory + Paths and filenames can either be given plainly or between ' or ". The only + devices known are DF0:, DF1:, DF2: and DF3:, disknames are not supported. + Refere to chapter 'Files' for more information. ! Load File: ! This command loads a file directly into memory: + L [f][s] Loads file f to s. ! L [f][s](n) Loads n bytes from file f to s. ! L [f][s](n)(o) Loads n bytes from file f to s, o bytes from the ! start of the file. ! Memory managing is supported. You still should not load data over SIM. ! Save File: ! With this command you can save an area of memory as file to disk: ! S [f][s][e] Saves memory from s to e as file f ! This command is also used to delete files. To do so simply save a file with ! the name of the file you want to delete and the same start- and end address ! (filelength=0). ! Memory managing is supported. ! List Directory: ! This command is used to list the directory of the root directory of a disk or ! a user directory: ! V [path] Lists directory of directory specified by path. ! V Lists directory of drive used last. + SIM reads the directory page by page because the display is used as buffer. + If a page is full or the directory is read, it displays it. If there is more + to be displayed, SIM writes 'more' in the footer. You can continue and view + the next part by pressing . ! EXAMPLES: ! L 'df0:c/dir' 60000 ! S df1:data 0 100 ! V df0:c + Miscellaneous + ------------- ! ? [n]{,}(n) Calculate ! F (n)(c){@} Define function keys ! P (s)(m) Start graphic searcher ! H [s][e](p) Hear sound ! s (p)(b)(c) Set display, backup and program addresses ! l* Show copperlist ! l? (s)(e) Find active copperlist ! l= [n] Find copperlist one or two ! R [s] Set range for access scan ! Calculate: ! If you need to calculate something, you can do it with the '?' command. SIM ! will calculate the result of one or several terms and return the result(s) as ! hexadecimal, signed hexadecimal, decimal and binary number and as ascii ! chars: ! ? [n] Calculate result of n. ! You can calculate the result of several terms at the same time by separating ! the terms by a komma. + Function Keys: ! The 'F' command is used to set and view the function key definitions: + F [n][c] @ Defines key n with command line c that is executed + directly. ! F [n][c] Occupies key n with text c. + F [n] Clears key n. ! F Lists key definitions. ! When you set a function key, the entier rest of the command line will be ! taken for the command or text. + When you list the function keys, the ones that are locked by Amiga-Fx are + marked by an asterix, the directly executables have an '@' at the end. ! Graphic Searcher: ! The 'P' command starts the one plane graphic searcher: ! P [s][m] Starts at address s with modulo m. ! P [s] Starts at address s with last modulo. + P Starts at last address with last modulo. ! When you have activated the graphic searcher, the following keys are used for ! display control: ! Cursor up Scrolls plane one line down. ! Cursor dn Scrolls plane one line up. ! Cursor left Scrolls plane one line right. + Cursor right Scrolls plane one line left. + SHIFT-Cursor up Scrolls plane one screen down. ! SHIFT-Cursor dn Scrolls plane one screen up. + HELP Modulo=modulo+2. ! DEL Modulo=modulo-2. + SHIFT-Help Modulo=modulo+16. ! SHIFT-Del Modulo=modulo-16. ! BACKSPACE Modulo=0. ! CR Switches between hires and lores. ! CTRL Ends graphic searcher. ! Since the graphic searcher also supports the memory manager, it is possible ! not only to look at the graphic memory but at the entier space of addressable ! memory including other memory and rom image. ! Because of technical reasons the status bar is now located at the bottom. It ! has also become neccessary to limit the modulo. It can now range from $ffb2 ! to $3ffe for a hires and from $ffda to $3ffe for a lores plane. ! Hear Sound: ! The 'H' command sends an area of memory as a sample to the audio hardware: ! H [s][e](p) Hear memory from s to e with period p. ! H [s][e] Hear memory from s to e with last period. ! Memory manager is supported. ! SIM Addresses: ! The 's' command is used to transfer the display and backup and the SIM ! code itself: ! s [p][b][c] New display at p, new backup at b, SIM copied to c. ! s [p][b] New display at p, new backup at b. ! s [p] New display at p. ! s Redraws the display. ! Be carefull when you transfer the SIM code. SIM does adjust breakpoint and ! traps to the new address, but a possible debug server will only know about ! the new location when you quit SIM. The old copy of SIM will still work, but ! its breakpoint and trap system will be confused. The same problem occurs ! when the tasktraphandle is set to SIM. Use this command only when the system ! is dead. + SIM does not check the values you enter, make sure that you do not specify + locations where i.e. display and SIM would overlay. ! Copperlist: + The 'l' command is basically used to disassemble a copperlist. The following + variations are used for different actions: ! l* Shows the active copperlist. ! l? [s][e] Starts to search for the copperlist from s to e. ! l? [s] Starts to search for the copperlist from s to $80000. ! l? Searches for the copperlist from $70 to $80000. ! l= [n] Starts to search quickly for copperlist 1 or 2. + To end copperlist display or searching, press . ! When you search quickly, the copperlist you are looking for will be ! activated. If this one is not the running one, search again for the other to ! set the other copperlist again. This kind of searching has the risk that you ! may search for a copperlist that does not exist. ! The 'l=' function does not work properly on MC68020+ due to some timing ! problems. Calling it on any MC68020+ may not find a copperlist. ! Set Scanrange: ! The 'R' command is used to define the range in which the access scan ! shortcuts will search for accesses. Default is $10000: ! R [s] Sets range to s. ! EXAMPLES: ! ? 256*5,52*56 ! F10 r:dpc pc@ ! F ! P 12356 52 ! s 70000 c50000 c40000 ! l* ! l=1 ! l? 20000 ! R $80000 ! Debugger Window Support ! ----------------------- ! A [s] Set new start address ! T [s]{@} Set linkterm ! Start Address: ! With this command you can directly set the start address of the active view: + A [s] Set new start address of view to s. + Linkterm: + To set a linkterm for a view, you use the 'T' command. SIM will calculate + the result of this term and use it as new start address each time it is + entered or the AMIGA-r shortcut is pressed: + T [s] @ Set smart linkterm for active view. + T [s] Set simple linkterm for active view. ! T Removes linkterm. ! When SIM calculates a simple linkterm, it takes the result as new start ! address. The result of a smart linkterm is only used as new start address if ! it is not in the space currently displayed in the view. Normally this is ! only used to link a view to the PC. ! EXAMPLES: ! A a0+56 ! T a0+d0 ! T pc @ ! 4.4 The Debugger Window ! =========================== ! You can switch it on or off by pressing . When you do so, a part of the ! worktable is locked for the cursor and used to print out the registers and ! one or two different views of the memory in different forms (disassembly, ! ascii etc.). The window is updated as soon as you execute a command that may ! change the memory and at entry of SIM. + The two views have two start addresses that are stored in m0 and m1. m1 is + unused when you do not splitt the window and use only one view. + You can link the two views to two terms, the socalled 'linkterms'. + 4.5 Debugger Window Shortcuts + ============================= ! The window and its views are controled with shortcuts that are qualified by ! either left or right Amiga. If you have splitted the window, you can select ! the view that recieves the commands by pressing . ! View Address ! ------------ ! Cursor up Decreases the views start address and scrolls the ! display one line down. ! Cursor dn Increases the views start address and scrolls the ! display one line up. ! Cursor left Decreases the views start address by one byte (two ! bytes for disassembly and copper dump). ! Cursor right Increases the views start address by one byte (two ! bytes for disassembly and copper dump). ! SHIFT-C up Decreases the views start address and scrolls the ! display one page up. ! SHIFT-C dn Increases the views start address and scrolls the ! display one page down. ! ALT-C up Decreases the size of the current view by one line. ! The minimum size is one line. ! ALT-C dn Increases the size of the current view by one line. ! The maximum size is as large as there stays one line ! for the monitor. If the cursor was in a line used by ! the debugger window, it is moved to the top line in ! the worktable. ! SHIFT-Alt-C up Moves the bar separating the two views one line up, ! which decreases the upper view and increases the ! lower view one line. ! SHIFT-Alt-C dn Moves the bar separating the two views one line down, ! which increases the upper view and decreases the ! lower view one line. + s Splitts the window into two views or unsplitts again + and removes the inactive view. ! r Recalculates the linkterm(s) and sets the views start ! addresses again. ! Output Form Selection ! --------------------- ! a Selects asciidump for the active view. + m Selects hexdump for the active view. ! l Selects copper disassembly for the active view. ! m Selects disassembly for the active view. ! p Selects text for the active view. ! D Dis-/enables symbols in general. + S Allows symbols also for $xxxx(An) either only at the + PC or throughout the entier disassembly. ! Breakpoints ! ----------- ! b Sets an unconditioned illegal breakpoint at the start ! address of the active view. ! v Sets an unconditioned resident illegal breakpoint at ! the start address of the active view. ! B Sets a JSR-breakpoint at the start address of the ! active view. + Flow + ---- + z Does one trace step. + u Does one trace step that does not follow into + subroutines. ! i Puts PC to next instruction. + x Exits SIM. ! q Quits SIM and returns control to debug server. ! g Leaves a subroutine. Therefore SIM puts a ! STACK-breakpoint at the actual stackpointer and ! exits. Do not use this when the subroutine has ! already put more data on the stack. This corresponds ! to the command line 'bssp:X'. ! G Performs an RTS. Basically does 'rpc[sp]:rspsp+4'. ! j Sets the pc to the start address of the active view. + Edit + ---- + + e Starts to edit in continuous mode at the start + address of the active view. + + n Starts to assemble in continuous mode at the start + address of the active view. + + N Replaces the instruction at the start address of the + active view with NOP instruction. + + + + + + + + Indirection + ----------- + + + [ Goes to next higher indirection level and takes the + longword at the start address of the active view as + the new start address and stores the old one. + + ] Goes to previous indirection level and takes the + stored start address as the new one. + + { Same as AMGIA-[ but the longword will be read as BCPL + and multiplied by four. + + } Goes to next higher indirection level and uses the + last address this level pointed at. + + SHIFT-ALT-C left If the instruction at the PC is a branch of any + kind, an indirection to the address of the branch is + done. + + ALT-C If the instruction at the start of the view is a + branch of any kind, an indirection to the address of + the branch is done. + + SHIFT-ALT-C right Goes to previous indirection level. + + ALT-C right Goes to previous indirection level. + + + The indirection commands can have a maximum depth of 8 levels. SIM does + never reset to the first level on its own, if you have reached the limit, you + must reset it by returning to level 1. + + + + + + + + + + Find and Compare + ---------------- + + + f Continues to search at the start address of the + active view. + + c Continues to compare. The source address will be the + start address of the first view , the destination + address the start address of the second view. + + > Initiates scan for accesses on start address of + current view. The range can be set with the 'R' + command, default is $10000. SIM will search both + upwards and downwards for accesses, the range + specifies the maximum distance to test. + + < Continues scan. + + + + + + + + + + Miscellaneous + ------------- + + + P Toggles the printer on/off. The printer can only be + activated if there is one connected to the parallel + port and it is selected. + + H Makes a hardcopy of the actual display by printing it + as text. You do not have to activate the printer + first. + + k Toggles between US keymap and custom keymap. + + ! Flushes keystatefield, see chapter 'The Keyboard'. + + ? Toggles keyboard buffer killer, see chapter 'The + Keyboard' + + + Toggles fully printable charset. When switched on + (full), the chars $0-$1f and $80-$9f are not replaced + by a period in asciidump, hexdump etc. Switch it off + (semi) when using the printer. + + \ Toggles the auto-unmodify traps feature. When this + is switched on, all modified traps are set again when + you leave SIM. + + F1 to F10 Toggles availability of funktion keys. + + 0 to 9 Takes one of the ten position memories as the start + address of the active view. + + SHIFT-0 to 9 Stores the start address of the active view in one of + the ten position memories. Works only with the + keypad! + + L Switches between PAL, NTSC and NTSC overscan if ECS + or AGA chipset is available. If not, NTSC users can + switch between NTSC and NTSC overscan only. + + M Toggles the MMU on or off (68020+ only). + + R Toggles register display mode: Either display MSP or + SR flags (68020+ only). + + ® Toggles register display mode: Either small register + list or large. + + Z Toggles EA calculation for condition breakpoints and + trace on/off. If the SEA, TEA, SX or TX register is + used in an condition expression, switch this on. + + + + + + + + + + ***************************************************************************** + 5. Additional Information + ***************************************************************************** + + + + 5.1 Assembler Usage + ======================= + + + SIM contains a full 68000 assembler which allows you to make changes to + programs while debugging. It supports the standard optimisations and aliases + used by most other assemblers: + + + - ADDI and ADDA can be replaced by ADD. ADDX can also be replaced by + ADD if the effective addresses are address register indirect with + predecrement. + + - SUBI and SUBA can be replaced by SUB. SUBX can also be replaced by + SUB if the effective addresses are address register indirect with + predecrement. + + - CMP can be used instead of CMPA, CMPI and CMPM. + + - EOR, OR and AND can be used instead of EORI, ORI and ANDI. + + - Bcc and DBcc instructions and PC-relative effective addresses use + absolute addresses. It is possible to specify the offset directly by + puting a '+' or '-' sign in front (but note that the offset is + counted from start of instruction plus 2): + + 00060010: bra $60000 + or 00060010: bra -$12 + + - If no size is given, Bcc will be optimised to short if possible. + + - If no size given, memory direct effective addresses are optimised to + WORD if possible. + + - If no size given for an instruction, the default size is used which + in most cases is WORD. + + - The interpreter is very tollerant concerning spaces, a line like + + move.l ( $75 ) ( PC , D7.l ) , ( $4 ).w + + will be accepted and assembled correctly. + + + + 5.2 Calculator Usage + ======================== + + + The calculator is one of the central functions of SIM, all numeric input is + handled by it. It disposes of several very useful operations and value + forms. The following operators are supported, sorted after priority: + + + ( ) Brackets: Correspond to normal brackets. Number of opening + and closing brackets must be the same. Maximum nesting is + 127. + + [ ] Memory indirection: The result of the term in these brackets + an address and the content of the memory at that address will + be read. + + A size directly after the closing bracket will define if the + value will be read as a BYTE, WORD or LONG and extended to + LONG. I.e.: [4].l reads out AbsExecBase, [$dff002].w reads + out the actual DMACON as a WORD. + + - Prefix change: Changes a positive value to a negative and + vice versa. I.e.: -5 is -5, -0 is 0, --6 is 6. + + ~ Logical NOT: Inverts all 32 bits of the value. I.e.: ~5 is -6. + + .s Sizing: Any value will be extended to LONG from the size + specified. I.e.: $89.b is $ffffff89. + + The size of the result is used both for the assembler when + using memory direct effective addresses and for data input + for the memory edit command etc. If multiple sizing + operations occur, the last sizing operation in the lowest + bracket level defines the finial size of the result. + + * / Multiply and divide: Signed LONG multiplication and division. + I.e.: -$56*5 is fffffe52, 9/-3 is -3. + + \ Modulo: Signed LONG modulo. I.e.: 11\4 is 3. + + + - Addition and subtraction: LONG addition and subtraction. + I.e.: 1000-9 is 991. + + << Shift left: Correspond to a multiplication with 2 to the nth + power, whereas n is the numer of bits to be shifted. I.e.: + $20<<8 is $2000. + + >> Shift right: Corresponds to a division by 2 to the nth + power, whereas n is the numer of bits to be shifted. I.e.: + $2000>>8 is $20. + + & Logical AND: LONG AND operation. I.e.: $1234&$ff00 is + $1200. + + ! Logical EOR: LONG EOR operation. I.e.: $c1!$54 is $a5. + + | Logical OR: LONG OR operation. I.e.: $1200|$34 is $1234. + + <> Not equal: Result of this operation is -1 if values not + equal, else 0. I.e.: 5<>6 is -1, 3<>3 is 0. + + = Equal: Result of this operation is -1 if values are equal, + else 0. I.e.: 5=6 is 0, 3=3 is -1. + + <= Lower or same: Signed comparison, result is -1 if value left + of operator is lower or the same than the right value. I.e.: + 1<=1 is -1, 6<=5 is 0. + + >= Greater or equal: Signed comparison, result is -1 if value + left of operator is greater or equal than the right value. + I.e.: 2=>1 is -1, 0=>5 is 0. + + < Less: Signed comparison, result is -1 if value left of + operator is less than the right value. I.e.: 1<1 is 0, 0<5 + is -1. + + > Greater: Signed comparison, result is -1 if value left of + operator is greater than the right value. I.e.: 2>1 is -1, + 0>5 is 0. + + + As for the form of values, the following are supported: + + + $x Hexadecimal number: A number in hexadecimal form, consisting + of max. 8 digits 0-9 and a-f. I.e.: $badcode1 + + #x Decimal number: A number in decimal form, consisting of + digits 0-9. I.e.: #1992. + + %x Binary number: A number in binary form, consisting of max. + 32 digits 0 and 1. I.e.: %1010001011. + + ' " ASCII chars: A number consisting of max. 4 ASCII chars. + The string must be introduced and ended with the same sign. + I.e.: "SIM!", 'DATA', '"MC"'. + + ! Last result: Stands for the result of the last term + calculated. I.e.: To display 16 bytes at $50000 one can + enter the command 'm $50000 !+$10'. + + @ Actual address: Stands for the actual address used by dump + commands and edit/assembly commands. I.e.: @-100. + + SIM SIM start: The program and base address of SIM. + + D0-D7 ,A0-A7 ,PC ,SP ,SSP ,USP ,SR ,CCR and M0-M7 + (MSP/ISP, VBR for 68020+) + + CPU registers: The calculator can directly use the contents + of these registers. SSP is the supervisor stack pointer, USP + the userstack pointer, SP and A7 the actual stack pointer + (68020+: SSP is the actual supervisor stack pointer, MSP and + ISP the master and interrupt stack pointers, VBR the vector + base register). + + M0-M7 are variables, M0 and M1 are used as view start + registers. I.e.: pc+10-d0. + + SEA, TEA, SX, TX + + The effective address of the source and destination EA of the + instruction at the PC. The SX and TX registers are 1 if the + instruction has a source/destination EA, otherwise 0 and the + corresponding EA register is undefined. I.e.: sea*sx + + x,\x Symbols: Uses the symbol specified after a '\'. I.e. \start. + + + A term normally ends at a space, a colon, a semicolon, a komma or a carriage + return. If you have opened a bracket, you can have spaces between operators + and values, but ONLY then. Otherwise, the end of the term will not be there + where you wanted it to be. + + The calculator can work in decimal or hexadecimal mode. In decimal mode you + do not have to write the '#' in front of a decimal number, but for + hexadecimal numbers, the '$' is neccessary. In hexadecimal mode you do not + have to write the '$' for hexadecimal numbers, but for decimal numbers, the + '#' is neccessary. + + Hexadecimal mode is usually used to get addresses and hexadecimal numbers. + For the other cases decimal mode is used, also for the assembler. + + + + 5.3 Data Line + ================= + + + The data line is used to specify data for different commands like find, edit + or occupy. The data line consists of four elements: + + + - Hexadecimaly numbers are introduced with or without '$'. They can be + as long as neccessary. The number is ended by a char that is no + digit. If you enter an odd number of digits, the last digit will be + taken as byte, its higher nibble zeroed. Spaces are allowed between + digits. + + - Assembler instructions are initiated by a 'n' character, then the + instruction follows. + + - Calculator terms are initiated by a '?', then the term follows. The + size of the result will be considered (LONG=4 bytes,WORD=2 bytes and + BYTE=1 byte). + + - Ascii chars are either initiated by ' or " and closed with the same + or a . The string length is only limited by the line length. + + + An example, using all the elements from above. The line: + + + 45,"ABC",njmp $60000,?[$fc0000].w,6666 + + + is interpreted as: + + 45 41 42 43 4e f9 00 06 00 00 11 11 66 66 + |- |------- |---------------- |---- |---- + | | | | | + 45 "ABC" jmp $60000 [$fc0000].w 6666 + + + A data line ends at a space or an illegal char. Between the komma that + separates two datatypes and the next datatype there can be spaces. also + between digits (only for the edit command, not for find and occupy). + + + + 5.4 The Debug Server Entrance + ================================= + + + The debug server entrance is specially concieved for the cooperation between + SIM and another debugger or loader, i.e. 'SIMBug'. It enables the debug + server to give control over a program to SIM and SIM to return control to the + debug server. + + In a part of the SIM base, there is space to store the registers d0-a6, USP + and SSP (ISP/MSP), SR and PC of the program that is monitored. The debug + server can fill in this table. Additionally, It can specify a reentry PC, + SR, USP and SSP (ISP/MSP). When it enters SIM by the debug server entrance, + SIM takes the registers out of the table and copies them into the register + buffer. SIM has now the control over the program. The length field + indicates how far you have initialised the list from the length field. If + you do not fill in the entier structure, the rest will be zeroed. + + If you want to give control back to the debug server, i.e. to unload the + program, you can use the 'q' command (or 'Q' or AMIGA-q). SIM does then copy + the registers back into the base area and takes the reentry PC, SR USP and + SSP (ISP/MSP) as the actual ones. To be sure that the debug server is still + there, SIM looks at the address if the longword $4f4b4159 + ("OKAY") is there. If the longword is there, it exits. That way, it returns + to the address specified by the reentry PC with reentry stacks and a reentry + SR. The registers do not contain sencefull information, appart a6 which + contains the base/codeaddress of SIM. In case you transfered SIM, the debug + server knows where you put it. + + The debug server can now read out the table with the registers and use them + for itself. + + + + 5.5 The SIM Base + ==================== + + + At the start of SIM, the different entrances are located, the backups and + reentry values and the debug server data structure. The structure of this + base is documented here. The offsets described won't be changed in higher + versions, I hope, but I feel free to extend it at the upper end: + + ;--- Base --------- ! STRUCT toolbase ;+0 The start address of SIM in memory ;--- Display ------ ! APTR plane ;+0 The start address of the $5000 bytes display ram ! (must be graphic memory!) ! ! APTR backup ;+4 The start address of the backup of the display. ! When not zero, SIM will copy what is in the ! memory of the future display to this address when entered and copy it back when left. ;--- Entrances ---- ! JMP entrance1 ;+8 Entrance for JSR. Here you can simply enter SIM by a 'JSR' to this address. ! ! JMP entrance2 ;+12 Entrance for Exec's traphandle. When you want to ! use SIM as traphandler of your task, write this address to . ! ! JMP entrance3 ;+16 Debug server entrance. ! LONG 0 ;+20 *** RESERVED FOR EXPANSION *** ! ;--- Traps -------- ;When a trap is set directly, its vector is set to ! ;the corresponding entrance in here. ! JMP entrance22 ;+24 Bus error ! JMP entrance23 ;+28 Address error ! JMP entrance24 ;+32 Illegal instruction ! JMP entrance25 ;+36 Divide-by-zero ! JMP entrance26 ;+40 CHK instruction ! JMP entrance27 ;+44 TRAPV instruction ! JMP entrance28 ;+48 Privilege violation ! JMP entrance29 ;+52 Trace ! JMP entrance2a ;+56 Op Code 1010 ! JMP entrance2b ;+60 Op Code 1111 ;--- Signal ------- ! LONG "SIM!" ;+64 This Long signals that this is SIM ! LONG version ;+68 Version of SIM as 4 ASCII chars ! ;--- Backups ------ ;When SIM is entered it backups some customregisters ! ;and vectors here. ! WORD dmacon ;+72 $DFF096/002 ! WORD intena ;+74 $DFF09A/01C ! WORD intreq ;+76 $DFF09C/01E ! LONG level2 ;+78 VBR+$68 ! LONG level3 ;+82 VBR+$6C ! ! BYTE ciaacra ;+86 $BFEE01 ! BYTE ciaacrb ;+87 $BFEF01 ! BYTE ciabcra ;+88 $BFDE00 ! BYTE ciabcrb ;+89 $BFDF00 ! BYTE ciaapra ;+90 $BFE001 ! BYTE ciaaprb ;+91 $BFE101 ! BYTE ciaaddra ;+92 $BFE201 ! BYTE ciaaddrb ;+93 $BFE301 ! BYTE ciabddra ;+94 $BFD200 ! BYTE ciaasp ;+95 $BFEC01 ! LONG vpos ;+96 $DFF004 + ;--- Reentry ------ ;Reentry values of things that can't be saved. ! ;When SIM is left, it inits the registers named ! ;with the values in this list. ! ! WORD $2981 ;+100 DIWSTRT ! WORD $29c1 ;+102 DIWSTOP ! WORD $0038 ;+104 DDFSTRT ! WORD $00d0 ;+106 DDFSTOP ! WORD $5200 ;+108 BPLCON0 ! WORD $0000 ;+110 BPLCON1 ! WORD $0000 ;+112 BPLMOD1 ! WORD $0000 ;+114 COLOR00 ! WORD $0000 ;+116 COLOR01 ;--- ICR Special -- ;The ICR data and mask. ! BYTE lasticr ;+118 $BFED00 read ! BYTE reentryicrmask ;+119 $BFED00 write + ;--- Distances ---- ;Distances to internal structures. ! LONG disasscalc-base ;+120 Distance to disasscalc module ! LONG preferences-base;+124 Distance to preferences structure ! ;--- Debug -------- ;Debug server structure for entrance 3. ! LONG 0 ;+128 Offset from here to end of inited part ! LONG "????" ;+132 Sign of server + ;--- Program ------ ;The registers of the program that is debugged. ! LONG 0 ;+136 Register d0 ! LONG 0 ;+140 Register d1 ! LONG 0 ;+144 Register d2 ! LONG 0 ;+148 Register d3 ! LONG 0 ;+152 Register d4 ! LONG 0 ;+156 Register d5 ! LONG 0 ;+160 Register d6 ! LONG 0 ;+164 Register d7 ! LONG 0 ;+168 Register a0 ! LONG 0 ;+172 Register a1 ! LONG 0 ;+176 Register a2 ! LONG 0 ;+180 Register a3 ! LONG 0 ;+184 Register a4 ! LONG 0 ;+188 Register a5 ! LONG 0 ;+192 Register a6 ! LONG 0 ;+196 User stack pointer ! LONG 0 ;+200 Supervisor stack pointer/ISP ! LONG 0 ;+204 PC of program ! WORD 0 ;+208 SR of program ! ;--- Server data -- ! LONG 0 ;+210 Reentry routine of server ! LONG 0 ;+214 Reentry usp of server ! LONG 0 ;+218 Reentry ssp of server/ISP ! LONG 0 ;+222 Reentry sr of server + ;--- Extension ---- ! APTR 0 ;+224 Pointer to zero ended list of APTRs that point to zero ended texts. The texts in this list are printed and the pointer is cleared ! APTR 0 ;+228 Pointer to task structure ! APTR 0 ;+232 Segmentlist ! APTR 0 ;+236 Symbollist with labels ! ! LONG 0 ;+240 MSP (68020+ only) ! LONG 0 ;+244 Reentry MSP (68020+ only) ! ! LONG 0,0 ; RESERVED ! ! LONG sim_size ;+256 Size of SIM ! BYTE 0 ;+260 CPU information ! BYTE 0 ;+261 MMU information ! WORD 0 ;+262 BEAMCON0 reentry value ! LONG 0 ;+264 VBR ! ! ! ;--- End ---------- ;+268 This is the end of the actual structure ! ! ! ! 5.6 Errors ! ============== ! ! ! SIM is a flexible tool. Therefore the user can do many mistakes. In this ! chapter, all errors are explained. When an error occurs that bases on an ! error in the command line (which in fact is in most cases so) SIM prints the ! error text in the line of the cursor and copies the command line in the next ! line. The cursor is in the line of the copied command line below the char or ! the word that probably caused the error. ! ! ! ! ! ! ! ! Assembler errors ! ---------------- ! ! ! illegal instruction: ! ! The assembler does not know this instruction. ! ! illegal value: ! ! An number is higher or less than it should be. ! ! illegal ea: ! ! This addressing mode is not allowed. ! ! illegal size: ! ! An instruction has either no size at all or does not support ! this size. ! ! illegal operator: ! ! An operator is not allowed here. ! ! line malformed: ! ! Something is undefinably wrong. ! ! too few info: ! ! Some part of this instruction is missing. ! ! illegal sea: ! ! An illegal effective address as source. ! ! illegal tea: ! ! An illegal effective address as destination. ! ! illegal char: ! ! The character is not allowed here. ! ! illegal condition: ! ! The condition of a Bcc, DBcc or Scc is inexistent. ! ! illegal direction: ! ! The direction for bitshifting is neither left nor right. ! ! ! ! ! ! ! ! Calculator errors ! ----------------- ! ! bracketerror: ! The number of brackets opened and closed does not match. + overflow: + The result is larger than $ffffffff or ±$8000000, or you have + divided by zero or you do more than 30 operations. ! illegal value: + The calculator cannot interprete that as a number. ! illegal operator: + This is no operator for mathematical operations supported by + the calculator. ! no value given: ! You have forgotten to give a term, or the very first value of ! an expected term is of an unknown type. ! Disk errors ! ----------- ! disk error: ! Something went wrong with the disk access, either the track ! that is read is damaged or the disk was writeprotected. In ! most cases you will get a warning in the statusline of the ! disk access display. + file not found: ! SIM could not locate the file you want to load or the path ! given was faulty. ! not enough space: ! The file to be saved won't fit on the disk. ! disk full: ! That error should not occur. ! directory error: + If something goes wrong while listing the directory of a + disk, i.e. bad hashes or disk damaged, this error is + returned. ! illegal path: ! SIM cannot locate the directory you want to list. ! Other errors ! ------------ ! too much: + The start address given for a command is higher than the end + address. + breakpointerror: ! SIM has no more breakpoints free or it could not set a ! breakpoint there, either because ROM is read only or it is ! not possible to put breakpoints in the memory presently ! occupied by the SIM code. ! 5.7 Footer Messages ! ======================= ! As mentioned earlier, there is a status field in the footer line. This space ! is used to transmit messages to the user that are not as important as to be ! printed in the monitor or serve as additional information. Currently the ! following texts can appear there due to an event: ! SIM is awaiting commands. ! busy As soon as SIM is executing commands this text is ! printed. This shows you If SIM is working or not. ! break When you break the execution of a command SIM replies ! with this message. ! pause When you pause. ! lock When you press SHIFT-CTRL to stop all output for some ! time. ! error When an error occurs. ! Fx on/off When you toggle function keys SIM returns the new ! state to you this way. ! flushed When you flush the keystatefield. ! prt err When the printer has troubble (paper out/select...). ! cnd err When an error occurs while calculating the condition ! terms of breakpoints or trace, SIM is entered and ! this text appears. + prt on/off When you toggle the printer and it is available. + AUT on/off When you toggle the auto unmodify traps feature. + US/** kmap When you select the keymap. ! indir x When you use indirects the current indirect level is ! shown. + returned When you return from the keyboard restoring routine + by entering 'return'. + KBF on/off When you toggle the keyboard buffer killer. ! more When the directory of a disk does not fit in the ! visible monitor part, SIM writes that message to tell ! you that there is more to see. + semi/full Whether or not the full charset is printable. ! symbols/opcode Symbols are available and used or not (disassembly ! with symbols or opcode field). ! $xxxx() Display offset for d16(ax) EAs. ! label() Display symbol for all d16(ax) EAs. + >label() Display symbol of d16(ax) EAs of instruction at PC. + Use offset for other instructions. + MMU on/off The status of the MMU tree (68020+ version only). ! MSP/SR flags If the register list shall either display the MSP or ! the SR flags (68020+ version only). + found If the scan for an access address was successful. ! caln/no EA If or if not the calculation of EAs is allowed while ! tracing. + ***************************************************************************** + 6. Appendix + ***************************************************************************** ! 6.1 Acknowledgements ! ======================== ! Big thanks must go to all the people who helped me in this project and many ! others: ! - Daniel Weber for continuous testing of all new features I ! inserted, some good and some bad ideas and his mighty ProAsm. ! Not to forget, for all the cool movies each saturday too. + - René Eberhard for more tips, betatesting, exchange of KS 2.0 + knowhow and loads of fun at MicroSpot and Feller and everywhere + else. + - Bryan Ford for many good ideas, betatesting, tons of hints, + profreading my documentations and all the cool e-mail chat + and much, much more. ! - André Dietisheim, Oliver Ferlin, Stefan Strasser, Kay Temirel, ! Ch. Schneider, F. Buergel and Niel Ericson for bugreports and ! ideas. + - Michael Hitch for MC68040 testing. ! - And to all the registered users. + 6.2 Registered Users + ======================== ! Thanks go to the following users who registered and persuaded me that some ! people use this tool: ! Daniel Weber (Switzerland) ! René Eberhard (Switzerland) ! Kay Temirel (Germany) ! Niel Ericson (Canada) ! Roby Leemann (Switzerland) ! Steve Anderson (Canada) ! Jörn Körner (Germany) ! Bryan Ford (USA) ! Dan Babcock (USA) ! Gerd Hesina (Austria) ! Jandl Mario (Austria) + 6.3 Contacting Me + ===================== ! If you want to register, if you have bugreports, question, ideas, flames or ! complaints (constructive criticism is always welcome), or if you just want to ! contact me, write or send a letter to: ! Stefan Walter ! Finsterruetistr. 57 ! 8135 Langnau a./A. ! SWITZERLAND ! Because snail mail is slow, you can also contact me by phone or by sending a ! message to the electronic mail address below (if you call by phone, please ! concider any possible time differences between your location and mine and ! don't wake me up in the night :). ! Phone: Switzerland/(0)1/713-01-46 ! Internet: avalon.physik.unizh.ch!swalter ! ----------------------------------------------------------------------------- ! Stefan Walter, 10.Mar.1993 *** /tmp/pmap.h Tue May 18 01:40:13 1993 --- ./kernel/motorola/m68k/pmap.h Sun May 16 01:20:40 1993 *************** *** 40,45 **** --- 40,46 ---- #ifndef ASSEMBLER + #include #include #include *** /tmp/pcb.c Tue May 18 01:40:18 1993 --- ./kernel/motorola/m68k/pcb.c Fri May 7 21:38:19 1993 *************** thread_t switch_context(old, continuatio *** 126,131 **** --- 126,133 ---- if (old->task != new->task) PMAP_CONTEXT(vm_map_pmap(old->task->map), new); + old->swap_func = continuation; + active_threads[0] = new; active_stacks[0] = new->kernel_stack; *************** thread_t switch_context(old, continuatio *** 132,138 **** fp_restore(&new->pcb->fpu_state); { ! register void (*old_d0)() asm("d0") = old; if(continuation) { --- 134,140 ---- fp_restore(&new->pcb->fpu_state); { ! register thread_t old_d0 asm("d0") = old; if(continuation) { *************** thread_t switch_context(old, continuatio *** 149,155 **** } else { ! asm("illegal"); asm volatile( " pea 0f;" " moveml d2-d7/a2-a7,%1@;" --- 151,157 ---- } else { ! /* asm("illegal"); */ asm volatile( " pea 0f;" " moveml d2-d7/a2-a7,%1@;" *************** load_context(thread_t new) *** 181,186 **** --- 183,189 ---- " moveq #0,d0;" /* No old thread */ " rts" : : "a" (STACK_KS(new->kernel_stack))); + /*NOTREACHED*/ } *************** kern_return_t thread_setstatus(thread, f *** 260,266 **** if (count < THREAD_STATE_REGS_COUNT) return(KERN_INVALID_ARGUMENT); ! state = (struct sun_thread_state *) tstate; pcb = thread->pcb; regs = pcb->user_regs; --- 263,269 ---- if (count < THREAD_STATE_REGS_COUNT) return(KERN_INVALID_ARGUMENT); ! state = (struct thread_state_regs *) tstate; pcb = thread->pcb; regs = pcb->user_regs; *** /tmp/psl.h Tue May 18 01:40:22 1993 --- ./kernel/motorola/m68k/psl.h Sun May 16 01:54:09 1993 *************** *** 0 **** --- 1 ---- + /* Should have symbolic priority level definitions here */ *** /tmp/machparam.h Tue May 18 01:40:27 1993 --- ./kernel/motorola/m68k/machparam.h Sun May 16 21:38:08 1993 *************** *** 26,79 **** /* * Generic interrupt priority definitions for m68k processors * ! * Author: Bryan Ford */ #ifndef _m68k_machparam_ #define _m68k_machparam_ /* Set the interrupt priority level and save the old level */ ! static inline int spln(unsigned short spl) { ! volatile unsigned short sr; ! asm("movew sr,%0" : "=d" (sr)); ! asm("movew %0,sr" : : "d" (spl | (sr & 0xf8ff))); ! return(sr & 0x700); } /* Set the interrupt priority level back to the previous level */ ! static inline void splx(unsigned short pri) { ! spln(pri); } /* Generic spl definitions for m68k interrupt priorities */ ! static inline int spl7(void) { ! volatile unsigned short sr; ! asm("movew sr,%0; oriw #0x0700,sr" : "=d" (sr)); ! return(sr & 0x700); } ! #define spl6() spln(0x0600) ! #define spl5() spln(0x0500) ! #define spl4() spln(0x0400) ! #define spl3() spln(0x0300) ! #define spl2() spln(0x0200) ! #define spl1() spln(0x0100) ! static inline int spl0(void) { unsigned short sr; ! asm("movew sr,%0; andiw #0xf8ff,sr" : "=d" (sr)); ! return(sr & 0x700); } #endif _m68k_machparam_ --- 26,144 ---- /* * Generic interrupt priority definitions for m68k processors * ! * Author: Bryan Ford ! * Contributors: Niklas Hallqvist */ #ifndef _m68k_machparam_ #define _m68k_machparam_ + #include + + #ifdef SPL_DEBUG + + extern int spl7 (); + extern int spl6 (); + extern int spl5 (); + extern int spl4 (); + extern int spl3 (); + extern int spl2 (); + extern int spl1 (); + extern int spl0 (); + extern int spln (unsigned short spl); + extern void splx (unsigned short spl); + + #else /* inline definitions then */ + + #ifdef MASKED_SPL + /* Set the interrupt priority level and save the old level */ ! static inline int spln (unsigned short spl) { ! unsigned short sr, scratch; ! asm volatile ("movew sr,%0;" ! "movew %0,%1;" ! "andiw #0xf8ff,%1;" ! "orw %2,%1;" ! "movew %1,sr;" ! : "=d" (sr), "=d" (scratch) : "d" (spl) : "cc"); ! return sr & 0x700; } /* Set the interrupt priority level back to the previous level */ ! static inline void splx (unsigned short pri) { ! unsigned short sr; ! ! asm volatile ("movew sr,%0;" ! "andiw #0xf8ff,%0;" ! "orw %1,%0;" ! "movew %0,sr;" ! : "=d" (sr) : "d" (pri) : "cc"); } /* Generic spl definitions for m68k interrupt priorities */ ! static inline int spl7 (void) ! { ! unsigned short sr; ! ! asm volatile ("movew sr,%0;" ! "oriw #0x0700,sr" ! : "=d" (sr) : : "cc"); ! return sr & 0x700; ! } ! ! static inline int spl0 (void) { ! unsigned short sr; ! asm volatile ("movew sr,%0;" ! "andiw #0xf8ff,sr" ! : "=d" (sr) : : "cc"); ! return sr & 0x700; } ! #define spl6() spln (0x0600) ! #define spl5() spln (0x0500) ! #define spl4() spln (0x0400) ! #define spl3() spln (0x0300) ! #define spl2() spln (0x0200) ! #define spl1() spln (0x0100) ! ! #else /* MASKED_SPL */ ! static inline int spln (unsigned short spl) { unsigned short sr; ! asm volatile ("movew sr,%0;" ! "movew %1,sr;" ! : "=d" (sr) : "d" (spl) : "cc"); ! return sr & 0x3700; ! } ! ! ! /* Set the interrupt priority level back to the previous level */ ! static inline void splx (unsigned short pri) ! { ! asm volatile ("movew %0,sr" : : "d" (pri) : "cc"); } + #define spl7() spln (0x2700) + #define spl6() spln (0x2600) + #define spl5() spln (0x2500) + #define spl4() spln (0x2400) + #define spl3() spln (0x2300) + #define spl2() spln (0x2200) + #define spl1() spln (0x2100) + #define spl0() spln (0x2000) + + #endif /* MASKED_SPL */ + + #endif /* SPL_DEBUG */ #endif _m68k_machparam_ *** /tmp/mmu.h Tue May 18 01:40:32 1993 --- ./kernel/motorola/m68k/mmu.h Sun May 16 01:13:08 1993 *************** *** 32,37 **** --- 32,38 ---- * Vidas Neverauskas * Ed Sharpe * Bryan Ford + * Michael L. Hitch (68040 MMU) * */ *************** *** 38,61 **** #ifndef _m68k_mmu_ #define _m68k_mmu_ - #include #include - #define M68030 - /* * Parameters which determine the 'geometry' of the M68K page tables in memory. * We assume three levels of page tables. */ #define L1_BITS 4 #define L2_BITS 7 #define L3_BITS 9 #define L4_BITS 0 #define PG_BITS 12 /* * Value to load into M68K Translation Control register. */ #define IS (32-PG_BITS-L1_BITS-L2_BITS-L3_BITS-L4_BITS) #define TC \ (0x80000000) + /* Enable bit */ \ --- 39,70 ---- #ifndef _m68k_mmu_ #define _m68k_mmu_ #include /* * Parameters which determine the 'geometry' of the M68K page tables in memory. * We assume three levels of page tables. */ + #ifdef M68040 + #define L1_BITS 7 + #define L2_BITS 7 + #define L3_BITS 6 + #define L4_BITS 0 + #define PG_BITS 12 + #else #define L1_BITS 4 #define L2_BITS 7 #define L3_BITS 9 #define L4_BITS 0 #define PG_BITS 12 + #endif M68040 /* * Value to load into M68K Translation Control register. */ + #ifdef M68040 + #define TC 0x8000 + #else #define IS (32-PG_BITS-L1_BITS-L2_BITS-L3_BITS-L4_BITS) #define TC \ (0x80000000) + /* Enable bit */ \ *************** *** 65,70 **** --- 74,80 ---- (L2_BITS << 8) + /* TIB */ \ (L3_BITS << 4) + /* TIC */ \ L4_BITS /* TID */ + #endif M68040 /* * Shifts and masks for converting between vaddr's and pfn's. *************** *** 94,99 **** --- 104,115 ---- */ typedef struct l1_entry { unsigned long + #ifdef M68040 + table_addr:28, /* pointer table address */ + pg_used:1, /* page used */ + prot:1, /* write protect */ + dtype:2; /* descriptor type */ + #else lu:1, /* lower/upper limit */ limit:15, /* table search limit */ #ifdef M68851 *************** typedef struct l1_entry { *** 111,116 **** --- 127,133 ---- unsigned long table_addr:28, /* base address of descriptor table */ :4; /* not used */ + #endif M68040 } pt_ldesc_t; /* template for bit-manipulation */ *************** typedef union pt_ldesc_template { *** 118,124 **** --- 135,143 ---- pt_ldesc_t pt_ldesc; struct double_bits { unsigned long lo; + #ifndef M68040 unsigned long hi; + #endif } bits; } pt_ldesc_template_t; *************** typedef struct pt_entry { *** 161,166 **** --- 180,190 ---- :23, /* */ #endif PMAP_PGBYTES==4096 #endif PMAP_PGBYTES==8192 + #ifdef M68040 + wired:1, /* U0 */ + sup:1, /* Supervisor */ + cache_m:2, /* Cache mode */ + #else wired:1, /* page-wired bit; (stolen from pfn) */ #ifdef M68851 gate:1, /* gate-ing for module descriptors */ *************** typedef struct pt_entry { *** 173,178 **** --- 197,203 ---- #else :1, #endif M68851 + #endif M68040 modified:1, /* page has been modified */ pg_used:1, /* page has been (used) referenced */ prot:1, /* protection - read/write */ *************** typedef union pte_template { *** 191,196 **** --- 216,222 ---- /* * Level 1 page table entries are M68K long-format table descriptors, + * (68040 used short-format) * level two page table entries are M68K short-format table descriptors, * level three are M68k short-format page descriptors. */ *************** typedef pt_sdesc_t l2_entry_t; *** 394,407 **** --- 420,443 ---- static inline void load_crp(void *lvl1_paddr) { + #ifdef M68040 + volatile void *crp = lvl1_paddr; + asm volatile("cpusha dc;nop"); + asm volatile("movel %0,d0;movec d0,srp;movec d0,urp" : : "a" (lvl1_paddr) : "d0"); + #else struct {long cntl; void *paddr;} crp = {0x80000000 | DT_LONG, lvl1_paddr}; asm volatile("pmove %0@,crp" : : "a" (&crp)); + #endif M68040 } static inline void load_tc(long tc) { + #ifdef M68040 + asm volatile("movel %0@,d0;movec d0,tc" : : "a" (&tc) : "d0"); + #else asm volatile("pmove %0@,tc" : : "r" (&tc)); + #endif M68040 } *** /tmp/pcb.h Tue May 18 01:40:37 1993 --- ./kernel/motorola/m68k/pcb.h Thu May 13 08:39:32 1993 *************** struct fpu_state *** 49,55 **** static inline void fp_save(struct fpu_state *state) { ! asm volatile("fsave %0@; tstb %0@; beq 0f; fmovem fp0-fp7,%0@-; fmovem fpcr/fpsr" /*"/fpiar"*/ ",%0@-; 0:" : : "a" (&state->istate)); } --- 49,55 ---- static inline void fp_save(struct fpu_state *state) { ! asm volatile("fsave %0@; tstb %0@; jeq 0f; fmovem fp0-fp7,%0@-; fmovem fpcr/fpsr" /*"/fpiar"*/ ",%0@-; 0:" : : "a" (&state->istate)); } *************** fp_save(struct fpu_state *state) *** 56,62 **** static inline void fp_restore(struct fpu_state *state) { ! asm volatile("tstb %0@; beq 0f; fmovem %1@+,fpcr/fpsr" /*"/fpiar"*/ "; fmovem %1@,fp0-fp7; 0: frestore %0@" : : "a" (&state->istate), "a" (&state->status)); } --- 56,62 ---- static inline void fp_restore(struct fpu_state *state) { ! asm volatile("tstb %0@; jeq 0f; fmovem %1@+,fpcr/fpsr" /*"/fpiar"*/ "; fmovem %1@,fp0-fp7; 0: frestore %0@" : : "a" (&state->istate), "a" (&state->status)); } *** /tmp/pmap.c Tue May 18 01:40:44 1993 --- ./kernel/motorola/m68k/pmap.c Thu May 13 08:39:29 1993 *************** *** 32,37 **** --- 32,38 ---- * Vidas Neverauskas * Ed Sharpe * Bryan Ford + * Michael L. Hitch (68040 MMU) * */ *************** pmap_create_kmap() *** 450,455 **** --- 451,457 ---- pt_ldesc_template_t l1_ktemplate; int cnt; + #ifndef M68040 l1_ktemplate.bits.lo = 0; l1_ktemplate.pt_ldesc.lu = 1; #ifdef M68851 *************** pmap_create_kmap() *** 457,462 **** --- 459,465 ---- #endif M68851 l1_ktemplate.pt_ldesc.sup = 1; l1_ktemplate.pt_ldesc.dtype = DT_SHORT; + #endif M68040 lvl2_paddr = (l2_entry_t *)(kernel_pmap->lvl1_paddr + 2*L1_ENTRIES); lvl2_vaddr = (l2_entry_t *)(kernel_pmap->lvl1_vaddr + 2*L1_ENTRIES); *************** pmap_create_kmap() *** 469,478 **** --- 472,486 ---- * [USER_L1_ENTRIES are never referenced in the kernel pmap.] */ for (cnt = 0; cnt < KERNEL_L1_ENTRIES; cnt++) { + #ifdef M68040 + lvl1_vaddr->bits.lo = (unsigned int)lvl2_paddr + DT_SHORT; + (lvl1_vaddr + L1_ENTRIES)->bits.lo = (unsigned int)lvl2_vaddr + DT_SHORT; + #else lvl1_vaddr->bits.hi = (unsigned int)lvl2_paddr; (lvl1_vaddr + L1_ENTRIES)->bits.hi = (unsigned int)lvl2_vaddr; lvl1_vaddr->bits.lo = l1_ktemplate.bits.lo; (lvl1_vaddr + L1_ENTRIES)->bits.lo = l1_ktemplate.bits.lo; + #endif M68040 lvl1_vaddr++; lvl2_paddr += 2*L2_ENTRIES; lvl2_vaddr += 2*L2_ENTRIES; *************** pmap_map (vm_offset_t virt, vm_offset_t *** 596,601 **** --- 604,617 ---- #endif DBG aprot = m68k_protection (kernel_pmap, prot); template.bits = PMAP_TRUNC_PAGE(start) | aprot | DT_PAGE; + #ifdef M68040 + template.pte.sup = 1; + #if 0 + template.pte.cache_m = 0; /* cacheable, copyback */ + #endif + if (start < 0x01000000) /* Inhibit cache & serialize */ + template.pte.cache_m = 2; /* 68000 address space */ + #endif M68040 for (num_phys_pages = PMAP_BTOP(PMAP_ROUND_PAGE(end - start)); num_phys_pages > 0; num_phys_pages--) { *************** pmap_create(size) *** 1074,1081 **** --- 1090,1099 ---- int cnt; pt_ldesc_template_t l1_utemplate; + #ifndef M68040 l1_utemplate.bits.lo = 0; l1_utemplate.pt_ldesc.lu = 1; + #endif /* * A software use-only map doesn't even need a map. *************** pmap_create(size) *** 1113,1122 **** --- 1131,1145 ---- */ l1 = (pt_ldesc_template_t *)lvl1; for (cnt = USER_L1_ENTRIES; cnt>0; cnt--) { + #ifdef M68040 + l1->bits.lo = 0; + (l1 + L1_ENTRIES)->bits.lo = (vm_offset_t) L2_ENTRY_NULL; + #else l1->bits.hi = 0; l1->bits.lo = l1_utemplate.bits.lo; (l1 + L1_ENTRIES)->bits.hi = (vm_offset_t) L2_ENTRY_NULL; (l1 + L1_ENTRIES)->bits.lo = l1_utemplate.bits.lo; + #endif M68040 l1++; } *************** pmap_expand(map, v) *** 2033,2041 **** --- 2056,2066 ---- /* fill in the level 2 table */ l1 = (pt_ldesc_template_t *) L1ENT(map, l2g_va); + #ifndef M68040 l1_template.bits.lo = 0; l1_template.pt_ldesc.lu = 1; l1_template.pt_ldesc.dtype = DT_SHORT; + #endif #if L2_ZONE bzero(lvl2, 2*L2_SIZE); #else *************** pmap_expand(map, v) *** 2045,2054 **** --- 2070,2084 ---- l2_vaddr = (vm_offset_t) lvl2; l2_paddr = pmap_extract (kernel_pmap, l2_vaddr); for (i = L2_GROUP_SIZE; i>0; i--) { + #ifdef M68040 + l1->bits.lo = l2_paddr | DT_SHORT; + (l1 + L1_ENTRIES)->bits.lo = l2_vaddr | DT_SHORT; + #else l1->bits.hi = l2_paddr; l1->bits.lo = l1_template.bits.lo; (l1 + L1_ENTRIES)->bits.hi = l2_vaddr; (l1 + L1_ENTRIES)->bits.lo = l1_template.bits.lo; + #endif l2_vaddr += L2_SIZE*2; l2_paddr += L2_SIZE*2; l1++; *************** pmap_change_caching (map, v, cached) *** 2436,2442 **** --- 2466,2476 ---- panic ("pmap_change_caching: pte missing"); for (i = ptes_per_vm_page; i>0; i--) + #ifdef M68040 + (pte++)->cache_m = cached ? 0 : 2; + #else (pte++)->no_cache = !cached; + #endif M68040 FLUSH_ATC_ENTRIES(pmap, v, v + PAGE_SIZE); *************** pmap_collect(pmap) *** 2711,2720 **** --- 2745,2759 ---- */ if (!l2_wired) { for (l1 = l1p; l1 < (l1p+L2_GROUP_SIZE); l1++) { + #ifdef M68040 + ((pt_ldesc_template_t *) l1) -> bits.lo = 0; + ((pt_ldesc_template_t *) l1+L1_ENTRIES) -> bits.lo = 0; + #else ((pt_ldesc_template_t *) l1) -> bits.lo = 0; ((pt_ldesc_template_t *) l1) -> bits.hi = 0; ((pt_ldesc_template_t *) l1+L1_ENTRIES) -> bits.lo = 0; ((pt_ldesc_template_t *) l1+L1_ENTRIES) -> bits.hi = 0; + #endif } L2_FREE(l2grp); } *************** static char *dtype_names[4] = {"INVALID" *** 3717,3722 **** --- 3756,3775 ---- dtype_names[p->dtype] ); + #ifdef M68040 + #define PRINT_PTE_DESC(p) \ + printf("%08X : ", \ + ((pte_template_t *)p)-> bits ); \ + printf("pfn=0x%X, wired=%d, cache_inhibit=%d, modified=%d, used=%d, prot=%d, dtype=%s\n", \ + /* gate and lock fields not available on 68030 */ \ + p->pfn, \ + p->wired, \ + p->cache_m, \ + p->modified, \ + p->pg_used, \ + p->prot, \ + dtype_names[p->dtype] ); + #else #define PRINT_PTE_DESC(p) \ printf("%08X : ", \ ((pte_template_t *)p)-> bits ); \ *************** static char *dtype_names[4] = {"INVALID" *** 3729,3734 **** --- 3782,3788 ---- p->pg_used, \ p->prot, \ dtype_names[p->dtype] ); + #endif /* *************** pmap_t pmap; *** 3788,3796 **** --- 3842,3858 ---- printf(" Level 1 table at 0x%X (0x%X):\n", l1p, l1v); for (i = 0; i < L1_ENTRIES; i++, l1p++, l1v++) { printf(" (%x)phys: ", i); + #ifdef M68040 + PRINT_SHORT_DESC(l1p); + #else PRINT_LONG_DESC(l1p); + #endif printf(" (%x)virt: ", i); + #ifdef M68040 + PRINT_SHORT_DESC(l1v); + #else PRINT_LONG_DESC(l1v); + #endif } } *************** boolean_t long_format; *** 3854,3860 **** --- 3916,3924 ---- printf(" level 1 table at 0x%X (virt shadow at 0x%X)\n", l1p, l1v); for (i = 0; i < L1_ENTRIES; i++, l1p++, l1v++) { if (prev_entry_lo == ((pt_ldesc_template_t *)l1p)->bits.lo + #ifndef M68040 && prev_entry_hi == ((pt_ldesc_template_t *)l1p)->bits.hi + #endif && L1IDX(va) != i && i != L1_ENTRIES-1) { n_dup_entries++; continue; /* suppress duplicate entry */ *************** boolean_t long_format; *** 3865,3879 **** --- 3929,3953 ---- n_dup_entries = 0; } prev_entry_lo = ((pt_ldesc_template_t *)l1p)->bits.lo; + #ifndef M68040 prev_entry_hi = ((pt_ldesc_template_t *)l1p)->bits.hi; + #endif if (L1IDX(va) == i) printf(" >> (%x)phys: ", i); else printf(" (%x)phys: ", i); + #ifdef M68040 + PRINT_SHORT_DESC(l1p); + #else PRINT_LONG_DESC(l1p); + #endif if (L1IDX(va) == i) printf(" >> (%x)virt: ", i); else printf(" (%x)virt: ", i); + #ifdef M68040 + PRINT_SHORT_DESC(l1v); + #else PRINT_LONG_DESC(l1v); + #endif } /* for */ } else { *************** boolean_t long_format; *** 3882,3890 **** --- 3956,3972 ---- l1v += L1IDX(va); printf(" level 1 entry index 0x%X at 0x%X (virt shadow at 0x%X)\n", L1IDX(va), l1p, l1v); printf(" phys: "); + #ifdef M68040 + PRINT_SHORT_DESC(l1p); + #else PRINT_LONG_DESC(l1p); + #endif printf(" virt: "); + #ifdef M68040 + PRINT_SHORT_DESC(l1v); + #else PRINT_LONG_DESC(l1v); + #endif } *** /tmp/amiga_dma.c Tue May 18 01:40:52 1993 --- ./kernel/amiga/amiga_dma.c Thu May 13 08:36:07 1993 *************** *** 28,37 **** * Amiga contributors: Markus Wild * Niklas Hallqvist * Eduardo Horvath */ ! #if defined (A3000) && defined (GVP11) ! #error Both A3000 and GVP11 cant be defined simultaneously #endif #if defined (A3000) || defined (GVP11) || defined (A2091) --- 28,38 ---- * Amiga contributors: Markus Wild * Niklas Hallqvist * Eduardo Horvath + * Michael L. Hitch */ ! #if defined (A3000) + defined (A2091) + defined (GVP11) > 1 ! #error Only one of A3000, A2091 and GVP11 can be defined #endif #if defined (A3000) || defined (GVP11) || defined (A2091) *************** *** 54,59 **** --- 55,74 ---- #endif #include + #ifdef BUFFERED_DMA + /* This is for those people that must DMA into 16-bit memory, although + it might be interesting for us others as well, as a DMA buffer isn't + in VM thus not requiring a max DMA size of 4K. Maybe this speeds up + disk accesses in spite of the extra copying involved. Just note: + DMA buffers are static, i.e. you can't use the memory for anything + else. */ + /* 8 Megs of DMA buffer !!! */ + #define DMA_MEMORY_BASE ((u_char *) 0x00200000) + /* partition 16-bit memory in 1M chunks */ + #define PER_TGT_DMA_SIZE 0x100000 + #define PER_TGT_BURST_SIZE (PER_TGT_DMA_SIZE>>1) + #endif + #define NAMIGA_DMA 1 /* XXX */ /* *************** int dma_in_progress = 0; *** 125,134 **** --- 140,153 ---- static inline vm_offset_t kvtophys (vm_offset_t kv) { + #ifndef DMA_MEMORY_BASE extern pmap_t kernel_pmap; extern vm_offset_t pmap_extract (); return pmap_extract (kernel_pmap, kv); + #else + return kv; + #endif } #ifdef A3000 *************** amiga_dma_new_target (dma, tgt) *** 398,406 **** --- 417,430 ---- /* provide enough space here, the cmd_buf is used for both, commands and (small) results of maintanance commands (ie. inquiry) MAKE SURE THE BUFFERS ARE LONG ALIGNED!! */ + #ifndef DMA_MEMORY_BASE static u_int cmds[NSCSI][8][256/4]; tgt->cmd_ptr = (u_char *) cmds[tgt->masterno][tgt->target_id]; + #else + tgt->cmd_ptr = DMA_MEMORY_BASE + tgt->masterno * PER_TGT_DMA_SIZE * 8 + + tgt->target_id * PER_TGT_DMA_SIZE; + #endif } /* *************** amiga_dma_map (dma, tgt) *** 412,418 **** target_info_t *tgt; { /* ! * We do real DMA. */ if ((tgt->cur_cmd == SCSI_CMD_WRITE) || --- 436,443 ---- target_info_t *tgt; { /* ! * We do real DMA unless we do DMA from/to a buffer (not yet implemented ! * for write operations). */ if ((tgt->cur_cmd == SCSI_CMD_WRITE) || *************** amiga_dma_map (dma, tgt) *** 426,431 **** --- 451,460 ---- tgt->transient_state.out_count = len; + #ifdef DMA_MEMORY_BASE + /* copy initial data to DMA buffer */ + #endif + /* avoid leaks ?? */ if (len < tgt->block_size) { *************** amiga_dma_end_xfer (dma, tgt, bytes_read *** 486,491 **** --- 515,527 ---- { /* would be nice to do this in parallel with xfer, earlier on */ ptr = tgt->dma_ptr + tgt->transient_state.dma_offset; + #ifdef DMA_MEMORY_BASE + /* need to transfer data from DMA buffer to user buffer*/ + if (tgt->cur_cmd == SCSI_CMD_READ || + tgt->cur_cmd == SCSI_CMD_LONG_READ) { + bcopy (ptr, tgt->ior->io_data + tgt->transient_state.copy_count, bytes_read); + } + #endif flush_the_damn_cache (ptr, bytes_read); } } *************** amiga_dma_start_datain (dma, tgt) *** 499,507 **** --- 535,545 ---- register int count; /* setup tgt->dma_ptr to ior->io_data, flush cache */ + #ifndef DMA_MEMORY_BASE if (tgt->cur_cmd == SCSI_CMD_READ || tgt->cur_cmd == SCSI_CMD_LONG_READ) dma_ptr = tgt->ior->io_data; else + #endif /* swear it won't disconnect midway a xfer or else */ dma_ptr = tgt->cmd_ptr; *************** amiga_dma_start_datain (dma, tgt) *** 514,521 **** amiga_dma_read(dma_ptr, count); ! #if 0 ! count = u_min(count, SBIC_TC_MAX); #else /* too bad the Amiga DMA can't chain DMA requests ;-( */ count = u_min (count, PMAP_PGBYTES); --- 552,559 ---- amiga_dma_read(dma_ptr, count); ! #ifdef PER_TGT_BURST_SIZE ! count = u_min(count, PER_TGT_BURST_SIZE); #else /* too bad the Amiga DMA can't chain DMA requests ;-( */ count = u_min (count, PMAP_PGBYTES); *************** amiga_dma_restart_datain_1 (dma, tgt) *** 544,551 **** amiga_dma_read (dma_ptr, count); ! #if 0 ! count = u_min(count, SBIC_TC_MAX); #else /* too bad the Amiga DMA can't chain DMA requests ;-( */ count = u_min (count, PMAP_PGBYTES); --- 582,590 ---- amiga_dma_read (dma_ptr, count); ! #ifdef PER_TGT_BURST_SIZE ! /* copy any data read from DMA buffer to user buffer */ ! count = u_min(count, PER_TGT_BURST_SIZE); #else /* too bad the Amiga DMA can't chain DMA requests ;-( */ count = u_min (count, PMAP_PGBYTES); *************** amiga_dma_start_dataout (dma, tgt, regp, *** 591,599 **** --- 630,640 ---- /* see dma_map, we have set dma_offset to 1 if transferring from ior, else we're transferring from the command buffer */ + #ifndef DMA_MEMORY_BASE if (tgt->transient_state.dma_offset) dma_ptr = tgt->ior->io_data; else + #endif dma_ptr = tgt->cmd_ptr + tgt->transient_state.cmd_count; if (! dma_ptr) *************** amiga_dma_restart_dataout_1 (dma, tgt) *** 622,629 **** amiga_dma_start_dataout (dma, tgt, &count, 0); count = tgt->transient_state.out_count; ! #if 0 ! count = u_min(count, SBIC_TC_MAX); #else /* too bad the Amiga DMA can't chain DMA requests ;-( */ count = u_min (count, PMAP_PGBYTES); --- 663,671 ---- amiga_dma_start_dataout (dma, tgt, &count, 0); count = tgt->transient_state.out_count; ! #ifdef PER_TGT_BURST_SIZE ! count = u_min(count, PER_TGT_BURST_SIZE); ! /* copy user data to DMA buffer */ #else /* too bad the Amiga DMA can't chain DMA requests ;-( */ count = u_min (count, PMAP_PGBYTES); *** /tmp/takeover.asm Tue May 18 01:40:57 1993 --- ./kernel/amiga/takeover.asm Mon May 17 22:09:11 1993 *************** *** 38,43 **** --- 38,48 ---- * The MMU instructions are still realized as 'DC.W's, later there will * hopefully be macros. + * Modified by Michael L. Hitch + * Added support for 68040 MMU: tested at runtime for appropriate MMU setup + * Added support for A68K: A68K changes by defining macros (limited) + * for 68030 and 68040 instructions, data statements for extended addressing + * modes, tried to maintain ProAsm compatibility ********************************************************************* *************** FUNC_CNT SET FUNC_CNT-6 * Standard offs *** 144,149 **** --- 149,161 ---- *** Some symbols directly extracted from include/exec/ *** If neccessary include include files instead + AttnFlags equ 296 + + AFF_68010 equ 1 + AFF_68020 equ 2 + AFF_68030 equ 4 + AFF_68040 equ 8 + MemList equ 322 LH_HEAD equ 0 *************** bhs macro *** 186,191 **** --- 198,286 ---- bcc.\0 \1 endm + * + * These CPU control instructions macros don't attempt to handle all arguments, + * just what is required by their use in takeover.asm + * + movec macro ; , + ifnc \1,d0 + fail MOVEC argument must be d0: \1 + endc + ifc \2,cacr + dc.l $4e7b0002 ; movec d0,ccar + endc + ifc \2,vbr + dc.l $4e7b0801 ; movec d0,vbr + endc + *** 68040 movec instructions + ifc \2,tc + dc.l $4e7b0003 ; movec d0,tc + endc + ifc \2,itt0 + dc.l $4e7b0004 ; move d0,itt0 + endc + ifc \2,itt1 + dc.l $4e7b0005 ; move d0,itt1 + endc + ifc \2,dtt0 + dc.l $4e7b0006 ; move d0,dtt0 + endc + ifc \2,dtt1 + dc.l $4e7b0007 ; move d0,dtt1 + endc + ifc \2,srp + dc.l $4e7b0807 ; move d0,srp + endc + endm + + pmove macro ; + ifc \1,(sp) + ifc \2,tc + dc.l $f0174000 ; pmove (sp),tc + endc + ifc \2,tt0 + dc.l $f0170800 ; pmove (sp),tt0 + endc + ifc \2,tt1 + dc.l $f0170c00 ; pmove (sp),tt1 + endc + ifc \2,srp + dc.l $f0174800 ; pmove (sp),srp + endc + endc ; ifc \1,sp + ifc \1,(a0) + ifc \2,tt0 + dc.l $f0100800 ; pmove (a0),tt0 + endc + endc + endm + + ptestr macro ; + ifnc \1,#5 + fail PTESTR 1st argument not #5: \1 + endc + ifnc \2,(a1) + fail PTESTR 2nd argument not (a1): \2 + endc + ifnc \3,#7 + fail PTESTR 3rd argument not #7: \3 + endc + ifnc \4,a0 + fail PTESTR 4th argument not a0 + endc + dc.l $f0119f15 ; ptestr.q #5,(a1),#7,a0 + endm + + cinva macro + ifnc \1,bc + fail CINVA only BC is defined + endc + dc.w $f4d8 ; cinva bc + endm + + pflusha macro + dc.w $f518 ; pflusha + endm *** SIM symbol node *************** entry *** 277,285 **** \takeover jsr _LVOSuperState(a6) move.w #$2700,sr moveq #0,d0 ! dc.w $4e7b,$0002 ;<*** movec d0,cacr lea stack_top(pc),sp move.w #$7fff,$dff096 ; Turn off all DMA --- 372,385 ---- \takeover jsr _LVOSuperState(a6) + moveq #AFF_68040,d0 ;**** This most likely isn't set on 1.3 + and.w AttnFlags(a6),d0 ;**** Should make a version independant test + move.w d0,CPUtype-entry(a4) + move.l #CPUtype2-entry,d1 ; copy that SIM reboot can easily access + move.w d0,0(a4,d1.l) move.w #$2700,sr moveq #0,d0 ! movec d0,cacr lea stack_top(pc),sp move.w #$7fff,$dff096 ; Turn off all DMA *************** entry *** 287,297 **** lea ROMEND,a1 ; Sniff out the physical location of the Kickstart ROM move.l ROMSIZE,d0 sub.l d0,a1 ; (assumptions: MMU enabled, short page descriptors, ! ! dc.w $f011,$9f15 ;<*** ptestr #5,(a1),#7,a0 ! ; page tables in unmapped memory) ! move.l (a0),d1 clr.b d1 move.l d1,rom_pstart-entry(a4) add.l d0,d1 --- 387,398 ---- lea ROMEND,a1 ; Sniff out the physical location of the Kickstart ROM move.l ROMSIZE,d0 sub.l d0,a1 ; (assumptions: MMU enabled, short page descriptors, ! move.l a1,d1 ! move.w CPUtype(pc),d4 ; if 68040, ! bne.s \ROM040 ; use virtual address ! ptestr #5,(a1),#7,a0 ; page tables in unmapped memory) move.l (a0),d1 + \ROM040 clr.b d1 move.l d1,rom_pstart-entry(a4) add.l d0,d1 *************** entry *** 300,305 **** --- 401,415 ---- move.l d6,a0 ; Beginning of hunk sizes in hunk_header lea 20(a0),a0 + move.w CPUtype(pc),d0 ; if running on 68040, round to page boundary + beq.s \noround + move.l a2,d0 ; round up memory size to 4K page boundary + add.l #$fff,d0 + and.w #$f000,d0 + exg d0,a2 + sub.l a2,d0 ; compute difference + add.l d0,d2 ; adjust memory size + \noround move.l #VM_MIN_KERNEL_ADDRESS,d7 ; Kernel VM relocation offset (d7) sub.l a2,d7 *************** entry *** 400,417 **** move.l a3,sym_length(a2) move.l a3,sym_size(a2) clr.l -(sp) ; Turn off all translation ! dc.w $f017,$4000 ;<*** pmove.l (sp),tc ! dc.w $f017,$0800 ;<*** pmove.l (sp),tt0 ! dc.w $f017,$0c00 ;<*** pmove.l (sp),tt1 moveq #0,d0 ; Make sure the VBR is right for SIM ! dc.w $4e7b,$0801 ;<*** movec d0,vbr sub.l a0,a0 move.l #$4E714EF9,(a0)+ ; Help Exec along during a reboot ! lea ROMEND+2,a1 ! sub.l ROMSIZE,a1 move.l a1,(a0)+ move.l d7,a1 ; Point all the vectors to SIM add.l sim_addr(pc),a1 --- 510,541 ---- move.l a3,sym_length(a2) move.l a3,sym_size(a2) + move.w CPUtype(pc),d0 + bne.s \mmuoff040 clr.l -(sp) ; Turn off all translation ! pmove.l (sp),tc ! pmove.l (sp),tt0 ! pmove.l (sp),tt1 ! bra.s \setvbr ! \mmuoff040 ! moveq #0,d0 ! movec d0,tc ! movec d0,itt1 ! movec d0,itt0 ! movec d0,dtt1 ! movec d0,dtt0 + \setvbr moveq #0,d0 ; Make sure the VBR is right for SIM ! movec d0,vbr sub.l a0,a0 move.l #$4E714EF9,(a0)+ ; Help Exec along during a reboot ! ; lea ROMEND+2,a1 ! ; sub.l ROMSIZE,a1 ! ;XXX this may not work if KickStart not in ROM ! move.l sim_addr(pc),a1 ! add.l #reboot-sim,a1 ; address of reboot code move.l a1,(a0)+ move.l d7,a1 ; Point all the vectors to SIM add.l sim_addr(pc),a1 *************** entry *** 421,435 **** move.l a1,(a0)+ dbra d0,\simize move.l #$000f810f,(sp) ; Transparently translate up to $0fffffff ! dc.w $f017,$0800 ;<*** pmove.l (sp),tt0 neg.l d7 ; Translate the kernel code to its virtual address move.l d7,(sp) move.l #$80000001,-(sp) ! dc.w $f017,$4800 ;<*** pmove.q (sp),srp move.l #$82808880,(sp) ; Doesn't really matter what our geometry is... ! dc.w $f017,$4000 ;<*** pmove.l (sp),tc addq #8,sp rts ; Drop into SIM's debug server (in virtual memory) --- 545,609 ---- move.l a1,(a0)+ dbra d0,\simize + move.w CPUtype(pc),d0 + bne.s \init040 move.l #$000f810f,(sp) ; Transparently translate up to $0fffffff ! pmove.l (sp),tt0 neg.l d7 ; Translate the kernel code to its virtual address move.l d7,(sp) move.l #$80000001,-(sp) ! ;XXX A68K doesn't like the .q size field, even when skipped with ifnd ! ; pmove.q (sp),srp ! pmove (sp),srp move.l #$82808880,(sp) ; Doesn't really matter what our geometry is... ! pmove.l (sp),tc addq #8,sp + rts + \init040 + move.l #$000fa000,d0 ; Transparently translate up to $0ffffff + movec d0,itt0 ; Cacheable for instructions + eori.w #$0040,d0 + movec d0,dtt0 ; Cache inhibited, serialized for data + ;** set up MMU tables to translate the kernel code to it's virtual address + move.l code_addr(pc),a0 ; allocate 1st level table at end + add.l d2,a0 ; of the memory chunk we found + lea -128*4(a0),a0 ; Assumes end is on 512 byte boundary + move.l a0,d0 + movec d0,srp + ;XXX assumes VM_MIN_KERNEL_ADDRESS is on 32M boundary + move.l #(VM_MIN_KERNEL_ADDRESS>>23),d0 ; offset to 2nd level table pointer + lea -128*4(a0),a1 ; address of 2nd level table + move.l a1,d1 ; 1st level descriptor + addq.w #2,d1 ; type = resident + move.l d1,0(a0,d0) + lea -8*64*4(a1),a0 ; address of 1st page table + move.l a0,d0 ; 2nd level descriptor + addq.w #2,d0 ; type = resident + ;XXX use MIN_PMEM to compute number of tables to set up + ;XXX set up 2M (8 * 256k) + ;XXX assumes VM_MIN_KERNEL_ADDRESS is on 256K boundary + moveq #8-1,d1 ; number of 2nd level entries + \build_2 + move.l d0,(a1)+ + add.l #$00000100,d0 + dbra d1,\build_2 + move.l code_addr(pc),d0 ; get physical address + add.w #$0481,d0 ; form 1st page descriptor + ;XXX can we run with copyback cache on? + ;XXX use MIN_PMEM to compute number of tables + ;XXX set up 2M (512 * 4K) + move.w #512-1,d1 ; number of descriptors to set up + \build_pt + move.l d0,(a0)+ + add.l #$00001000,d0 + dbra d1,\build_pt + pflusha ; invalidate all ATC entries + cinva bc ; invalid both caches + nop + move.l #$80008000,d0 + movec d0,cacr ; enable caching + move.l #$8000,d0 ; enable MMU with 4K pages + movec d0,tc rts ; Drop into SIM's debug server (in virtual memory) *************** sym_addr ds.l 1 *** 529,534 **** --- 703,709 ---- rom_pstart ds.l 1 ; Physical location of Kickstart ROM rom_pend ds.l 1 + CPUtype ds.w 1 *** sim - SIM program image *************** sim_traphack *** 549,559 **** sim_sign dc.l 'OKAY' sim_resethack lea \ttdata(pc),a0 ! dc.w $f010,$0800 ;<*** pmove.l (a0),tt0 jmp (2) \ttdata dc.l $000f810f cnop 0,4 sim_end --- 724,749 ---- sim_sign dc.l 'OKAY' sim_resethack + move.w CPUtype2(pc),d0 ; test if 68040 + bne.s \reset040 lea \ttdata(pc),a0 ! pmove.l (a0),tt0 jmp (2) + \reset040 + move.l #$000fa040,d0 + movec d0,itt0 + movec d0,dtt0 + jmp 2 \ttdata dc.l $000f810f + + reboot + lea ROMEND+2,a0 + sub.l ROMSIZE,a0 ; point to ROM entry + cnop 0,4 + reset ; reset back to pre-autoconfig state + jmp (a0) ; and enter the ROM + CPUtype2 dc.w 0 cnop 0,4 sim_end *** /tmp/init.c Tue May 18 01:41:03 1993 --- ./kernel/amiga/init.c Sun May 16 22:09:10 1993 *************** *** 47,53 **** #include #endif ! char version[] = "0.008"; char *root_name = "blah"; --- 47,53 ---- #include #endif ! char version[] = "0.009"; char *root_name = "blah"; *************** gimmeabreak(void) *** 167,180 **** asm("illegal"); } - void startrtclock(void) - { - } - - void resettodr(void) - { - } - int timemmap(int dev_number,vm_offset_t ofs,vm_prot_t prot) { return(0); --- 167,172 ---- *************** int timemmap(int dev_number,vm_offset_t *** 184,189 **** --- 176,189 ---- void delay(int per) { /* Hmmm... */ + #ifdef M68040 + /* The preprocessor condition above are really testing for a 68040 MMU + but as there are no test for the 040 CPU I'm aware of, I'm using it. + This delay has been shown to be needed on 040s >= 33 MHz, but not on + 28 MHz machines. */ + int i; + for (i = per * 8; i; --i) ; + #endif } *** /tmp/kd.c Tue May 18 01:41:08 1993 --- ./kernel/amiga/kd.c Sat May 8 07:40:46 1993 *************** *** 41,48 **** #include #include #include - /* Display sizes in characters */ #define NTSC_WIDTH 80 #define NTSC_HEIGHT 27 --- 41,48 ---- #include #include #include + #include /* Display sizes in characters */ #define NTSC_WIDTH 80 #define NTSC_HEIGHT 27 *************** int screen_width, screen_height; *** 60,68 **** int px,py; - struct tty kd_tty; ! /* * kd_state shows the state of the modifier keys (ctrl, caps lock, --- 60,67 ---- int px,py; struct tty kd_tty; ! extern struct cirbuf *cons_buf; /* * kd_state shows the state of the modifier keys (ctrl, caps lock, *************** xorcurs(void) *** 236,241 **** --- 235,242 ---- int kd_putc(int c) { + u_int s = spltty (); + xorcurs(); switch(c) { *************** kd_putc(int c) *** 281,286 **** --- 282,288 ---- break; } xorcurs(); + splx(s); return(0); } *************** kdintr(void) *** 784,798 **** --- 786,806 ---- */ for ( ; (c != K_DONE) && (char_idx <= max); c = key_map[scancode][char_idx++]) { + #if 0 (*linesw[tp->t_line].l_rint)(c, tp); + #else + putc (c, cons_buf); + #endif } } } + #if 0 { int i; for(i = 0;i < 50;i++); /* oohhhh... */ } + #endif ciaa.cra &= ~(1<<6); ciaa.sdr = incode; *************** kdintr(void) *** 800,806 **** splx(o_pri); } ! /* Called from cons.c, to poll for characters from the keyboard. Called at spltty. */ int kd_cnpollc(void) --- 808,814 ---- splx(o_pri); } ! #if 0 /* Called from cons.c, to poll for characters from the keyboard. Called at spltty. */ int kd_cnpollc(void) *************** kd_cnpollc(void) *** 842,844 **** --- 850,853 ---- } return c; } + #endif *** /tmp/uart.c Tue May 18 01:41:13 1993 --- ./kernel/amiga/uart.c Sun May 16 23:42:59 1993 *************** *** 41,46 **** --- 41,47 ---- #include #include #include /* for struct uio (!) */ + #include #include #include *************** *** 51,57 **** extern void ttrstrt(); ! struct tty uart_tty = {}; /* * map speed numbers into the values we have to poke into SERPER --- 52,59 ---- extern void ttrstrt(); ! extern struct cirbuf *cons_buf; ! struct tty uart_tty; /* * map speed numbers into the values we have to poke into SERPER *************** utrint () *** 260,265 **** --- 262,268 ---- if (!(data & SERDATRF_RBF)) return; + #if 0 if ((tp->t_state&(TS_ISOPEN|TS_WOPEN)) == 0) return; *************** utrint () *** 269,274 **** --- 272,280 ---- c = data & 0x7f; ttyinput(c, tp); + #else + putc (data & 0xff, cons_buf); + #endif } void *************** utportdeath(unsigned dev, mach_port_t po *** 314,334 **** void ut_cnputc(int c) { ! if (c) { /* inhibit tx-interrupts while we poll manually, or the uart driver may get `slightly' confused.. */ ! /* custom.intena = INTF_TBE; */ while (! (custom.serdatr & (SERDATRF_TBE|SERDATRF_TSRE))) ; custom.serdat = (c&0xff) | 0x100; while (! (custom.serdatr & SERDATRF_TBE)) ; custom.intreq = INTF_TBE; ! /* custom.intena = INTF_SETCLR | INTF_TBE; */ #if 1 /* well ahem... *slow* vt100.... */ for (c = 0; c < 10000; c++) ; ! /* rather rude kind of flow-control, but I want to see EVERYTHING on my vt100, not just parts of a too fast transmission ;-)) */ if ((c = ut_cnpollc ()) == 19) --- 320,343 ---- void ut_cnputc(int c) { ! int s; ! ! if (c && c != -1) { /* inhibit tx-interrupts while we poll manually, or the uart driver may get `slightly' confused.. */ ! custom.intena = INTF_TBE; while (! (custom.serdatr & (SERDATRF_TBE|SERDATRF_TSRE))) ; custom.serdat = (c&0xff) | 0x100; while (! (custom.serdatr & SERDATRF_TBE)) ; custom.intreq = INTF_TBE; ! custom.intena = INTF_SETCLR | INTF_TBE; + #if 0 #if 1 /* well ahem... *slow* vt100.... */ for (c = 0; c < 10000; c++) ; ! #else /* rather rude kind of flow-control, but I want to see EVERYTHING on my vt100, not just parts of a too fast transmission ;-)) */ if ((c = ut_cnpollc ()) == 19) *************** ut_cnputc(int c) *** 336,345 **** do c = ut_cnpollc (); while (c != 17); } #endif } } ! /* Called from cons.c, to poll for a character. */ int ut_cnpollc(void) --- 345,371 ---- do c = ut_cnpollc (); while (c != 17); } #endif + #else + s = spltty (); + if (cons_buf->c_cf != cons_buf->c_cl && *(cons_buf->c_cf) == 19) + { + getc (cons_buf); + splx (s); + do + { + s = spltty (); + c = getc (cons_buf); + splx (s); + } + while (c != 17); + } + else + splx (s); + #endif } } ! #if 0 /* Called from cons.c, to poll for a character. */ int ut_cnpollc(void) *************** ut_cnpollc(void) *** 366,369 **** #endif return c; } ! --- 392,395 ---- #endif return c; } ! #endif *** /tmp/kd.h Tue May 18 01:41:18 1993 --- ./kernel/amiga/kd.h Sat May 8 08:04:45 1993 *************** typedef struct { *** 505,510 **** --- 505,514 ---- /* Special routines used by the kernel to perform polled I/O */ void kd_cnputc(int c); + #if 0 int kd_cnpollc(void); + #endif + + extern struct tty kd_tty; #endif _amiga_kd_ *** /tmp/uart.h Tue May 18 01:41:23 1993 --- ./kernel/amiga/uart.h Sat May 8 07:51:21 1993 *************** extern struct conssw conssw; *** 52,58 **** /* Special routines used by the kernel to perform polled I/O */ ! void kd_cnputc(int c); ! int kd_cnpollc(void); #endif _amiga_uart_ --- 52,62 ---- /* Special routines used by the kernel to perform polled I/O */ ! void ut_cnputc(int c); ! #if 0 ! int ut_cnpollc(void); ! #endif ! ! extern struct tty uart_tty; #endif _amiga_uart_ *** /tmp/interrupt.c Tue May 18 01:41:27 1993 --- ./kernel/amiga/interrupt.c Sun May 16 00:20:35 1993 *************** *** 35,49 **** #include #include #include #include #include void level_1_int_c (int user) { - extern void utxint(); - if (custom.intreqr & INTF_SOFTINT) { custom.intreq = INTF_SOFTINT; --- 35,50 ---- #include #include #include + #include #include #include + extern void kdintr(void); + extern void utxint(); void level_1_int_c (int user) { if (custom.intreqr & INTF_SOFTINT) { custom.intreq = INTF_SOFTINT; *************** level_1_int_c (int user) *** 55,76 **** asm ("illegal;"); } void level_2_int_c (int user) { ! extern void kdintr(void); ! int ints = ciaa.icr; custom.intreq = INTF_PORTS; #if defined (A3000) || defined (GVP11) || defined (A2091) ! amiga_dma_intr (0, 0, 2); ! sbic_intr (0, 2); #endif ! #if later ! if(ints & (1<<3)) ! kdintr(); #endif } --- 56,105 ---- asm ("illegal;"); } + /* This comment does only apply if the 'if 0's below is changed to be in. + We play a game with splhigh here, because someone is not very nice + to us. Nested interrupts have been noticed when in critical regions + of sbic_intr, and that cannot be tolerated. However, since we don't + know who is doing this to us we have to put new level 2 interrupts + on hold via software. */ void level_2_int_c (int user) { ! #if 0 ! int s = splhigh (); ! #endif int ints = ciaa.icr; + #if 0 + static int pending = 0; + static int busy = 0; + #endif custom.intreq = INTF_PORTS; + #if 0 + if (!busy) + { + busy = 1; + splx (s); + #endif #if defined (A3000) || defined (GVP11) || defined (A2091) ! amiga_dma_intr (0, 0, 2); ! sbic_intr (0, 2); #endif ! if(ints & (1<<3)) ! kdintr(); ! #if 0 ! s = splhigh (); ! busy = 0; ! if (pending) ! { ! pending--; ! custom.intreq = INTF_SETCLR | INTF_PORTS; ! } ! } ! else ! pending++; ! splx (s); #endif } *************** level_3_int_c (int user) *** 88,98 **** clock_interrupt (1000000 / HZ, user, user); #endif } - else #if 1 printf("spurious non-VERTB INT3\n"); - #else - ; #endif } --- 117,125 ---- clock_interrupt (1000000 / HZ, user, user); #endif } #if 1 + else printf("spurious non-VERTB INT3\n"); #endif } *************** level_6_int_c (int user) *** 139,145 **** { /* deal with other level 6 interrupts. External boards may cause int6, here's the place to handle them */ ! custom.intena = 0x2000; /* Disable interrupt */ #if 1 printf ("spurious non-CIAB INT6 %x\n", custom.intreqr); #endif --- 166,172 ---- { /* deal with other level 6 interrupts. External boards may cause int6, here's the place to handle them */ ! custom.intreq = INTF_EXTER; /* Clear interrupt */ #if 1 printf ("spurious non-CIAB INT6 %x\n", custom.intreqr); #endif *** /tmp/cons.c Tue May 18 01:41:32 1993 --- ./kernel/amiga/cons.c Sat May 8 00:39:25 1993 *************** *** 29,34 **** --- 29,35 ---- * * Contributors: * Bryan Ford + * Niklas Hallqvist */ #include *************** *** 35,69 **** #include #include #include ! static boolean_t inited; - /* Called from init.c */ void ! cninit(void) { ! kdinit(); ! utinit(); ! inited = 1; } ! ! /* Send a character from the kernel to both the screen and the serial port */ void ! cnputc(u_char c) { ! if(inited) { ! int s; ! ! if(c == '\n') cnputc('\r'); ! s = splhigh(); ! ut_cnputc(c); ! kd_cnputc(c); ! splx (s); } } --- 36,94 ---- #include #include #include + #include + #define CONS_BUFSIZE 256 ! static struct cirbuf phys_cons_buf; ! struct cirbuf *cons_buf = &phys_cons_buf; ! static enum { UNDEFINED, RAW, TTY } state = UNDEFINED; /* Called from init.c */ void ! cninit (void) { ! kdinit (); ! utinit (); ! state = RAW; ! /* We can't use cb_alloc here because kalloc isn't initialized yet */ ! #if 0 ! cb_alloc (cons_buf, CONS_BUFSIZE); ! #else ! { ! register struct cirbuf *cb = cons_buf; ! register int buf_size = CONS_BUFSIZE; ! static char buf[CONS_BUFSIZE]; ! ! cb->c_start = buf; ! cb->c_end = buf + buf_size; ! cb->c_cf = buf; ! cb->c_cl = buf; ! cb->c_cc = 0; ! cb->c_hog = buf_size - 1; ! } ! #endif } ! /* Send a character from the kernel to both the screen and the serial port ! */ void ! cnputc (u_char c) { ! if(state != UNDEFINED) { ! if (c == '\n') cnputc('\r'); ! if (state == RAW) ! { ! ut_cnputc (c); ! kd_cnputc (c); ! } ! else ! { ! ttyoutput (c, &kd_tty); ! ttyoutput (c, &uart_tty); ! } } } *************** cnputc(u_char c) *** 70,91 **** /* Get a key from either the keyboard or the serial port */ int ! cngetc(void) { ! int s, c, c_o; ! ! if(!inited) ! return(-1); ! do { ! s = splhigh(); ! if ((c = ut_cnpollc()) < 0) ! c = kd_cnpollc(); ! splx (s); } - while (c < 0); ! return(c); } - --- 95,119 ---- /* Get a key from either the keyboard or the serial port */ int ! cngetc (void) { ! int c = -1; ! switch (state) { ! case UNDEFINED: ! break; ! case RAW: ! while (c < 0) ! { ! int s = spltty (); ! c = getc (cons_buf); ! splx (s); ! } ! break; ! default: ! panic ("cngetc: state not implemented\n"); } ! return c; } *** /tmp/patchSIM-009.c Tue May 18 01:41:36 1993 --- ./kernel/amiga/patchSIM-009.c Mon May 17 22:35:50 1993 *************** *** 0 **** --- 1,45 ---- + #include + #include + #include + + int main () + { + int fd = open ("SIM", O_RDWR); + unsigned int val = 0; + + if (fd < 0) + { + perror ("SIM"); + return 1; + } + if (lseek (fd, 31890, SEEK_SET) < 0) + { + perror ("lseek"); + return 1; + } + read (fd, &val, sizeof val); + if (val != 0xfffffffe && val != 0x00800000) + { + fprintf (stderr, + "I'm not sure this is SIM 1.72 from KludgeMach 0.008\n"); + return 1; + } + if (val == 0xfffffffe) + { + fprintf (stderr, "This binary seems patched\n"); + return 1; + } + if (lseek (fd, 31890, SEEK_SET) < 0) + { + perror ("lseek"); + return 1; + } + val = 0xfffffffe; + if (write (fd, &val, sizeof val) != sizeof val) + { + perror ("write"); + return 1; + } + close (fd); + return 0; + } *** /tmp/machparam.h Tue May 18 01:41:40 1993 --- ./kernel/amiga/machparam.h Mon May 10 12:24:13 1993 *************** extern int splhigh(); *** 60,66 **** #endif /* block hardware clock interrupts */ ! #define splclock() spl3() /* block serial line and keyboard interrupts */ #define spltty() spl5() --- 60,66 ---- #endif /* block hardware clock interrupts */ ! #define splclock() spl6() /* block serial line and keyboard interrupts */ #define spltty() spl5() *************** extern int splhigh(); *** 72,78 **** #define splio() spl5() /* block all interrupts that may affect scheduling (eg. switch tasks) */ ! #define splsched() spl5() /* not used, what was the purpose for this level? */ #define splvm() spl7() --- 72,78 ---- #define splio() spl5() /* block all interrupts that may affect scheduling (eg. switch tasks) */ ! #define splsched() spl6() /* not used, what was the purpose for this level? */ #define splvm() spl7() *** /tmp/autoconf.c Tue May 18 01:41:45 1993 --- ./kernel/amiga/autoconf.c Sun May 16 00:14:45 1993 *************** printf("machine_init\n"); *** 158,179 **** machine_slot[0].is_cpu = TRUE; machine_slot[0].running = TRUE; machine_slot[0].clock_freq = hz; machine_slot[0].cpu_type = CPU_TYPE_MC68030; #ifdef A3000 machine_slot[0].cpu_subtype = CPU_SUBTYPE_AMIGA_3000; a3000_init(); ! #endif ! #ifdef A2091 ! machine_slot[0].cpu_subtype = CPU_SUBTYPE_AMIGA_2000; /* We don't really know, do we */ a2091_init(); #endif #ifdef GVP11 - machine_slot[0].cpu_subtype = CPU_SUBTYPE_AMIGA_2000; - gvp11_init (); #endif custom.intena = 0x7fff; --- 158,180 ---- machine_slot[0].is_cpu = TRUE; machine_slot[0].running = TRUE; machine_slot[0].clock_freq = hz; + /* We don't really know, do we */ machine_slot[0].cpu_type = CPU_TYPE_MC68030; #ifdef A3000 machine_slot[0].cpu_subtype = CPU_SUBTYPE_AMIGA_3000; a3000_init(); ! #else ! /* We don't really know, do we */ ! machine_slot[0].cpu_subtype = CPU_SUBTYPE_AMIGA_2000; + #ifdef A2091 a2091_init(); #endif #ifdef GVP11 gvp11_init (); #endif + #endif custom.intena = 0x7fff; *************** printf("machine_init\n"); *** 191,201 **** PORTS: CIA A interrupt (keyboard and parallel port) EXTER: CIA B interrupt (hardclock) */ custom.intena = (INTF_SETCLR | INTF_INTEN | INTF_SOFTINT /*| INTF_VERTB*/ ! /*| INTF_RBF*/ | INTF_TBE | INTF_PORTS | INTF_EXTER); printf ("about to enable interrupts\n"); spl0(); /* Probe the sbic based scsi busses (with ints enabled!) */ #ifdef A3000 --- 192,204 ---- PORTS: CIA A interrupt (keyboard and parallel port) EXTER: CIA B interrupt (hardclock) */ custom.intena = (INTF_SETCLR | INTF_INTEN | INTF_SOFTINT /*| INTF_VERTB*/ ! | INTF_RBF | INTF_TBE | INTF_PORTS | INTF_EXTER); printf ("about to enable interrupts\n"); spl0(); + + printf ("spl0, configure_bus_master\n"); /* Probe the sbic based scsi busses (with ints enabled!) */ #ifdef A3000 *** /tmp/cia_clock.c Tue May 18 01:41:49 1993 --- ./kernel/amiga/cia_clock.c Sun May 16 21:51:01 1993 *************** *** 0 **** --- 1,79 ---- + /* + * Mach Operating System + * Copyright (c) 1992 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + /* + * Amiga interrupt handler entrypoints, called from m68k/locore.s + * + * Contributors: + * Markus Wild + */ + + #include + #include + #include + #include + + /* We're using Timer A, CIA-B as hardclock, since the int-level 6 fits + nicely into Vax-interrupt-architecture ;-) */ + + void + startrtclock(void) + { + unsigned short interval; + + /* FIXME for now assume NTSC timing... (although I'm European;-)) */ + + /* stop timer A */ + ciab.cra = ciab.cra & 0xc0; + + /* load interval into registers. + the clocks run at NTSC: 715.909kHz or PAL: 709.379kHz */ + + interval = 715909 / HZ; + + /* order of setting is important ! */ + ciab.talo = interval & 0xff; + ciab.tahi = interval >> 8; + + /* enable interrupts for timer A */ + ciab.icr = (1<<7) | (1<<0); + + /* start timer A in continuous shot mode */ + ciab.cra = (ciab.cra & 0xc0) | 1; + + printf ("ciab-clock running\n"); + } + + + void + resettodr(void) + { + } + + /* + void inittodr(void) + { + } + */ *** /tmp/psl.h Tue May 18 01:41:53 1993 --- ./kernel/amiga/psl.h Sun May 16 00:23:51 1993 *************** *** 0 **** --- 1,6 ---- + #ifndef _amiga_psl_h + #define _amiga_psl_h + + #include + + #endif /* _amiga_psl_h */ *** /tmp/rdb.h Tue May 18 01:41:57 1993 --- ./kernel/amiga/rdb.h Sun May 16 23:20:53 1993 *************** *** 0 **** --- 1,58 ---- + #ifndef _amiga_rdb_h + #define _amiga_rdb_h + + struct amiga_rdb { + unsigned long rdb_ID; /* 4 character identifier */ + unsigned long rdb_SummedLongs; /* size of this checksummed structure */ + long rdb_ChkSum; /* block checksum (longword sum to zero) */ + unsigned long rdb_HostID; + unsigned long rdb_BlockBytes; + unsigned long rdb_Flags; + unsigned long rdb_BadBlockList; + unsigned long rdb_PartitionList; /* optional first partition block */ + unsigned long rdb_FileSysHeaderList; + unsigned long rdb_DriveInit; + unsigned long rdb_Reserved1[6]; + unsigned long rdb_Cylinders; /* number of drive cylinders */ + unsigned long rdb_Sectors; /* sectors per track */ + unsigned long rdb_Heads; /* number of drive heads */ + }; + + #define IDNAME_RIGIDDISK 0x5244534b /* 'RDSK' */ + #define RDB_LOCATION_LIMIT 16 + + struct amiga_part { + unsigned long pb_ID; /* 4 character identifier */ + unsigned long pb_SummedLongs; /* size of this checksummed structure */ + long pb_ChkSum; /* block checksum (longword sum to zero) */ + unsigned long pb_HostID; + unsigned long pb_Next; + unsigned long pb_Flags; + unsigned long pb_Reserved1[2]; + unsigned long pb_DevFlags; + unsigned char pb_DriveName[32]; + unsigned long pb_Reserved2[15]; + unsigned long pb_Environment[17]; + unsigned long pb_EReserved[15]; + }; + + #define IDNAME_PARTITION 0x50415254 /* 'PART' */ + #define DE_TABLESIZE 0 /* size of environment table */ + #define DE_SIZEBLOCK 1 /* longwords per block */ + #define DE_SECORG 2 /* not used */ + #define DE_NUMHEADS 3 /* number of heads */ + #define DE_SECSPERBLK 4 /* not used */ + #define DE_BLKSPERTRACK 5 /* blocks per track */ + #define DE_RESERVEDBLKS 6 /* number of reserved blocks */ + #define DE_PREFAC 7 /* not used */ + #define DE_INTERLEAVE 8 /* usually 0 */ + #define DE_LOWCYL 9 /* starting cylinder */ + #define DE_UPPERCYL 10 /* last cylinder */ + #define DE_NUMBUFFERS 11 /* number of buffers */ + #define DE_MEMBUFTYPE 12 /* type of memory to allocate for buffers */ + #define DE_MAXTRANSFER 13 /* maximum transfer size */ + #define DE_MASK 14 /* address mask */ + #define DE_BOOTPRI 15 /* boot priority for automount */ + #define DE_DOSTYPE 16 /* filesystem type */ + + #endif _amiga_rdb_h *** /tmp/spl_debug.c Tue May 18 01:42:02 1993 --- ./kernel/amiga/spl_debug.c Sun May 16 00:32:53 1993 *************** *** 0 **** --- 1,86 ---- + /* this file is only needed, if the spl functions are not inline expanded. + It's a bit easier to fiddle with spl-settings changing one file than + recompiling the whole kernel.. */ + + #ifdef SPL_DEBUG + + #include + + #define PRINTF(a) if (0) printf(a) + + /* Set the interrupt priority level and save the old level */ + int spln(unsigned short spl) + { + register unsigned short sr; + register int scratch; + + asm volatile ("movew sr,%0;" + "movew %0,%1;" + "andiw #0xf8ff,%1;" + "orw %2,%1;" + "movew %1,sr;" + : "=d" (sr), "=d" (scratch) : "d" (spl) : "cc"); + return(sr & 0x700); + } + + + /* Set the interrupt priority level back to the previous level */ + void splx(unsigned short pri) + { + #if 0 + printf ("[splx%d]", pri); + #endif + spln(pri); + } + + + /* efficiency is secondary for this file.... */ + + #define LEVEL(num) int spl##num(void) { return spln(PSL_IPL##num); } + + LEVEL(0) + LEVEL(1) + LEVEL(2) + LEVEL(3) + LEVEL(4) + LEVEL(5) + LEVEL(6) + LEVEL(7) + + /* block software timeouts */ + int splsoftclock() + { PRINTF ("[splsoftclock]"); return spl1(); } + + /* block SCSI interrupts (logically spl2, but must match at least spltty) */ + int splbio() + { PRINTF ("[splbio]"); return spltty(); } + + /* block hardware clock interrupts (CIAB generates INT6) */ + int splclock() + { PRINTF ("[splclock]"); return spl6(); } + + /* block serial line and keyboard interrupts */ + int spltty() + { PRINTF ("[spltty]"); return spl5(); } + + /* block network interrupts (at least SLIP, ie. spltty, if nothing else) */ + int splimp() + { PRINTF ("[splimp]"); return spltty(); } + + /* block ALL io devices (still hardcoded in ds_routines.c to splsched!!!) */ + int splio() + { PRINTF ("[splio]"); return spl5(); } + + /* block all interrupts that may affect scheduling (eg. switch tasks) */ + int splsched() + { PRINTF ("[splsched]"); return spl7(); } + + /* not used, what was the purpose for this level? */ + int splvm() + { PRINTF ("[splvm]"); return spl7(); } + + /* block all interrupts */ + int splhigh() + { PRINTF ("[splhigh]"); return spl7(); } + + #endif /* SPL_DEBUG */ *** /tmp/a3000_dma.c Tue May 18 01:42:07 1993 --- ./kernel/amiga/a3000_dma.c Sun May 16 00:51:05 1993 *************** *** 1,562 **** - /* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS AS-IS - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - - /* based on the mips/PMAX/kmin_dma.c code */ - - #include - #include - #include - #include /* spl definitions */ - #include - #include - - #include - #include - - #define NA3000 1 /* XXX */ - - /* - * Definition of the driver for the auto-configuration program. - */ - - int a3000_probe(), a3000_attach(), a3000_intr(); - - - /* a bit ridiculous I know... */ - caddr_t a3000_std[NA3000] = { 0 }; - struct bus_device *a3000_info[NA3000]; - struct bus_driver a3000_driver = - { a3000_probe, 0, a3000_attach, 0, a3000_std, "a3000", a3000_info,}; - - /* - * Adapt/Probe/Attach functions - */ - a3000_probe (xxx, ui) - struct bus_device *ui; - { - /* we are only called if ??? hand-filled us in */ - return 1; - } - - a3000_attach(ui) - register struct bus_device *ui; - { - /* we got nothing to say */ - } - - a3000_intr (unit, spllevel, intr) - { - if (a3000_dmac.int_status & A3000_DMAC_INT_PENDING) - a3000_dma_intr (unit, spllevel, intr); - } - - - /* - * Functions to support DMA for the on-board SCSI - */ - - #include - #include - #include - #include - #include - - /* utilities */ - - #define u_min(a,b) (((a) < (b)) ? (a) : (b)) - - int dma_in_progress = 0; - - static inline void - a3000_stop_dma () - { - if (dma_in_progress) - { - a3000_dmac.flush_DMA = 1; - while (! (a3000_dmac.int_status & A3000_DMAC_DMA_IDLE)) ; - a3000_dmac.clear_ints = 1; - a3000_dmac.stop_DMA = 1; - - dma_in_progress = 0; - } - } - - static inline void * - kvtophys (vm_offset_t kv) - { - extern pmap_t kernel_pmap; - - return pmap_extract (kernel_pmap, kv); - } - - a3000_dma_read (dma_ptr, count) - vm_offset_t dma_ptr; - { - register vm_offset_t phys; - - /* stop DMA engine first */ - a3000_stop_dma (); - - phys = kvtophys (dma_ptr); - - a3000_dmac.control = A3000_DMAC_DIR_READ; - a3000_dmac.DMA_address = phys; - a3000_dmac.start_DMA = 1; - - dma_in_progress = 1; - } - - a3000_dma_write (dma_ptr, count) - vm_offset_t dma_ptr; - { - register vm_offset_t phys; - - /* stop DMA engine first */ - a3000_stop_dma (); - - phys = kvtophys(dma_ptr); - - a3000_dmac.control = A3000_DMAC_DIR_WRITE; - a3000_dmac.DMA_address = phys; - a3000_dmac.start_DMA = 1; - - dma_in_progress = 1; - } - - a3000_dma_intr (unit, spllevel, intr) - { - a3000_stop_dma (); - } - - - /* - * Cold, probe time init - */ - opaque_t - a3000_dma_init (unit, base, dma_bsizep) - int unit; - vm_offset_t base; - int *dma_bsizep; - { - a3000_dmac.DACK_width = A3000_DMAC_WIDTH; - return (opaque_t) 0; - } - - /* - * A target exists - */ - void - a3000_dma_new_target (dma, tgt) - opaque_t dma; - target_info_t *tgt; - { - /* provide enough space here, the cmd_buf is used for both, commands and - (small) results of maintanance commands (ie. inquiry) - MAKE SURE THE BUFFERS ARE LONG ALIGNED!! */ - static u_int cmds[NSCSI][8][256/4]; - - tgt->cmd_ptr = (u_char *) cmds[tgt->masterno][tgt->target_id]; - } - - /* - * Map virtual addresses onto physical ones - */ - void - a3000_dma_map (dma, tgt) - opaque_t dma; - target_info_t *tgt; - { - /* - * We do real DMA. - */ - - if ((tgt->cur_cmd == SCSI_CMD_WRITE) || - (tgt->cur_cmd == SCSI_CMD_LONG_WRITE)) - { - io_req_t ior = tgt->ior; - register int len = ior->io_count; - - tgt->transient_state.out_count = len; - - /* avoid leaks ?? */ - if (len < tgt->block_size) - { - /* bzero(to + len, tgt->block_size - len);*/ - len = tgt->block_size; - tgt->transient_state.out_count = len; - } - - tgt->transient_state.dma_offset = 0; - } - else - { - tgt->transient_state.out_count = 0; - tgt->transient_state.dma_offset = 0; - } - } - - int - a3000_dma_start_cmd (dma, tgt) - opaque_t dma; - register target_info_t *tgt; - { - /* contrary to the 3min, this command already starts DMA for the data - transfer, since there's no CDB to be transmitted */ - - if (tgt->transient_state.in_count) - return a3000_dma_start_datain (dma, tgt); - else if (tgt->transient_state.out_count) - return a3000_dma_start_dataout (dma, tgt); - else - return 0; - } - - void - a3000_dma_end_cmd(dma, tgt, ior) - opaque_t dma; - target_info_t *tgt; - io_req_t ior; - { - tgt->dma_ptr = 0; - tgt->transient_state.dma_offset = 0; - } - - void - a3000_dma_end_xfer (dma, tgt, bytes_read) - opaque_t dma; - target_info_t *tgt; - int bytes_read; - { - register volatile char *ptr; - register int nb; - - a3000_stop_dma (); - - /* On read, flush cache (necessary with our DMAC??) XXXX */ - if (bytes_read != 0) - { - /* would be nice to do this in parallel with xfer, earlier on */ - ptr = tgt->dma_ptr + tgt->transient_state.dma_offset; - flush_the_damn_cache (ptr, bytes_read); - } - } - - int - a3000_dma_start_datain (dma, tgt) - opaque_t dma; - register target_info_t *tgt; - { - register char *dma_ptr; - register int count; - - /* setup tgt->dma_ptr to ior->io_data, flush cache */ - if (tgt->cur_cmd == SCSI_CMD_READ || tgt->cur_cmd == SCSI_CMD_LONG_READ) - dma_ptr = tgt->ior->io_data; - else - /* swear it won't disconnect midway a xfer or else */ - dma_ptr = tgt->cmd_ptr; - - if (!(tgt->dma_ptr = dma_ptr)) - panic ("a3000_dma_start_datain, no dma_ptr"); - - count = tgt->transient_state.in_count; - if (count <= 0) - panic ("a3000_dma_start_datain"); - - a3000_dma_read(dma_ptr, count); - - #if 0 - count = u_min(count, SBIC_TC_MAX); - #else - /* too bad the A3000 DMA can't chain DMA requests ;-( */ - count = u_min (count, PMAP_PGBYTES); - #endif - - return count; - } - - int - a3000_dma_restart_datain_1 (dma, tgt) - opaque_t dma; - target_info_t *tgt; - { - register char *dma_ptr; - register int count; - - /* This is the unlikely case we disconnected before - actually starting the data xfer */ - if (tgt->dma_ptr == 0) - return a3000_dma_start_datain (dma, tgt); - - /* keep dma_offset anyways */ - dma_ptr = tgt->dma_ptr + tgt->transient_state.dma_offset; - - count = tgt->transient_state.in_count; - - a3000_dma_read (dma_ptr, count); - - #if 0 - count = u_min(count, SBIC_TC_MAX); - #else - /* too bad the A3000 DMA can't chain DMA requests ;-( */ - count = u_min (count, PMAP_PGBYTES); - #endif - return count; - } - - int - a3000_dma_restart_datain_2 (dma, tgt, xferred) - opaque_t dma; - target_info_t *tgt; - int xferred; - { - /*XXX*/ tgt->transient_state.copy_count = tgt->transient_state.dma_offset; - tgt->transient_state.dma_offset += xferred; - - return a3000_dma_restart_datain_1 (dma, tgt); - } - - void - a3000_dma_restart_datain_3 (dma, tgt) - opaque_t dma; - target_info_t *tgt; - { - register volatile char *ptr; - int len; - - /* avoid doing it again!! XXXX */ - ptr = tgt->dma_ptr + tgt->transient_state.copy_count; - len = tgt->transient_state.dma_offset + tgt->transient_state.copy_count; - flush_the_damn_cache (ptr, len); - } - - - boolean_t - a3000_dma_start_dataout (dma, tgt, regp, cmd) - opaque_t dma; - register target_info_t *tgt; - volatile char *regp, cmd; - { - register char *dma_ptr; - - /* since we don't transmit the CDB explicitly, make sure no code depends - on such dma stuff */ - if (tgt->transient_state.dma_offset) - panic ("a3000_dma_start_dataout"); - - dma_ptr = tgt->ior->io_data; - if (! dma_ptr) - panic ("a3000_dma_start_dataout no data_ptr!"); - - a3000_dma_write (dma_ptr, tgt->transient_state.out_count); - - tgt->transient_state.dma_offset = 0; - tgt->dma_ptr = dma_ptr; - - return TRUE; - } - - int - a3000_dma_restart_dataout_1 (dma, tgt) - opaque_t dma; - target_info_t *tgt; - { - int count; - - /* this is if we disconnected before starting any xfer */ - if (tgt->dma_ptr == 0) - a3000_dma_start_dataout (dma, tgt, &count, 0); - - count = tgt->transient_state.out_count; - #if 0 - count = u_min(count, SBIC_TC_MAX); - #else - /* too bad the A3000 DMA can't chain DMA requests ;-( */ - count = u_min (count, PMAP_PGBYTES); - #endif - - return count; - } - - int - a3000_dma_restart_dataout_2 (dma, tgt, xferred) - opaque_t dma; - register target_info_t *tgt; - int xferred; - { - tgt->transient_state.dma_offset += xferred; - - return a3000_dma_restart_dataout_1 (dma, tgt); - } - - int - a3000_dma_restart_dataout_3 (dma, tgt, regp) - opaque_t dma; - target_info_t *tgt; - volatile char *regp; - { - register char *dma_ptr; - int ret; - - /* keep dma_offset anyways */ - dma_ptr = tgt->dma_ptr + tgt->transient_state.dma_offset; - - /* unaligned issues here, align to 8 bytes ? (maybe not..) XXXX */ - - a3000_dma_write (dma_ptr, tgt->transient_state.out_count); - - return 0; /* or 1 if adjusted */ - } - - void - a3000_dma_restart_dataout_4 (dma, tgt) - opaque_t dma; - target_info_t *tgt; - { - /* Nothing needed here */ - } - - int - a3000_dma_start_msgin (dma, tgt) - opaque_t dma; - target_info_t *tgt; - { - /* SBIC ONLY SUPPORTS DATA DMA, NO MSGS */ - return 0; - } - - void - a3000_dma_end_msgin (dma, tgt) - opaque_t dma; - target_info_t *tgt; - { - /* SBIC ONLY SUPPORTS DATA DMA, NO MSGS */ - } - - - boolean_t - a3000_dma_disconn_1 (dma, tgt, xferred) - opaque_t dma; - target_info_t *tgt; - int xferred; - { - /* - * XXX Known bug: if we disconnect on an odd bb ?? - */ - a3000_stop_dma (); - - tgt->transient_state.dma_offset += xferred; - return FALSE; - } - - boolean_t - a3000_dma_disconn_2 (dma, tgt) - opaque_t dma; - target_info_t *tgt; - { - /* Nothing needed */ - return FALSE; - } - - - boolean_t - a3000_dma_disconn_3 (dma, tgt, xferred) - opaque_t dma; - target_info_t *tgt; - int xferred; - { - register volatile char *ptr; - - a3000_stop_dma (); - - ptr = tgt->dma_ptr + tgt->transient_state.dma_offset; - flush_the_damn_cache (ptr, xferred); - - tgt->transient_state.dma_offset += xferred; - return FALSE; - } - - #define a3000_dma_disconn_4 a3000_dma_disconn_3 - #define a3000_dma_disconn_5 a3000_dma_disconn_1 - #define a3000_dma_disconn_callback 0 /* never called */ - - flush_the_damn_cache (p, nb) - vm_offset_t p; - { - vm_size_t off; - - off = p & (PMAP_PGBYTES-1); - off = PMAP_PGBYTES - off; - while (nb) - { - off = (nb < off) ? nb : off; - #if 0 - mipscache_Dflush( PHYS_TO_K0SEG(kvtophys(p)), off); - #else - /* XXXXX HOW DO YOU DO THIS WITH M68K PMAP CODE??? - moveq #??,d0 - movec d0,cacr - ??????? */ - #endif - p += off; - nb -= off; - off = PMAP_PGBYTES; - } - } - - scsi_dma_ops_t a3000_dma_ops = { - a3000_dma_init, - a3000_dma_new_target, - a3000_dma_map, - a3000_dma_start_cmd, - a3000_dma_end_xfer, - a3000_dma_end_cmd, - a3000_dma_start_datain, - a3000_dma_start_msgin, - a3000_dma_end_msgin, - a3000_dma_start_dataout, - a3000_dma_restart_datain_1, - a3000_dma_restart_datain_2, - a3000_dma_restart_datain_3, - a3000_dma_restart_dataout_1, - a3000_dma_restart_dataout_2, - a3000_dma_restart_dataout_3, - a3000_dma_restart_dataout_4, - a3000_dma_disconn_1, - a3000_dma_disconn_2, - a3000_dma_disconn_3, - a3000_dma_disconn_4, - a3000_dma_disconn_5, - a3000_dma_disconn_callback, - }; - - /* moved here so I don't have to declare a3000_dma_ops in the header... */ - a3000_init () - { - a3000_dmac.DACK_width = A3000_DMAC_WIDTH; - sbic_set_dmaops (0, &a3000_dma_ops); - } - --- 0 ---- *** /tmp/mach_param.h Tue May 18 01:42:12 1993 --- ./kernel/amiga/mach_param.h Sun May 16 21:52:57 1993 *************** *** 27,33 **** --- 27,35 ---- #ifndef _amiga_mach_param_ #define _amiga_mach_param_ + #ifndef HZ #define HZ 50 + #endif #define A3000_SCSI_ADDR 0xdd0040 *** /tmp/conf.c Tue May 18 01:42:17 1993 --- ./kernel/amiga/conf.c Fri May 7 21:24:37 1993 *************** extern int utopen(), utclose(), utread() *** 43,50 **** extern int utgetstat(), utsetstat(), utportdeath(); #define utname "ut" ! /* A3000 SCSI driver */ ! #if defined(A3000)||defined(A2091) #define rz_name "sd" extern int rz_get_status(), rz_set_status(), rz_devinfo(); extern int rz_open(), rz_close(), rz_read(), rz_write(); --- 43,50 ---- extern int utgetstat(), utsetstat(), utportdeath(); #define utname "ut" ! /* SCSI driver */ ! #if defined (A3000) || defined (A2091) || defined (GVP11) #define rz_name "sd" extern int rz_get_status(), rz_set_status(), rz_devinfo(); extern int rz_open(), rz_close(), rz_read(), rz_write(); *************** struct dev_ops dev_name_list[] = *** 81,87 **** nodev, nulldev, utportdeath, 0, nodev }, ! #ifdef A3000 { rz_name, rz_open, rz_close, rz_read, rz_write, rz_get_status, rz_set_status, nodev, nodev, nulldev, nulldev, 8, --- 81,87 ---- nodev, nulldev, utportdeath, 0, nodev }, ! #if defined (A3000) || defined (A2091) || defined (GVP11) { rz_name, rz_open, rz_close, rz_read, rz_write, rz_get_status, rz_set_status, nodev, nodev, nulldev, nulldev, 8, *** /tmp/ds_routines.c Tue May 18 01:42:23 1993 --- ./kernel/device/ds_routines.c Tue May 18 00:59:45 1993 *************** ds_notify(msg) *** 1444,1452 **** queue_head_t io_done_list; decl_simple_lock_data(, io_done_list_lock) - #if 0 #define splio splsched /* XXX must block ALL io devices */ - #endif void iodone(ior) register io_req_t ior; --- 1444,1450 ---- *************** io_req_t ior; *** 1572,1580 **** { int s; - #if 1 - printf("This is to prevent invoking the scheduler.\n"); - #endif s = splio(); ior_lock(ior); while ((ior->io_op&IO_DONE)==0) { --- 1570,1575 ---- *** /tmp/bootstrap.c Tue May 18 01:42:30 1993 --- ./kernel/kern/bootstrap.c Tue May 18 01:00:23 1993 *************** *** 189,194 **** --- 189,200 ---- #include + #include + #include + #include + #include + #include + #include /* * Bootstrap image is moved out of BSS at startup. *************** void bootstrap_create() *** 318,334 **** while(1) { char blah[31]; ! printf("enter 'boot' to reboot: "); safe_gets(blah,30); printf("You typed: %s\n",blah); ! if(!strcmp(blah,"boot")) asm("jmp 2"); if(!strcmp(blah,"break")) gimmeabreak(); - if (!strncmp(blah,"read",4) && (blah[4] == 0 || blah[4] == ' ')) - read_test(blah+4); if(!strcmp(blah,"exit")) break; } #if defined(iPSC386)|| defined(iPSC860) --- 324,375 ---- while(1) { char blah[31]; ! printf ("\nTime since boot: %d.%02d secs, ", ! time.seconds, time.microseconds / 10000); ! printf ("Enter '?' to get help: "); safe_gets(blah,30); printf("You typed: %s\n",blah); ! if (!strcmp (blah, "?") || !strcmp (blah, "help")) ! { ! printf ("?\t\t\t\t\tprint this text\n"); ! printf ("boot\t\t\t\t\tcold reboot\n"); ! printf ("break\t\t\t\t\tenter into SIM\n"); ! printf ("format [n]\t\t\t\tformat SCSI target\n"); ! printf ("help\t\t\t\t\tprint this text\n"); ! printf ("log\t\t\t\t\tprint SCSI log\n"); ! printf ("read [v] [t] [udev] [ppart] [nrecs] [ssize]" ! "\tread from a SCSI device\n"); ! printf ("\tv = verbose " ! "(dump 8 bytes of each block)\n"); ! printf ("\tt = calculate transfer rate\n"); ! printf ("\tu = SCSI unit number\n"); ! printf ("\tp = partition number\n"); ! printf ("\tn = number of reads\n"); ! printf ("\ts = size of data to read (K = *1024)\n"); ! printf ("stat\t\t\t\t\tprint SCSI statistics\n"); ! printf ("state\t\t\t\t\tprint SCSI state\n"); ! printf ("exit\t\t\t\t\tcontinue with MACH\n"); ! } ! else if(!strcmp(blah,"boot")) asm("jmp 2"); if(!strcmp(blah,"break")) gimmeabreak(); if(!strcmp(blah,"exit")) break; + else if(!strncmp (blah, "format ", 7)) + format_test (*(blah + 7)); + else if (!strcmp (blah, "log")) + { + sbic_print_log (0); + printf ("\n"); + } + else if (!strncmp (blah, "read",4) + && (blah[4] == 0 || blah[4] == ' ')) + read_test(blah+4); + else if (!strcmp (blah, "stat")) + sbic_print_stat (); + else if (!strcmp (blah, "state")) + sbic_state (0, 0); } #if defined(iPSC386)|| defined(iPSC860) *************** void bootstrap_create() *** 369,374 **** --- 410,440 ---- (void) thread_resume(bootstrap_thread); } + void + format_test (dev) + char dev; + { + io_req_t ior; + target_info_t *tgt; + scsi_softc_t *sc; + + if (dev < '0' || dev > '7') + return; + io_req_alloc (ior, 0); + ior->io_count = 4096; + ior->io_op = IO_READ; + if (rz_check (dev - '0', &sc, &tgt)) + { + tgt->ior = ior; + if (scsi_read_defect (tgt, 0x10, ior)) + printf ("defects at 0x%x\n", ior->io_data); + else + printf ("scsi_read_defects failed somehow\n"); + } + else + printf ("device %c not found\n", dev); + } + /* * Read some records from the specified SCSI unit * Default read from unit 0 *************** void bootstrap_create() *** 375,450 **** * Optional 'v' do display some data each record */ - #include - #include - read_test(arg) char *arg; { ! int i; int dev = 0; int verbose = 0; ! int status; io_req_t ior; unsigned char *buf; struct device dummy_device; ! int s = spl0(); int read_test_done (); ! if (*arg++ == ' ') { ! if (*arg == 'v') { ! verbose = 1; /* Want verbose mode */ ! ++arg; ! } ! if (*arg>='0' && *arg<='7') ! dev = (*arg - '0') << 3; /* get device number */ ! } dummy_device.flag = 0; io_req_alloc(ior, 0); ior->io_unit = dev; ior->io_device = &dummy_device; - printf("Doing rz_open..."); i = rz_open (dev, 0, ior); if (i != 0) { printf ("rz_open status: %d\n", i); io_req_free(ior); - splx(s); return; } ! printf ("Beginning read test on %d\n", dev); ! for (i = 0; i < (verbose ? 10 : 200); ++i) { ior->io_unit = dev; ! ior->io_recnum = i; ! ior->io_count = 512; ior->io_error = 0; ior->io_next = 0; ior->io_op = IO_READ; ior->io_done = read_test_done; status = rz_read (dev, ior); if (status == -1) iowait (ior); buf = ior->io_data; ! if (verbose && ior->io_error) { ! printf ("io_error = %d, io_residual=%d buf=%08X", ior->io_error, ! ior->io_residual, ior->io_data); ! printf (" %02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], ! buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); } if (ior->io_alloc_size) { vm_deallocate(kernel_map, buf, ior->io_alloc_size); ior->io_alloc_size = 0; } } printf ("End of read test on %d\n", dev); rz_close (dev); io_req_free(ior); - splx(s); } read_test_done (ior) io_req_t ior; { ! printf ("read_test_done: buf=%08x\n", ior->io_data); ! return (TRUE); } /* --- 441,589 ---- * Optional 'v' do display some data each record */ read_test(arg) char *arg; { ! int i, s; int dev = 0; int verbose = 0; ! int nrecords = 2000; ! int rsize = 512; ! int recnum = 0; ! int do_time = 0; ! int status; io_req_t ior; unsigned char *buf; struct device dummy_device; ! unsigned long start, end, ticks; int read_test_done (); ! while (*arg) ! switch (*arg++) ! { ! case ' ': case '\t': ! break; ! ! case 'u': ! if (*arg >= '0' && *arg <= '7') ! dev |= (*arg++ - '0') << 3; ! break; ! ! case 'p': ! if (*arg >= '0' && *arg <= '7') ! dev |= *arg++ - '0'; ! break; ! ! case 's': ! rsize = 0; ! while (*arg >= '0' && *arg <= '9') ! rsize = rsize * 10 + (*arg++ - '0'); ! if (*arg == 'k' || *arg == 'K') ! { ! arg++; ! rsize *= 1024; ! } ! else if (*arg == 'b' || *arg == 'B') ! { ! arg++; ! rsize *= 512; ! } ! if (! rsize) ! rsize = 512; ! break; ! ! case 'n': ! nrecords = 0; ! while (*arg >= '0' && *arg <= '9') ! nrecords = nrecords * 10 + (*arg++ - '0'); ! break; ! ! case 'v': ! verbose = 1; ! break; ! ! case 't': ! do_time = 1; ! break; ! ! } ! dummy_device.flag = 0; io_req_alloc(ior, 0); ior->io_unit = dev; ior->io_device = &dummy_device; i = rz_open (dev, 0, ior); if (i != 0) { printf ("rz_open status: %d\n", i); io_req_free(ior); return; } ! printf ("Beginning read test on %d/%d/%d, rsize = %d, " ! "nrecords = %d\n", ! dev>>6, (dev>>3)&7, dev&7, rsize, nrecords); ! ticks = 0; ! for (i = 0; i < nrecords; ++i) { ior->io_unit = dev; ! ior->io_recnum = recnum; ! ior->io_count = rsize; ior->io_error = 0; ior->io_next = 0; ior->io_op = IO_READ; ior->io_done = read_test_done; + s = splclock(); start = elapsed_ticks; splx (s); status = rz_read (dev, ior); + s = splclock(); end = elapsed_ticks; splx (s); if (status == -1) iowait (ior); buf = ior->io_data; ! if (verbose || ior->io_error) { ! printf ("io_error = %d, io_residual=%d buf=%08X", ! ior->io_error, ior->io_residual, ! ior->io_data); ! printf (" %02x %02x %02x %02x " ! "%02x %02x %02x %02x\n", ! buf[0], buf[1], buf[2], buf[3], ! buf[4], buf[5], buf[6], buf[7]); } if (ior->io_alloc_size) { vm_deallocate(kernel_map, buf, ior->io_alloc_size); ior->io_alloc_size = 0; + recnum += rsize / 512; } + if (do_time) + ticks += end - start; } + + if (do_time) + { + char *unit = ""; + int cps; + + printf ("ticks elapsed = %d\n", ticks); + printf ("time elapsed = %ds\n", ticks / hz); + + cps = rsize * nrecords * hz / ticks; + + if (cps >= 1024) + { + cps /= 1024; unit = "k"; + } + if (cps >= 1024) + { + cps /= 1024; unit = "M"; + } + + printf ("cps = %d%s\n", cps, unit); + } printf ("End of read test on %d\n", dev); rz_close (dev); io_req_free(ior); } read_test_done (ior) io_req_t ior; { ! printf ("read_test_done: buf=%08x\n", ior->io_data); ! return (TRUE); } /* *** /tmp/Makefile Tue May 18 01:42:36 1993 --- ./kernel/Makefile Sun May 16 23:36:15 1993 *************** *** 1,12 **** - CFLAGS = -I. -I../include -Iamiga -DKERNEL -DMACH_KERNEL -DA2091 -mc68020 -nostdinc - LDFLAGS = -nostdlib - .c.o: ! gcc -c -O2 $(CFLAGS) -o$*.o $*.c .s.o: ! gcc -c $(CFLAGS) -o$*.o $*.s .asm.o: pro $*.asm --- 1,55 ---- + # Choose gccv -pipe if you have got enough memory + #CC = gccv -pipe + CC = gcc + + # These are for 33C93 hackers only... + #DEBUG = -DCMD_DEBUG -DSCSI_DEBUG + DEBUG = + + # Choose CPU/MMU type + # + #CPU = -m68020 -DM68551 + CPU = -m68030 -DM68030 + #CPU = -m68040 -DM68040 + + # Choose the SCSI driver you have available + #DRIVER = -DA3000 + #DRIVER = -DA2091 + DRIVER = -DGVP11 + + # This should be defined if you for some reason want to have dedicated + # buffers for DMA. An example is when your SCSI controller can't access + # all of your memory. + #DMA = -DBUFFERED_DMA + DMA = + + # If you are paranoid use -DSPL_DEBUG, and you will be able to put + # breakpoints at all spl* functions. If you're cautious use -DMASKED_SPL, + # which is the only really implemented way of doing things. If you are + # a believer just comment this define out completely. That way you + # will have a fast, one stack only, *not* working interrupt priority + # handling scheme. + #SPL = -DSPL_DEBUG + SPL = -DMASKED_SPL + #SPL = + + # Choose the clocktick frequency here... Not really dependent on the + # display type (PAL/NTSC) or any powerline AC frequency. These choices + # are just usual values + #HZ = -DHZ=60 + HZ = -DHZ=50 + + INCLUDES = -nostdinc -I. -I../include -Iamiga + MACHFLAGS= -DKERNEL -DMACH_KERNEL + CFLAGS = $(INCLUDES) $(MACHFLAGS) $(DRIVER) $(DEBUG) $(SPL) $(CPU) \ + $(DMA) $(HZ) + LDFLAGS = -nostdlib .c.o: ! $(CC) -c -O2 $(CFLAGS) -o$*.o $*.c .s.o: ! $(CC) -c $(CFLAGS) -o$*.o $*.s .asm.o: pro $*.asm *************** DEVICE_OS = device/ds_routines.o device/ *** 37,59 **** device/dev_name.o device/dev_pager.o device/device_init.o device/net_io.o device/subrs.o \ device/device_server.o device/device_reply_user.o device/device_pager_server.o ! M68K_OS = motorola/m68k/pmap.o motorola/m68k/trap.o motorola/m68k/pcb.o motorola/m68k/stubs.o \ ! motorola/m68k/bcopy.o motorola/m68k/bzero.o motorola/m68k/_setjmp.o \ AMIGA_OS = amiga/locore.o amiga/init.o amiga/conf.o amiga/interrupt.o \ ! amiga/cons.o amiga/kd.o amiga/kernel_font.o amiga/uart.o amiga/amiga_dma.o \ ! amiga/autoconf.o ! ! SCSI_OS = scsi/rz.o scsi/rz_cpu.o scsi/rz_disk.o scsi/rz_disk_bbr.o scsi/rz_labels.o \ ! scsi/rz_tape.o scsi/scsi.o scsi/scsi_alldevs.o scsi/scsi_comm.o scsi/scsi_cpu.o \ ! scsi/scsi_disk.o scsi/scsi_jukebox.o scsi/scsi_optical.o scsi/scsi_printer.o \ ! scsi/scsi_rom.o scsi/scsi_scanner.o scsi/scsi_tape.o scsi/scsi_worm.o \ ! scsi/adapters/scsi_33c93_hdw.o CHIPS_OS = chips/busses.o - # chips/mc_clock.o ! ALL_OS = $(AMIGA_OS) $(M68K_OS) $(MACH_OS) $(KERN_OS) $(VM_OS) $(IPC_OS) $(DEVICE_OS) $(CHIPS_OS) $(SCSI_OS) all: amiga/boot.asm kernel amiga/takeover.bin a68k amiga/boot.asm --- 80,105 ---- device/dev_name.o device/dev_pager.o device/device_init.o device/net_io.o device/subrs.o \ device/device_server.o device/device_reply_user.o device/device_pager_server.o ! M68K_OS = motorola/m68k/pmap.o motorola/m68k/trap.o motorola/m68k/pcb.o \ ! motorola/m68k/stubs.o motorola/m68k/bcopy.o motorola/m68k/bzero.o \ ! motorola/m68k/_setjmp.o AMIGA_OS = amiga/locore.o amiga/init.o amiga/conf.o amiga/interrupt.o \ ! amiga/cons.o amiga/kd.o amiga/kernel_font.o amiga/uart.o \ ! amiga/amiga_dma.o amiga/autoconf.o amiga/spl_debug.o \ ! amiga/cia_clock.o ! ! SCSI_OS = scsi/rz.o scsi/rz_cpu.o scsi/rz_disk.o scsi/rz_disk_bbr.o \ ! scsi/rz_labels.o scsi/rz_tape.o scsi/scsi.o scsi/scsi_alldevs.o \ ! scsi/scsi_comm.o scsi/scsi_cpu.o scsi/scsi_disk.o \ ! scsi/scsi_jukebox.o scsi/scsi_optical.o scsi/scsi_printer.o \ ! scsi/scsi_rom.o scsi/scsi_scanner.o scsi/scsi_tape.o \ ! scsi/scsi_worm.o scsi/adapters/scsi_33c93_hdw.o CHIPS_OS = chips/busses.o ! ALL_OS = $(AMIGA_OS) $(M68K_OS) $(MACH_OS) $(KERN_OS) $(VM_OS) $(IPC_OS) \ ! $(DEVICE_OS) $(CHIPS_OS) $(SCSI_OS) all: amiga/boot.asm kernel amiga/takeover.bin a68k amiga/boot.asm *** /tmp/scsi_disk.c Tue May 18 01:42:42 1993 --- ./kernel/scsi/scsi_disk.c Tue May 18 01:01:15 1993 *************** int scdisk_mode_select(tgt, lbn, ior, md *** 184,190 **** bzero(tgt->cmd_ptr, sizeof(*cmd) + sizeof(*parm)); cmd = (scsi_cmd_mode_select_t*) (tgt->cmd_ptr); cmd->scsi_cmd_code = SCSI_CMD_MODE_SELECT; ! cmd->scsi_cmd_lun_and_lba1 = SCSI_CMD_MSL_PF; /* XXX only if... */ cmd->scsi_cmd_xfer_len = sizeof(scsi_mode_select_param_t);/* no vuq */ parm = (scsi_mode_select_param_t*) (cmd + 1); --- 184,190 ---- bzero(tgt->cmd_ptr, sizeof(*cmd) + sizeof(*parm)); cmd = (scsi_cmd_mode_select_t*) (tgt->cmd_ptr); cmd->scsi_cmd_code = SCSI_CMD_MODE_SELECT; ! cmd->scsi_cmd_lun_and_lba1 = mlen > 12 ? SCSI_CMD_MSL_PF : 0; cmd->scsi_cmd_xfer_len = sizeof(scsi_mode_select_param_t);/* no vuq */ parm = (scsi_mode_select_param_t*) (cmd + 1); *************** int scdisk_mode_select(tgt, lbn, ior, md *** 194,200 **** if (save) cmd->scsi_cmd_lun_and_lba1 |= SCSI_CMD_MSL_SP; } else { ! /* parm->medium_type = if (floppy)disk.. */ parm->desc_len = 8; /* this really is the LBN */ parm->descs[0].density_code = 0;/* XXX default XXX */ --- 194,200 ---- if (save) cmd->scsi_cmd_lun_and_lba1 |= SCSI_CMD_MSL_SP; } else { ! parm->medium_type = 0; /* XXX if (floppy)disk.. */ parm->desc_len = 8; /* this really is the LBN */ parm->descs[0].density_code = 0;/* XXX default XXX */ *** /tmp/rz_labels.h Tue May 18 01:42:47 1993 --- ./kernel/scsi/rz_labels.h Tue May 18 01:01:59 1993 *************** *** 26,31 **** --- 26,35 ---- /* * HISTORY * $Log$ + * Revision 2.11 93/05/15 18:58:00 mlh + * Support for AmigaDOS RigidDiskBlocks + * [93/05/15 18:58:00 mlh] + * * Revision 2.10 92/02/23 22:44:34 elf * The vendor-label-searching function is now fixed. * [92/02/22 19:03:13 af] *************** typedef struct { *** 224,229 **** --- 228,239 ---- char label[sizeof(scsi_bios_label_t)]; } scsi_bios_boot0_t; + + #ifdef amiga + /* include rigid diskblock information. Other targets shouldn't have to + bother with this longish definitions. */ + #include + #endif #endif _SCSI_RZ_LABELS_H_ *** /tmp/scsi_alldevs.c Tue May 18 01:42:53 1993 --- ./kernel/scsi/scsi_alldevs.c Tue May 18 01:02:19 1993 *************** void scsi_go_and_wait(tgt, insize, outsi *** 130,136 **** printf("\nior=%lx, sc=%lx, sc->go=%lx sc->go...", ior, sc, sc->go); #endif (*sc->go)(tgt, insize, outsize, ior==0); ! if (0&&ior) iowait(ior); else while (tgt->done == SCSI_RET_IN_PROGRESS); --- 130,136 ---- printf("\nior=%lx, sc=%lx, sc->go=%lx sc->go...", ior, sc, sc->go); #endif (*sc->go)(tgt, insize, outsize, ior==0); ! if (ior) iowait(ior); else while (tgt->done == SCSI_RET_IN_PROGRESS); *************** scsi_check_sense_data(tgt, sns) *** 310,318 **** { unsigned char code; ! if (sns->u.xtended.error_class != SCSI_SNS_XTENDED_SENSE_DATA) { printf("Bad sense data, vuqe class x%x code x%x\n", ! sns->u.non_xtnded.error_class, sns->u.non_xtnded.error_code); return FALSE; /* and good luck */ } else { code = sns->u.xtended.sense_key; --- 310,318 ---- { unsigned char code; ! if (sns->error_class != SCSI_SNS_XTENDED_SENSE_DATA) { printf("Bad sense data, vuqe class x%x code x%x\n", ! sns->error_class, sns->error_code); return FALSE; /* and good luck */ } else { code = sns->u.xtended.sense_key; *************** void scsi_copy_and_verify( tgt, params, *** 573,578 **** --- 573,597 ---- #endif + /* quick hack, needs nicer coding! */ + void scsi_change_definition (tgt, para, ior) + register target_info_t *tgt; + int para; + io_req_t ior; + { + unsigned char *cmd; + + cmd = tgt->cmd_ptr; + cmd[0] = 0x40; + cmd[1] = 0; + cmd[2] = 1; /* 1: save to nvram */ + cmd[3] = para & 0x7f; + cmd[4] = cmd[5] = cmd[6] = cmd[7] = 0; + cmd[8] = 0; cmd[9] = 0; + tgt->cur_cmd = 0x40; + scsi_go_and_wait (tgt, 10, 0, ior); + } + #ifdef SCSI2 scsi_change_definition scsi_log_select *************** void scsi_print_sense_data(sns) *** 681,687 **** if (sns->u.xtended.eom) printf(", EndOfMedium"); if (sns->u.xtended.fm) printf(", FileMark"); ! if (sns->u.xtended.addr_valid) { unsigned int info; info = (sns->u.xtended.info0 << 24) | (sns->u.xtended.info1 << 16) | --- 700,706 ---- if (sns->u.xtended.eom) printf(", EndOfMedium"); if (sns->u.xtended.fm) printf(", FileMark"); ! if (sns->addr_valid) { unsigned int info; info = (sns->u.xtended.info0 << 24) | (sns->u.xtended.info1 << 16) | *** /tmp/scsi_33C93.h Tue May 18 01:42:59 1993 --- ./kernel/scsi/adapters/scsi_33C93.h Tue May 18 01:02:52 1993 *************** typedef struct { *** 142,158 **** volatile unsigned char sbic_value; /* rw: register value */ } sbic_ind_regmap_t; ! #define sbic_read_reg(regs,regno,val) { \ (regs)->sbic_address = (regno); \ wbflush(); \ (val) = (regs)->sbic_value; \ ! } ! #define sbic_write_reg(regs,regno,val) { \ (regs)->sbic_address = (regno); \ wbflush(); \ (regs)->sbic_value = (val); \ ! } #define SBIC_myid 0 #define SBIC_cdbsize 0 --- 142,158 ---- volatile unsigned char sbic_value; /* rw: register value */ } sbic_ind_regmap_t; ! #define sbic_read_reg(regs,regno,val) do { \ (regs)->sbic_address = (regno); \ wbflush(); \ (val) = (regs)->sbic_value; \ ! } while (0) ! #define sbic_write_reg(regs,regno,val) do { \ (regs)->sbic_address = (regno); \ wbflush(); \ (regs)->sbic_value = (val); \ ! } while (0) #define SBIC_myid 0 #define SBIC_cdbsize 0 *** /tmp/scsi_33c93_hdw.c Tue May 18 01:43:06 1993 --- ./kernel/scsi/adapters/scsi_33c93_hdw.c Tue May 18 01:03:08 1993 *************** *** 102,110 **** #define PAD(n) char n; #define PAD0 char __pad0; #ifdef A3000 ! #define SBIC_CLOCK_FREQUENCY 143 /* according to A3000T service manual */ #endif ! #ifdef A2091 #define SBIC_CLOCK_FREQUENCY 77 #endif #define SBIC_MACHINE_DMA_MODE SBIC_CTL_DMA --- 102,111 ---- #define PAD(n) char n; #define PAD0 char __pad0; #ifdef A3000 ! /* according to A3000T service manual */ ! #define SBIC_CLOCK_FREQUENCY 143 #endif ! #if defined (A2091) || defined (GVP11) #define SBIC_CLOCK_FREQUENCY 77 #endif #define SBIC_MACHINE_DMA_MODE SBIC_CTL_DMA *************** *** 124,129 **** --- 125,133 ---- } #endif #endif + #ifdef GVP11 + #include + #endif #define db_printf printf #define db_printsym(arg,arg2) printf("$%lx\n", arg) #define wbflush() *************** typedef struct { *** 193,199 **** PAD(pad20) volatile unsigned char sbic_selid; /* rw: Target ID (select) */ PAD(pad21) ! volatile unsigned char sbic_rselid; /* rw: Target ID (reselect) */ PAD(pad22) volatile unsigned char sbic_csr; /* r : Status register */ PAD(pad23) --- 197,203 ---- PAD(pad20) volatile unsigned char sbic_selid; /* rw: Target ID (select) */ PAD(pad21) ! volatile unsigned char sbic_rselid; /* rw: Target ID (resel.) */ PAD(pad22) volatile unsigned char sbic_csr; /* r : Status register */ PAD(pad23) *************** typedef struct { *** 211,217 **** PAD(pad29) char u4; /* unused, padding */ PAD(pad30) ! volatile unsigned char sbic_asr; /* r : Aux Status Register */ PAD(pad31) } sbic_padded_mux_regmap_t; --- 215,221 ---- PAD(pad29) char u4; /* unused, padding */ PAD(pad30) ! volatile unsigned char sbic_asr; /* r : Aux Status Reg. */ PAD(pad31) } sbic_padded_mux_regmap_t; *************** typedef struct { *** 220,227 **** #ifdef PAD0 PAD0 #endif ! volatile unsigned char sbic_asr; /* r : Aux Status Register */ ! /*#define sbic_address sbic_asr /* w : desired register no */ PAD(pad1); volatile unsigned char sbic_value; /* rw: register value */ PAD(pad2); --- 224,231 ---- #ifdef PAD0 PAD0 #endif ! volatile unsigned char sbic_asr; /* r : Aux Status Reg. */ ! /*#define sbic_address sbic_asr /* w : desired reg no */ PAD(pad1); volatile unsigned char sbic_value; /* rw: register value */ PAD(pad2); *************** typedef sbic_padded_mux_regmap_t *** 331,390 **** typedef sbic_padded_ind_regmap_t sbic_padded_regmap_t; ! #define SET_SBIC_myid(regs,val) sbic_write_reg(regs,SBIC_myid,val) ! #define GET_SBIC_myid(regs,val) sbic_read_reg(regs,SBIC_myid,val) ! #define SET_SBIC_cdbsize(regs,val) sbic_write_reg(regs,SBIC_cdbsize,val) ! #define GET_SBIC_cdbsize(regs,val) sbic_read_reg(regs,SBIC_cdbsize,val) ! #define SET_SBIC_control(regs,val) sbic_write_reg(regs,SBIC_control,val) ! #define GET_SBIC_control(regs,val) sbic_read_reg(regs,SBIC_control,val) ! #define SET_SBIC_timeo(regs,val) sbic_write_reg(regs,SBIC_timeo,val) ! #define GET_SBIC_timeo(regs,val) sbic_read_reg(regs,SBIC_timeo,val) ! #define SET_SBIC_cdb1(regs,val) sbic_write_reg(regs,SBIC_cdb1,val) ! #define GET_SBIC_cdb1(regs,val) sbic_read_reg(regs,SBIC_cdb1,val) ! #define SET_SBIC_cdb2(regs,val) sbic_write_reg(regs,SBIC_cdb2,val) ! #define GET_SBIC_cdb2(regs,val) sbic_read_reg(regs,SBIC_cdb2,val) ! #define SET_SBIC_cdb3(regs,val) sbic_write_reg(regs,SBIC_cdb3,val) ! #define GET_SBIC_cdb3(regs,val) sbic_read_reg(regs,SBIC_cdb3,val) ! #define SET_SBIC_cdb4(regs,val) sbic_write_reg(regs,SBIC_cdb4,val) ! #define GET_SBIC_cdb4(regs,val) sbic_read_reg(regs,SBIC_cdb4,val) ! #define SET_SBIC_cdb5(regs,val) sbic_write_reg(regs,SBIC_cdb5,val) ! #define GET_SBIC_cdb5(regs,val) sbic_read_reg(regs,SBIC_cdb5,val) ! #define SET_SBIC_cdb6(regs,val) sbic_write_reg(regs,SBIC_cdb6,val) ! #define GET_SBIC_cdb6(regs,val) sbic_read_reg(regs,SBIC_cdb6,val) ! #define SET_SBIC_cdb7(regs,val) sbic_write_reg(regs,SBIC_cdb7,val) ! #define GET_SBIC_cdb7(regs,val) sbic_read_reg(regs,SBIC_cdb7,val) ! #define SET_SBIC_cdb8(regs,val) sbic_write_reg(regs,SBIC_cdb8,val) ! #define GET_SBIC_cdb8(regs,val) sbic_read_reg(regs,SBIC_cdb8,val) ! #define SET_SBIC_cdb9(regs,val) sbic_write_reg(regs,SBIC_cdb9,val) ! #define GET_SBIC_cdb9(regs,val) sbic_read_reg(regs,SBIC_cdb9,val) ! #define SET_SBIC_cdb10(regs,val) sbic_write_reg(regs,SBIC_cdb10,val) ! #define GET_SBIC_cdb10(regs,val) sbic_read_reg(regs,SBIC_cdb10,val) ! #define SET_SBIC_cdb11(regs,val) sbic_write_reg(regs,SBIC_cdb11,val) ! #define GET_SBIC_cdb11(regs,val) sbic_read_reg(regs,SBIC_cdb11,val) ! #define SET_SBIC_cdb12(regs,val) sbic_write_reg(regs,SBIC_cdb12,val) ! #define GET_SBIC_cdb12(regs,val) sbic_read_reg(regs,SBIC_cdb12,val) ! #define SET_SBIC_tlun(regs,val) sbic_write_reg(regs,SBIC_tlun,val) ! #define GET_SBIC_tlun(regs,val) sbic_read_reg(regs,SBIC_tlun,val) ! #define SET_SBIC_cmd_phase(regs,val) sbic_write_reg(regs,SBIC_cmd_phase,val) ! #define GET_SBIC_cmd_phase(regs,val) sbic_read_reg(regs,SBIC_cmd_phase,val) ! #define SET_SBIC_syn(regs,val) sbic_write_reg(regs,SBIC_syn,val) ! #define GET_SBIC_syn(regs,val) sbic_read_reg(regs,SBIC_syn,val) ! #define SET_SBIC_count_hi(regs,val) sbic_write_reg(regs,SBIC_count_hi,val) ! #define GET_SBIC_count_hi(regs,val) sbic_read_reg(regs,SBIC_count_hi,val) ! #define SET_SBIC_count_med(regs,val) sbic_write_reg(regs,SBIC_count_med,val) ! #define GET_SBIC_count_med(regs,val) sbic_read_reg(regs,SBIC_count_med,val) ! #define SET_SBIC_count_lo(regs,val) sbic_write_reg(regs,SBIC_count_lo,val) ! #define GET_SBIC_count_lo(regs,val) sbic_read_reg(regs,SBIC_count_lo,val) ! #define SET_SBIC_selid(regs,val) sbic_write_reg(regs,SBIC_selid,val) ! #define GET_SBIC_selid(regs,val) sbic_read_reg(regs,SBIC_selid,val) ! #define SET_SBIC_rselid(regs,val) sbic_write_reg(regs,SBIC_rselid,val) ! #define GET_SBIC_rselid(regs,val) sbic_read_reg(regs,SBIC_rselid,val) ! #define SET_SBIC_csr(regs,val) sbic_write_reg(regs,SBIC_csr,val) ! #define GET_SBIC_csr(regs,val) sbic_read_reg(regs,SBIC_csr,val) ! #define SET_SBIC_cmd(regs,val) sbic_write_reg(regs,SBIC_cmd,val) ! #define GET_SBIC_cmd(regs,val) sbic_read_reg(regs,SBIC_cmd,val) ! #define SET_SBIC_data(regs,val) sbic_write_reg(regs,SBIC_data,val) ! #define GET_SBIC_data(regs,val) sbic_read_reg(regs,SBIC_data,val) #define SBIC_TC_PUT(regs,val) { \ sbic_write_reg(regs,SBIC_count_hi,((val)>>16)); \ --- 335,394 ---- typedef sbic_padded_ind_regmap_t sbic_padded_regmap_t; ! #define SET_SBIC_myid(regs,val) sbic_write_reg(regs,SBIC_myid,val) ! #define GET_SBIC_myid(regs,val) sbic_read_reg(regs,SBIC_myid,val) ! #define SET_SBIC_cdbsize(regs,val) sbic_write_reg(regs,SBIC_cdbsize,val) ! #define GET_SBIC_cdbsize(regs,val) sbic_read_reg(regs,SBIC_cdbsize,val) ! #define SET_SBIC_control(regs,val) sbic_write_reg(regs,SBIC_control,val) ! #define GET_SBIC_control(regs,val) sbic_read_reg(regs,SBIC_control,val) ! #define SET_SBIC_timeo(regs,val) sbic_write_reg(regs,SBIC_timeo,val) ! #define GET_SBIC_timeo(regs,val) sbic_read_reg(regs,SBIC_timeo,val) ! #define SET_SBIC_cdb1(regs,val) sbic_write_reg(regs,SBIC_cdb1,val) ! #define GET_SBIC_cdb1(regs,val) sbic_read_reg(regs,SBIC_cdb1,val) ! #define SET_SBIC_cdb2(regs,val) sbic_write_reg(regs,SBIC_cdb2,val) ! #define GET_SBIC_cdb2(regs,val) sbic_read_reg(regs,SBIC_cdb2,val) ! #define SET_SBIC_cdb3(regs,val) sbic_write_reg(regs,SBIC_cdb3,val) ! #define GET_SBIC_cdb3(regs,val) sbic_read_reg(regs,SBIC_cdb3,val) ! #define SET_SBIC_cdb4(regs,val) sbic_write_reg(regs,SBIC_cdb4,val) ! #define GET_SBIC_cdb4(regs,val) sbic_read_reg(regs,SBIC_cdb4,val) ! #define SET_SBIC_cdb5(regs,val) sbic_write_reg(regs,SBIC_cdb5,val) ! #define GET_SBIC_cdb5(regs,val) sbic_read_reg(regs,SBIC_cdb5,val) ! #define SET_SBIC_cdb6(regs,val) sbic_write_reg(regs,SBIC_cdb6,val) ! #define GET_SBIC_cdb6(regs,val) sbic_read_reg(regs,SBIC_cdb6,val) ! #define SET_SBIC_cdb7(regs,val) sbic_write_reg(regs,SBIC_cdb7,val) ! #define GET_SBIC_cdb7(regs,val) sbic_read_reg(regs,SBIC_cdb7,val) ! #define SET_SBIC_cdb8(regs,val) sbic_write_reg(regs,SBIC_cdb8,val) ! #define GET_SBIC_cdb8(regs,val) sbic_read_reg(regs,SBIC_cdb8,val) ! #define SET_SBIC_cdb9(regs,val) sbic_write_reg(regs,SBIC_cdb9,val) ! #define GET_SBIC_cdb9(regs,val) sbic_read_reg(regs,SBIC_cdb9,val) ! #define SET_SBIC_cdb10(regs,val) sbic_write_reg(regs,SBIC_cdb10,val) ! #define GET_SBIC_cdb10(regs,val) sbic_read_reg(regs,SBIC_cdb10,val) ! #define SET_SBIC_cdb11(regs,val) sbic_write_reg(regs,SBIC_cdb11,val) ! #define GET_SBIC_cdb11(regs,val) sbic_read_reg(regs,SBIC_cdb11,val) ! #define SET_SBIC_cdb12(regs,val) sbic_write_reg(regs,SBIC_cdb12,val) ! #define GET_SBIC_cdb12(regs,val) sbic_read_reg(regs,SBIC_cdb12,val) ! #define SET_SBIC_tlun(regs,val) sbic_write_reg(regs,SBIC_tlun,val) ! #define GET_SBIC_tlun(regs,val) sbic_read_reg(regs,SBIC_tlun,val) ! #define SET_SBIC_cmd_phase(regs,val) sbic_write_reg(regs,SBIC_cmd_phase,val) ! #define GET_SBIC_cmd_phase(regs,val) sbic_read_reg(regs,SBIC_cmd_phase,val) ! #define SET_SBIC_syn(regs,val) sbic_write_reg(regs,SBIC_syn,val) ! #define GET_SBIC_syn(regs,val) sbic_read_reg(regs,SBIC_syn,val) ! #define SET_SBIC_count_hi(regs,val) sbic_write_reg(regs,SBIC_count_hi,val) ! #define GET_SBIC_count_hi(regs,val) sbic_read_reg(regs,SBIC_count_hi,val) ! #define SET_SBIC_count_med(regs,val) sbic_write_reg(regs,SBIC_count_med,val) ! #define GET_SBIC_count_med(regs,val) sbic_read_reg(regs,SBIC_count_med,val) ! #define SET_SBIC_count_lo(regs,val) sbic_write_reg(regs,SBIC_count_lo,val) ! #define GET_SBIC_count_lo(regs,val) sbic_read_reg(regs,SBIC_count_lo,val) ! #define SET_SBIC_selid(regs,val) sbic_write_reg(regs,SBIC_selid,val) ! #define GET_SBIC_selid(regs,val) sbic_read_reg(regs,SBIC_selid,val) ! #define SET_SBIC_rselid(regs,val) sbic_write_reg(regs,SBIC_rselid,val) ! #define GET_SBIC_rselid(regs,val) sbic_read_reg(regs,SBIC_rselid,val) ! #define SET_SBIC_csr(regs,val) sbic_write_reg(regs,SBIC_csr,val) ! #define GET_SBIC_csr(regs,val) sbic_read_reg(regs,SBIC_csr,val) ! #define SET_SBIC_cmd(regs,val) sbic_write_reg(regs,SBIC_cmd,val) ! #define GET_SBIC_cmd(regs,val) sbic_read_reg(regs,SBIC_cmd,val) ! #define SET_SBIC_data(regs,val) sbic_write_reg(regs,SBIC_data,val) ! #define GET_SBIC_data(regs,val) sbic_read_reg(regs,SBIC_data,val) #define SBIC_TC_PUT(regs,val) { \ sbic_write_reg(regs,SBIC_count_hi,((val)>>16)); \ *************** typedef struct script { *** 456,483 **** /* forward decls of script actions */ boolean_t ! sbic_end(), /* all come to an end */ ! sbic_prepare_status(), /* prepare to get status from target */ ! sbic_get_status(), /* get status from target */ ! sbic_dma_in(), /* get data from target via dma */ ! sbic_dma_in_r(), /* get data from target via dma (restartable)*/ ! sbic_dma_out(), /* send data to target via dma */ ! sbic_dma_out_r(), /* send data to target via dma (restartable) */ ! sbic_ack_sel(), /* negotiate synch xfer */ ! sbic_send_ident(), /* negotiate synch xfer */ ! sbic_load_cmd_atn(), /* negotiate synch xfer */ sbic_load_cmd(), ! sbic_dosynch(), /* negotiate synch xfer */ ! sbic_bus_device_reset(), /* send a BUS RESET message */ ! sbic_msg_in(), /* receive the disconenct message */ ! sbic_disconnected(), /* target has disconnected */ ! sbic_reconnect(); /* target reconnected */ /* forward decls of error handlers */ boolean_t ! sbic_err_generic(), /* generic handler */ ! sbic_err_disconn(), /* target disconnects amidst */ ! gimmeabreak(); /* drop into the debugger */ int sbic_reset_scsibus(); boolean_t sbic_probe_target(); --- 460,487 ---- /* forward decls of script actions */ boolean_t ! sbic_end(), /* all come to an end */ ! sbic_prepare_status(), /* prepare to get status from target */ ! sbic_get_status(), /* get status from target */ ! sbic_dma_in(), /* get data from target via dma */ ! sbic_dma_in_r(), /* ditto (restartable) */ ! sbic_dma_out(), /* send data to target via dma */ ! sbic_dma_out_r(), /* ditto (restartable) */ ! sbic_ack_sel(), /* negotiate synch xfer */ ! sbic_send_ident(), /* negotiate synch xfer */ ! sbic_load_cmd_atn(), /* negotiate synch xfer */ sbic_load_cmd(), ! sbic_dosynch(), /* negotiate synch xfer */ ! sbic_bus_device_reset(), /* send a BUS RESET message */ ! sbic_msg_in(), /* receive the disconenct message */ ! sbic_disconnected(), /* target has disconnected */ ! sbic_reconnect(); /* target reconnected */ /* forward decls of error handlers */ boolean_t ! sbic_err_generic(), /* generic handler */ ! sbic_err_disconn(), /* target disconnects amidst */ ! gimmeabreak(); /* drop into the debugger */ int sbic_reset_scsibus(); boolean_t sbic_probe_target(); *************** static sbic_wait(); *** 487,521 **** * State descriptor for this layer. There is one such structure * per (enabled) SCSI-33c93 interface */ ! struct sbic_softc { ! watchdog_t wd; ! sbic_padded_regmap_t *regs; /* 33c93 registers */ ! ! scsi_dma_ops_t *dma_ops; /* DMA operations and state */ ! opaque_t dma_state; ! ! script_t script; /* what should happen next */ ! boolean_t (*error_handler)();/* what if something is wrong */ ! int in_count; /* amnt we expect to receive */ ! int out_count; /* amnt we are going to ship */ ! ! volatile char state; ! #define SBIC_STATE_BUSY 0x01 /* selecting or currently connected */ ! #define SBIC_STATE_TARGET 0x04 /* currently selected as target */ ! #define SBIC_STATE_COLLISION 0x08 /* lost selection attempt */ ! #define SBIC_STATE_DMA_IN 0x10 /* tgt --> initiator xfer */ ! #define SBIC_STATE_AM_MODE 0x20 /* 33c93A with advanced mode (AM) */ ! ! unsigned char ntargets; /* how many alive on this scsibus */ ! unsigned char done; ! unsigned char unused; ! ! scsi_softc_t *sc; /* HBA-indep info */ ! target_info_t *active_target; /* the current one */ ! ! target_info_t *next_target; /* trying to seize bus */ ! queue_head_t waiting_targets;/* other targets competing for bus */ ! } sbic_softc_data[NSBIC]; typedef struct sbic_softc *sbic_softc_t; --- 491,525 ---- * State descriptor for this layer. There is one such structure * per (enabled) SCSI-33c93 interface */ ! struct sbic_softc ! { ! watchdog_t wd; ! sbic_padded_regmap_t *regs; /* 33c93 registers */ ! ! scsi_dma_ops_t *dma_ops; /* DMA operations and state */ ! opaque_t dma_state; ! ! script_t script; /* what should happen next */ ! boolean_t (*error_handler)(); /* what if something is wrong */ ! int in_count; /* amount we expect to receive */ ! int out_count; /* amount we are going to ship */ ! ! volatile char state; ! #define SBIC_STATE_BUSY 0x01 /* selecting or currently connected */ ! #define SBIC_STATE_TARGET 0x04 /* currently selected as target */ ! #define SBIC_STATE_COLLISION 0x08 /* lost selection attempt */ ! #define SBIC_STATE_DMA_IN 0x10 /* tgt --> initiator xfer */ ! #define SBIC_STATE_AM_MODE 0x20 /* 33c93A with advanced mode (AM) */ ! ! unsigned char ntargets; /* how many alive on this scsibus */ ! unsigned char done; ! unsigned char unused; ! ! scsi_softc_t *sc; /* HBA-indep info */ ! target_info_t *active_target; /* the current one */ ! ! target_info_t *next_target; /* trying to seize bus */ ! queue_head_t waiting_targets; /* other targets competing for bus */ } sbic_softc_data[NSBIC]; typedef struct sbic_softc *sbic_softc_t; *************** typedef struct sbic_softc *sbic_softc_t; *** 522,535 **** sbic_softc_t sbic_softc[NSBIC]; - /* sbic probed and ready to serve interrupts */ - int sbic_probed = 0; - /* * Synch xfer parameters, and timing conversions */ ! int sbic_min_period = SBIC_SYN_MIN_PERIOD; /* in cycles = f(ICLK,FSn) */ ! int sbic_max_offset = SBIC_SYN_MAX_OFFSET; /* pure number */ int sbic_to_scsi_period(regs,a) sbic_padded_regmap_t *regs; --- 526,536 ---- sbic_softc_t sbic_softc[NSBIC]; /* * Synch xfer parameters, and timing conversions */ ! int sbic_min_period = SBIC_SYN_MIN_PERIOD; /* in cycles = f(ICLK,FSn) */ ! int sbic_max_offset = SBIC_SYN_MAX_OFFSET; /* pure number */ int sbic_to_scsi_period(regs,a) sbic_padded_regmap_t *regs; *************** int sbic_to_scsi_period(regs,a) *** 541,550 **** /* best we can do is 200ns at 20Mhz, 2 cycles */ GET_SBIC_myid(regs,fs); ! fs = (fs >>6) + 2; /* DIV */ ! fs = (fs * 10000) / (SBIC_CLOCK_FREQUENCY<<1); /* Cycle, in ns */ ! if (a < 2) a = 8; /* map to Cycles */ ! return ((fs*a)>>2); /* in 4 ns units */ } int scsi_period_to_sbic(regs,p) --- 542,551 ---- /* best we can do is 200ns at 20Mhz, 2 cycles */ GET_SBIC_myid(regs,fs); ! fs = (fs >> 6) + 2; /* DIV */ ! fs = (fs * 10000) / (SBIC_CLOCK_FREQUENCY << 1); /* Cycle, in ns */ ! if (a < 2) a = 8; /* map to Cycles */ ! return ((fs * a) >> 2); /* in 4 ns units */ } int scsi_period_to_sbic(regs,p) *************** int scsi_period_to_sbic(regs,p) *** 555,565 **** /* Just the inverse of the above */ GET_SBIC_myid(regs,fs); ! fs = (fs >>6) + 2; /* DIV */ ! fs = (fs * 10000) / (SBIC_CLOCK_FREQUENCY<<1); /* Cycle, in ns */ ! ret = p << 2; /* in ns units */ ! ret = ret / fs; /* in Cycles */ if (ret < sbic_min_period) return sbic_min_period; /* verify rounding */ --- 556,566 ---- /* Just the inverse of the above */ GET_SBIC_myid(regs,fs); ! fs = (fs >> 6) + 2; /* DIV */ ! fs = (fs * 10000) / (SBIC_CLOCK_FREQUENCY << 1); /* Cycle, in ns */ ! ret = p << 2; /* in ns units */ ! ret = ret / fs; /* in Cycles */ if (ret < sbic_min_period) return sbic_min_period; /* verify rounding */ *************** int scsi_period_to_sbic(regs,p) *** 574,587 **** * Definition of the controller for the auto-configuration program. */ ! int sbic_probe(), scsi_slave(), scsi_attach(), sbic_go(), sbic_intr(); caddr_t sbic_std[NSBIC] = { 0 }; struct bus_device *sbic_dinfo[NSBIC*8]; struct bus_ctlr *sbic_minfo[NSBIC]; struct bus_driver sbic_driver = ! { sbic_probe, scsi_slave, scsi_attach, sbic_go, sbic_std, "rz", sbic_dinfo, ! "sbic", sbic_minfo, BUS_INTR_B4_PROBE}; sbic_set_dmaops(unit, dmaops) --- 575,591 ---- * Definition of the controller for the auto-configuration program. */ ! int sbic_probe(), scsi_slave(), scsi_attach(), sbic_go(); ! void sbic_intr(); caddr_t sbic_std[NSBIC] = { 0 }; struct bus_device *sbic_dinfo[NSBIC*8]; struct bus_ctlr *sbic_minfo[NSBIC]; struct bus_driver sbic_driver = ! { ! sbic_probe, scsi_slave, scsi_attach, sbic_go, sbic_std, "rz", sbic_dinfo, ! "sbic", sbic_minfo, BUS_INTR_B4_PROBE ! }; sbic_set_dmaops(unit, dmaops) *************** sbic_state(regs, overrule) *** 675,680 **** --- 679,687 ---- #ifdef A2091 regs = (sbic_padded_regmap_t*)A2091_SCSI_ADDR; #endif + #ifdef GVP11 + regs = (sbic_padded_regmap_t*)GVP11_SCSI_ADDR; + #endif } GET_SBIC_asr(regs,asr); *************** sbic_target_state(tgt) *** 716,726 **** tgt = sbic_softc[0]->active_target; if (tgt == 0) return 0; ! db_printf("@x%x: fl %x dma %X+%x cmd %x@%X id %x per %x off %x ior %X ret %X\n", ! tgt, ! tgt->flags, tgt->dma_ptr, tgt->transient_state.dma_offset, tgt->cur_cmd, ! tgt->cmd_ptr, tgt->target_id, tgt->sync_period, tgt->sync_offset, ! tgt->ior, tgt->done); if (tgt->flags & TGT_DISCONNECTED){ script_t spt; --- 723,734 ---- tgt = sbic_softc[0]->active_target; if (tgt == 0) return 0; ! db_printf("@x%x: fl %x dma %X+%x cmd %x@%X id %x per %x off %x " ! "ior %X ret %X\n", ! tgt, tgt->flags, tgt->dma_ptr, ! tgt->transient_state.dma_offset, tgt->cur_cmd, ! tgt->cmd_ptr, tgt->target_id, tgt->sync_period, ! tgt->sync_offset, tgt->ior, tgt->done); if (tgt->flags & TGT_DISCONNECTED){ script_t spt; *************** sbic_target_state(tgt) *** 727,733 **** spt = tgt->transient_state.script; db_printf("disconnected at "); db_printsym(spt,1); ! db_printf(": %x %x ", spt->condition.csr, spt->condition.pha); db_printsym(spt->action,1); db_printf(", "); db_printsym(tgt->transient_state.handler, 1); --- 735,742 ---- spt = tgt->transient_state.script; db_printf("disconnected at "); db_printsym(spt,1); ! db_printf(": %x %x ", spt->condition.csr, ! spt->condition.pha); db_printsym(spt->action,1); db_printf(", "); db_printsym(tgt->transient_state.handler, 1); *************** sbic_probe (reg, ui) *** 874,881 **** SBIC_probe(reg, ui); #endif /*MAPPABLE*/ - sbic_probed ++; - /* * Initialize hw descriptor, cache some pointers */ --- 883,888 ---- *************** sbic_reset (regs, quick) *** 1082,1088 **** /* will do IDI on the fly */ SET_SBIC_control (regs, (/*SBIC_CTL_HHP | SBIC_CTL_EDI */ /* | SBIC_CTL_HSP | */ SBIC_MACHINE_DMA_MODE)); ! /* don't allow selection (SBIC_RID_ES) until we can handle target mode!! */ SET_SBIC_rselid (regs, SBIC_RID_ER /* | SBIC_RID_ES | SBIC_RID_DSP */); SET_SBIC_syn (regs, SBIC_SYN(0,sbic_min_period)); /* asynch for now */ --- 1089,1095 ---- /* will do IDI on the fly */ SET_SBIC_control (regs, (/*SBIC_CTL_HHP | SBIC_CTL_EDI */ /* | SBIC_CTL_HSP | */ SBIC_MACHINE_DMA_MODE)); ! /* don't allow selection (SBIC_RID_ES) until we can handle target mode! */ SET_SBIC_rselid (regs, SBIC_RID_ER /* | SBIC_RID_ES | SBIC_RID_DSP */); SET_SBIC_syn (regs, SBIC_SYN(0,sbic_min_period)); /* asynch for now */ *************** sbic_go (tgt, cmd_count, in_count, cmd_o *** 1154,1160 **** case SCSI_CMD_LONG_READ: LOG(2,"readop"); #if CMD_DEBUG ! printf("readop\n"); #endif scp = sbic_script_data_in; break; --- 1161,1167 ---- case SCSI_CMD_LONG_READ: LOG(2,"readop"); #if CMD_DEBUG ! printf("readop\n"); #endif scp = sbic_script_data_in; break; *************** printf("readop\n"); *** 1163,1169 **** case SCSI_CMD_LONG_WRITE: LOG(0x1a,"writeop"); #if CMD_DEBUG ! printf("writeop\n"); #endif scp = sbic_script_data_out; break; --- 1170,1176 ---- case SCSI_CMD_LONG_WRITE: LOG(0x1a,"writeop"); #if CMD_DEBUG ! printf("writeop\n"); #endif scp = sbic_script_data_out; break; *************** printf("writeop\n"); *** 1172,1184 **** /* This is likely the first thing out: do the synch neg if so */ #if CMD_DEBUG ! printf("inquiryop\n"); #endif if (!cmd_only && ((tgt->flags&TGT_DID_SYNCH)==0)) { scp = sbic_script_try_synch; tgt->flags |= TGT_TRY_SYNCH; ! break; } /* fall thru */ --- 1179,1191 ---- /* This is likely the first thing out: do the synch neg if so */ #if CMD_DEBUG ! printf("inquiryop\n"); #endif if (!cmd_only && ((tgt->flags&TGT_DID_SYNCH)==0)) { scp = sbic_script_try_synch; tgt->flags |= TGT_TRY_SYNCH; ! break; } /* fall thru */ *************** printf("inquiryop\n"); *** 1188,1194 **** case SCSI_CMD_READ_CAPACITY: case SCSI_CMD_READ_BLOCK_LIMITS: #if CMD_DEBUG ! printf("cmdop\n"); #endif scp = sbic_script_data_in; LOG(0x1c,"cmdop"); --- 1195,1201 ---- case SCSI_CMD_READ_CAPACITY: case SCSI_CMD_READ_BLOCK_LIMITS: #if CMD_DEBUG ! printf("cmdop\n"); #endif scp = sbic_script_data_in; LOG(0x1c,"cmdop"); *************** printf("cmdop\n"); *** 1199,1208 **** case SCSI_CMD_REASSIGN_BLOCKS: case SCSI_CMD_FORMAT_UNIT: #if CMD_DEBUG ! printf("maintop\n"); #endif tgt->transient_state.cmd_count = sizeof(scsi_command_group_0); ! tgt->transient_state.out_count = cmd_count - sizeof(scsi_command_group_0); scp = sbic_script_data_out; LOG(0x1c,"cmdop"); LOG(0x80+tgt->cur_cmd,0); --- 1206,1216 ---- case SCSI_CMD_REASSIGN_BLOCKS: case SCSI_CMD_FORMAT_UNIT: #if CMD_DEBUG ! printf("maintop\n"); #endif tgt->transient_state.cmd_count = sizeof(scsi_command_group_0); ! tgt->transient_state.out_count ! = cmd_count - sizeof(scsi_command_group_0); scp = sbic_script_data_out; LOG(0x1c,"cmdop"); LOG(0x80+tgt->cur_cmd,0); *************** printf("maintop\n"); *** 1210,1216 **** case SCSI_CMD_TEST_UNIT_READY: #if CMD_DEBUG ! printf("TURop\n"); #endif /* * Do the synch negotiation here, unless prohibited --- 1218,1224 ---- case SCSI_CMD_TEST_UNIT_READY: #if CMD_DEBUG ! printf("TURop\n"); #endif /* * Do the synch negotiation here, unless prohibited *************** printf("TURop\n"); *** 1230,1236 **** default: #if CMD_DEBUG ! printf("otherop\n"); #endif LOG(0x1c,"cmdop"); LOG(0x80+tgt->cur_cmd,0); --- 1238,1244 ---- default: #if CMD_DEBUG ! printf("otherop\n"); #endif LOG(0x1c,"cmdop"); LOG(0x80+tgt->cur_cmd,0); *************** sbic_attempt_selection (sbic) *** 1335,1341 **** val &= ~(SBIC_RID_MASK|SBIC_RID_ER); /* the enable reselection bit is used to build the identify msg */ if (tgt->transient_state.identify != 0xff) ! val |= (tgt->transient_state.identify & SCSI_IFY_ENABLE_DISCONNECT) << 1; SET_SBIC_rselid (regs, val); SET_SBIC_tlun (regs, tgt->lun); --- 1343,1350 ---- val &= ~(SBIC_RID_MASK|SBIC_RID_ER); /* the enable reselection bit is used to build the identify msg */ if (tgt->transient_state.identify != 0xff) ! val ! |= (tgt->transient_state.identify & SCSI_IFY_ENABLE_DISCONNECT) << 1; SET_SBIC_rselid (regs, val); SET_SBIC_tlun (regs, tgt->lun); *************** sbic_attempt_selection (sbic) *** 1364,1371 **** SET_SBIC_selid (regs, val); val = SBIC_SYN(tgt->sync_offset,tgt->sync_period); ! #if 0 ! printf("s[%d,%d] ", tgt->sync_offset,tgt->sync_period); #endif SET_SBIC_syn (regs, val); GET_SBIC_syn (regs, count); --- 1373,1380 ---- SET_SBIC_selid (regs, val); val = SBIC_SYN(tgt->sync_offset,tgt->sync_period); ! #if SCSI_DEBUG ! printf("s[%d,%d] ", tgt->sync_offset,tgt->sync_period); #endif SET_SBIC_syn (regs, val); GET_SBIC_syn (regs, count); *************** printf("s[%d,%d] ", tgt->sync_offset,tgt *** 1372,1385 **** if (count != val) panic ("couldn't set sync-period!!"); ! if (tgt->flags & TGT_DID_SYNCH) ! command = ((tgt->transient_state.identify == 0xff) ! ? SBIC_CMD_SEL ! : SBIC_CMD_SEL_ATN); /*preferred*/ ! else if (tgt->flags & TGT_TRY_SYNCH) ! command = SBIC_CMD_SEL_ATN; ! else ! command = SBIC_CMD_SEL; } /* Try to avoid reselect collisions */ --- 1381,1389 ---- if (count != val) panic ("couldn't set sync-period!!"); ! command = (tgt->transient_state.identify == 0xff ! ? SBIC_CMD_SEL ! : SBIC_CMD_SEL_ATN); /*preferred*/ } /* Try to avoid reselect collisions */ *************** printf("s[%d,%d] ", tgt->sync_offset,tgt *** 1386,1397 **** GET_SBIC_asr (regs,val); if (val & SBIC_ASR_INT) { ! printf("sbic_attempt_sel: 2 returning because of resel collision\n"); return; } ! #if 0 ! printf("as[%d,$%lx] ", tgt->target_id, tgt->cur_cmd); #endif SET_SBIC_cmd (regs, command); #undef command --- 1390,1401 ---- GET_SBIC_asr (regs,val); if (val & SBIC_ASR_INT) { ! printf("sbic_attempt_sel: 2 returning because of resel collision\n"); return; } ! #if SCSI_DEBUG ! printf("as[%d,$%lx] ", tgt->target_id, tgt->cur_cmd); #endif SET_SBIC_cmd (regs, command); #undef command *************** printf("as[%d,$%lx] ", tgt->target_id, t *** 1405,1410 **** --- 1409,1415 ---- * Move along the current command's script if * all is well, invoke error handler if not. */ + void sbic_intr (unit, spllevel) int spllevel; { *************** sbic_intr (unit, spllevel) *** 1412,1418 **** register script_t scp; register int asr, csr, pha; register sbic_padded_regmap_t *regs; - static int nesting = 0; #if MAPPABLE extern boolean_t rz_use_mapped_interface; --- 1417,1422 ---- *************** sbic_intr (unit, spllevel) *** 1421,1433 **** #endif /*MAPPABLE*/ sbic = sbic_softc[unit]; - regs = sbic->regs; - /* if not yet probed... */ ! if (! sbic_probed) return; ! ! LOG(5,"\n\tintr"); /* drop spurious interrupts */ GET_SBIC_asr (regs, asr); --- 1425,1434 ---- #endif /*MAPPABLE*/ sbic = sbic_softc[unit]; /* if not yet probed... */ ! if (!sbic) return; ! regs = sbic->regs; /* drop spurious interrupts */ GET_SBIC_asr (regs, asr); *************** sbic_intr (unit, spllevel) *** 1434,1439 **** --- 1435,1442 ---- if ((asr & SBIC_ASR_INT) == 0) return; + LOG(5,"\n\tintr"); + WAIT_CIP (regs); GET_SBIC_csr (regs, csr); *************** sbic_intr (unit, spllevel) *** 1440,1454 **** /* collect ephemeral information */ GET_SBIC_cmd_phase (regs, pha); ! #if 0 printf ("intr [%d] csr = $%lx, asr = $%lx, pha = $%lx\n", ! sbic->active_target ? sbic->active_target->target_id : -1, csr, asr, pha); #endif TR(csr);TR(asr);TR(pha);TRCHECK /* XXX verify this is indeed the case for a SCSI RST asserted */ if ((csr & SBIC_CSR_CAUSE) == SBIC_CSR_RESET) ! return sbic_bus_reset(sbic); /* we got an interrupt allright */ if (sbic->active_target) --- 1443,1461 ---- /* collect ephemeral information */ GET_SBIC_cmd_phase (regs, pha); ! #if SCSI_DEBUG printf ("intr [%d] csr = $%lx, asr = $%lx, pha = $%lx\n", ! sbic->active_target ? sbic->active_target->target_id : -1, csr, ! asr, pha); #endif TR(csr);TR(asr);TR(pha);TRCHECK /* XXX verify this is indeed the case for a SCSI RST asserted */ if ((csr & SBIC_CSR_CAUSE) == SBIC_CSR_RESET) ! { ! sbic_bus_reset(sbic); ! return; ! } /* we got an interrupt allright */ if (sbic->active_target) *************** TR(csr);TR(asr);TR(pha);TRCHECK *** 1456,1462 **** #if 0 /* for now, don't. I need to be sure that I'm not interrupted by ints ! generated by the chip while doing programmed i/o to read/send messages */ splx(spllevel); /* drop priority */ #endif --- 1463,1470 ---- #if 0 /* for now, don't. I need to be sure that I'm not interrupted by ints ! generated by the chip while doing programmed i/o to read/send ! messages */ splx(spllevel); /* drop priority */ #endif *************** TR(csr);TR(asr);TR(pha);TRCHECK *** 1466,1472 **** || (csr == SBIC_CSR_RSLT_NOAM) || (csr == SBIC_CSR_SLT) || (csr == SBIC_CSR_SLT_ATN)) ! return sbic_target_intr(sbic); /* * In attempt_selection() we gave the select command even if --- 1474,1483 ---- || (csr == SBIC_CSR_RSLT_NOAM) || (csr == SBIC_CSR_SLT) || (csr == SBIC_CSR_SLT_ATN)) ! { ! sbic_target_intr(sbic); ! return; ! } /* * In attempt_selection() we gave the select command even if *************** TR(csr);TR(asr);TR(pha);TRCHECK *** 1473,1479 **** * the chip might have been reconnected already. */ if ((csr == SBIC_CSR_RSLT_NI) || (csr == SBIC_CSR_RSLT_IFY)) ! return sbic_reconnect (sbic, csr, pha); /* * Check for parity errors --- 1484,1493 ---- * the chip might have been reconnected already. */ if ((csr == SBIC_CSR_RSLT_NI) || (csr == SBIC_CSR_RSLT_IFY)) ! { ! sbic_reconnect (sbic, csr, pha); ! return; ! } /* * Check for parity errors *************** TR(csr);TR(asr);TR(pha);TRCHECK *** 1481,1487 **** if (asr & SBIC_ASR_PE) { char *msg; ! printf("{PE %x,%x}", asr, pha); msg = "SCSI bus parity error"; /* all we can do is to throw a reset on the bus */ --- 1495,1501 ---- if (asr & SBIC_ASR_PE) { char *msg; ! printf("{PE %x,%x}", asr, pha); msg = "SCSI bus parity error"; /* all we can do is to throw a reset on the bus */ *************** printf("{PE %x,%x}", asr, pha); *** 1493,1511 **** if ((scp = sbic->script) == 0) /* sanity */ { ! printf("ERROR -- NO SCRIPT!!!\n"); ! return; ! } ! ! /* check whether it's possible to get this processing single threaded.. ! this is an *AWEFUL* KLUDGE!! why the hell can this interrupt nest?? ! Is the debugger playing mean games here??? */ ! if (nesting++) ! return; ! #if 0 ! printf("Matching script [%lx,%lx]?[%lx,%lx]...", csr, pha, ! scp->condition.csr, scp->condition.pha); #endif LOG(6,"match"); if (SCRIPT_MATCH(csr,pha,scp->condition)) --- 1507,1519 ---- if ((scp = sbic->script) == 0) /* sanity */ { ! printf("ERROR -- NO SCRIPT!!!\n"); ! return; ! } ! #ifdef SCSI_DEBUG ! printf("Matching script [%lx,%lx]?[%lx,%lx]...", csr, pha, ! scp->condition.csr, scp->condition.pha); #endif LOG(6,"match"); if (SCRIPT_MATCH(csr,pha,scp->condition)) *************** printf("Matching script [%lx,%lx]?[%lx,% *** 1514,1521 **** * Perform the appropriate operation, * then proceed */ ! #if 0 ! printf("Success!\n"); #endif if ((*scp->action)(sbic, csr, pha)) { --- 1522,1529 ---- * Perform the appropriate operation, * then proceed */ ! #ifdef SCSI_DEBUG ! printf("Success!\n"); #endif if ((*scp->action)(sbic, csr, pha)) { *************** printf("Success!\n"); *** 1522,1534 **** sbic->script++; } } ! else { ! #if 0 ! printf("\n"); #endif (*sbic->error_handler)(sbic, csr, pha); ! } ! nesting--; } sbic_target_intr() --- 1530,1542 ---- sbic->script++; } } ! else ! { ! #if SCSI_DEBUG ! printf("\n"); #endif (*sbic->error_handler)(sbic, csr, pha); ! } } sbic_target_intr() *************** sbic_release_bus (sbic) *** 1593,1599 **** else { LOG(0xC,"dequeue"); ! sbic->next_target = (target_info_t *) dequeue_head (&sbic->waiting_targets); sbic_attempt_selection(sbic); } --- 1601,1608 ---- else { LOG(0xC,"dequeue"); ! sbic->next_target ! = (target_info_t *) dequeue_head (&sbic->waiting_targets); sbic_attempt_selection(sbic); } *************** sbic_prepare_status (sbic, csr, pha) *** 1608,1615 **** register target_info_t *tgt = sbic->active_target; SBIC_TC_PUT (regs, 0); ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI /*| SBIC_CTL_IDI*/ ! /* | SBIC_CTL_HSP*/ | SBIC_MACHINE_DMA_MODE)); SET_SBIC_cmd_phase (regs, 0x46); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); --- 1617,1625 ---- register target_info_t *tgt = sbic->active_target; SBIC_TC_PUT (regs, 0); ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI ! /*| SBIC_CTL_IDI*/ /*| SBIC_CTL_HSP*/ ! | SBIC_MACHINE_DMA_MODE)); SET_SBIC_cmd_phase (regs, 0x46); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); *************** TRWRAP *** 1648,1656 **** sbic->done = SCSI_RET_SUCCESS; #if 0 ! /* this is sort of a kludge... if we did a sync-setup, return RETRY so that ! the `real' command is tried again, we didn't execute any command when ! setting up sync mode */ if (tgt->flags & TGT_TRY_SYNCH) { tgt->flags &= ~TGT_TRY_SYNCH; --- 1658,1666 ---- sbic->done = SCSI_RET_SUCCESS; #if 0 ! /* this is sort of a kludge... if we did a sync-setup, return RETRY so ! that the `real' command is tried again, we didn't execute any command ! when setting up sync mode */ if (tgt->flags & TGT_TRY_SYNCH) { tgt->flags &= ~TGT_TRY_SYNCH; *************** TRWRAP *** 1659,1665 **** #endif /* Tell DMA engine we are done */ ! (*sbic->dma_ops->end_xfer)(sbic->dma_state, tgt, tgt->transient_state.in_count); return sbic_end (sbic, csr, pha); --- 1669,1676 ---- #endif /* Tell DMA engine we are done */ ! (*sbic->dma_ops->end_xfer)(sbic->dma_state, tgt, ! tgt->transient_state.in_count); return sbic_end (sbic, csr, pha); *************** sbic_dma_out_r (sbic, csr, ir) *** 1835,1841 **** if (tgt->transient_state.out_count <= 0) panic ("sbic_dma_out_r:2"); ! count = (*sbic->dma_ops->restart_dataout_2)(sbic->dma_state, tgt, xferred); /* last chunk ? */ if (tgt->transient_state.out_count == count) --- 1846,1853 ---- if (tgt->transient_state.out_count <= 0) panic ("sbic_dma_out_r:2"); ! count = (*sbic->dma_ops->restart_dataout_2)(sbic->dma_state, tgt, ! xferred); /* last chunk ? */ if (tgt->transient_state.out_count == count) *************** sbic_dosynch (sbic, csr, pha) *** 2133,2142 **** SBIC_TC_PUT (regs, 5); SET_SBIC_cmd_phase (regs, 0); SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO); ! sbic_wait (regs, SBIC_ASR_DBR); SET_SBIC_data (regs, SCSI_EXTENDED_MESSAGE); ! /* after sending the ID of the extended message, the target may at any ! time decide to reject the message. So be prepared to get an interrupt ! while transmitting our message */ if (!(sbic_wait (regs, SBIC_ASR_DBR|SBIC_ASR_INT) & SBIC_ASR_INT)) SET_SBIC_data (regs, 3); if (!(sbic_wait (regs, SBIC_ASR_DBR|SBIC_ASR_INT) & SBIC_ASR_INT)) --- 2145,2155 ---- SBIC_TC_PUT (regs, 5); SET_SBIC_cmd_phase (regs, 0); SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO); ! sbic_wait (regs, SBIC_ASR_DBR); ! SET_SBIC_data (regs, SCSI_EXTENDED_MESSAGE); ! /* after sending the ID of the extended message, the target may at ! any time decide to reject the message. So be prepared to get an ! interrupt while transmitting our message */ if (!(sbic_wait (regs, SBIC_ASR_DBR|SBIC_ASR_INT) & SBIC_ASR_INT)) SET_SBIC_data (regs, 3); if (!(sbic_wait (regs, SBIC_ASR_DBR|SBIC_ASR_INT) & SBIC_ASR_INT)) *************** sbic_dosynch (sbic, csr, pha) *** 2151,2157 **** { sbic_wait (regs, SBIC_ASR_INT); GET_SBIC_csr (regs, csr); ! /* if the command was aborted, we might have a still set TC register */ SBIC_TC_PUT (regs, 0); if ((csr & SBIC_CSR_QUALIFIER) != (0x08 | SCSI_PHASE_MSG_IN)) --- 2164,2171 ---- { sbic_wait (regs, SBIC_ASR_INT); GET_SBIC_csr (regs, csr); ! /* if the command was aborted, we might have a still set TC ! register */ SBIC_TC_PUT (regs, 0); if ((csr & SBIC_CSR_QUALIFIER) != (0x08 | SCSI_PHASE_MSG_IN)) *************** cmd: *** 2243,2249 **** tgt->sync_period = scsi_period_to_sbic (regs, c2); tgt->sync_offset = c3; ! #if 0 printf ("\ndo_sync[%d]: per = %d (%d), off = %d; resume phase $%lx.\n", tgt->target_id, tgt->sync_period, c2, tgt->sync_offset, pha); #endif --- 2257,2263 ---- tgt->sync_period = scsi_period_to_sbic (regs, c2); tgt->sync_offset = c3; ! #if SCSI_DEBUG printf ("\ndo_sync[%d]: per = %d (%d), off = %d; resume phase $%lx.\n", tgt->target_id, tgt->sync_period, c2, tgt->sync_offset, pha); #endif *************** printf ("\ndo_sync[%d]: per = %d (%d), o *** 2255,2261 **** } else { ! /* status seen, count on the chip handling the cmd complete right */ SET_SBIC_cmd_phase (regs, pha); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); } --- 2269,2276 ---- } else { ! /* status seen, count on the chip handling the cmd complete ! right */ SET_SBIC_cmd_phase (regs, pha); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); } *************** sbic_err_generic(sbic, csr, pha) *** 2406,2412 **** tgt = sbic->active_target; ! #if 0 printf("generic err\n"); #endif LOG(0x13,"err_generic"); --- 2421,2427 ---- tgt = sbic->active_target; ! #if SCSI_DEBUG printf("generic err\n"); #endif LOG(0x13,"err_generic"); *************** printf("generic err\n"); *** 2435,2442 **** panic ("target command completed???"); case SBIC_CSR_XFERRED | SCSI_PHASE_STATUS: ! if (sbic->script->condition.csr == (SBIC_CSR_XFERRED|SCSI_PHASE_DATAI) ! || sbic->script->condition.csr == (SBIC_CSR_XFERRED|SCSI_PHASE_DATAO)) { /* command seems to have no data phase, skip it and proceed to status phase */ --- 2450,2459 ---- panic ("target command completed???"); case SBIC_CSR_XFERRED | SCSI_PHASE_STATUS: ! if ((sbic->script->condition.csr ! == (SBIC_CSR_XFERRED | SCSI_PHASE_DATAI)) ! || (sbic->script->condition.csr ! == (SBIC_CSR_XFERRED | SCSI_PHASE_DATAO))) { /* command seems to have no data phase, skip it and proceed to status phase */ *************** printf("generic err\n"); *** 2446,2455 **** } else { ! /* part of sync handshake, try to have the chip complete on its own */ SBIC_TC_PUT (regs, 0); ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI /*| SBIC_CTL_IDI*/ ! /* | SBIC_CTL_HSP*/ | SBIC_MACHINE_DMA_MODE)); SET_SBIC_cmd_phase (regs, 0x46); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); } --- 2463,2474 ---- } else { ! /* part of sync handshake, try to have the chip complete on ! its own */ SBIC_TC_PUT (regs, 0); ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI ! /*| SBIC_CTL_IDI*//*| SBIC_CTL_HSP*/ ! | SBIC_MACHINE_DMA_MODE)); SET_SBIC_cmd_phase (regs, 0x46); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); } *************** printf("generic err\n"); *** 2461,2472 **** case SBIC_CSR_XFERRED | SCSI_PHASE_DATAI: printf ("DATAI: tin_count=%d, exp csr=$%lx\n", ! tgt->transient_state.in_count, sbic->script->condition.csr); return; case SBIC_CSR_S_XFERRED: #if 1 ! printf ("$16: expected script csr would be $%lx\n", sbic->script->condition.csr); #endif /* nevertheless finish it.. */ sbic_get_status (sbic, csr, pha); --- 2480,2493 ---- case SBIC_CSR_XFERRED | SCSI_PHASE_DATAI: printf ("DATAI: tin_count=%d, exp csr=$%lx\n", ! tgt->transient_state.in_count, ! sbic->script->condition.csr); return; case SBIC_CSR_S_XFERRED: #if 1 ! printf ("$16: expected script csr would be $%lx\n", ! sbic->script->condition.csr); #endif /* nevertheless finish it.. */ sbic_get_status (sbic, csr, pha); *************** printf("generic err\n"); *** 2488,2499 **** /* Good! */ SET_SBIC_cmd (regs, SBIC_CMD_CLR_ACK); sbic->done = SCSI_RET_SUCCESS; ! (*sbic->dma_ops->end_xfer)(sbic->dma_state, tgt, tgt->transient_state.in_count); return sbic_end(sbic, csr, pha); case SCSI_DISCONNECT: ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI | SBIC_CTL_IDI ! /* | SBIC_CTL_HSP*/ | SBIC_MACHINE_DMA_MODE)); SET_SBIC_cmd_phase (regs, 0x42); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); return; --- 2509,2522 ---- /* Good! */ SET_SBIC_cmd (regs, SBIC_CMD_CLR_ACK); sbic->done = SCSI_RET_SUCCESS; ! (*sbic->dma_ops->end_xfer)(sbic->dma_state, tgt, ! tgt->transient_state.in_count); return sbic_end(sbic, csr, pha); case SCSI_DISCONNECT: ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI ! | SBIC_CTL_IDI /*| SBIC_CTL_HSP*/ ! | SBIC_MACHINE_DMA_MODE)); SET_SBIC_cmd_phase (regs, 0x42); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); return; *************** printf("generic err\n"); *** 2521,2528 **** case SBIC_CSR_SDP: /* save data pointers. */ tgt->transient_state.script = sbic_script_temp_disconn; ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI | SBIC_CTL_IDI ! /* | SBIC_CTL_HSP*/ | SBIC_MACHINE_DMA_MODE)); WAIT_CIP (regs); SET_SBIC_cmd (regs, SBIC_CMD_CLR_ACK); return; --- 2544,2552 ---- case SBIC_CSR_SDP: /* save data pointers. */ tgt->transient_state.script = sbic_script_temp_disconn; ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI ! | SBIC_CTL_IDI /*| SBIC_CTL_HSP*/ ! | SBIC_MACHINE_DMA_MODE)); WAIT_CIP (regs); SET_SBIC_cmd (regs, SBIC_CMD_CLR_ACK); return; *************** printf("generic err\n"); *** 2532,2538 **** case SBIC_CSR_XFR_PAUSED_ATN: case SBIC_CSR_RSLT_AM: default: ! printf ("SBIC phase %x, ignoring (probably should anyway;-))\n", csr); return; } /* never reached */ --- 2556,2563 ---- case SBIC_CSR_XFR_PAUSED_ATN: case SBIC_CSR_RSLT_AM: default: ! printf ("SBIC phase %x, ignoring (probably should anyway;-))\n", ! csr); return; } /* never reached */ *************** printf("generic err\n"); *** 2568,2575 **** case SBIC_CSR_MIS_1 | SCSI_PHASE_DATAI: case SBIC_CSR_MIS_1 | SCSI_PHASE_DATAO: /* those happen usually after reconnects */ ! if (sbic->script->condition.csr == (SBIC_CSR_XFERRED|SCSI_PHASE_DATAI) ! || sbic->script->condition.csr == (SBIC_CSR_XFERRED|SCSI_PHASE_DATAO)) { if (sbic->script->action (sbic, csr, pha)) sbic->script++; --- 2593,2602 ---- case SBIC_CSR_MIS_1 | SCSI_PHASE_DATAI: case SBIC_CSR_MIS_1 | SCSI_PHASE_DATAO: /* those happen usually after reconnects */ ! if ((sbic->script->condition.csr ! == (SBIC_CSR_XFERRED | SCSI_PHASE_DATAI)) ! || (sbic->script->condition.csr ! == (SBIC_CSR_XFERRED | SCSI_PHASE_DATAO))) { if (sbic->script->action (sbic, csr, pha)) sbic->script++; *************** printf("generic err\n"); *** 2581,2587 **** case SBIC_CSR_MIS_1 | SCSI_PHASE_STATUS: /* this error occurs if a too large size was given for a certain ! command. For example size 255 for an inquiry command using fewer bytes */ SBIC_TC_GET (regs, count); /* the sbic contains the number of bytes transferred in the TC */ if (sbic->state & SBIC_STATE_DMA_IN) --- 2608,2615 ---- case SBIC_CSR_MIS_1 | SCSI_PHASE_STATUS: /* this error occurs if a too large size was given for a certain ! command. For example size 255 for an inquiry command using fewer ! bytes */ SBIC_TC_GET (regs, count); /* the sbic contains the number of bytes transferred in the TC */ if (sbic->state & SBIC_STATE_DMA_IN) *************** printf("generic err\n"); *** 2589,2595 **** else tgt->transient_state.out_count -= count; SBIC_TC_PUT (regs, 0); ! if (sbic->script->condition.csr == (SBIC_CSR_XFERRED|SCSI_PHASE_STATUS)) { if (sbic->script->action (sbic, csr, pha)) sbic->script++; --- 2617,2624 ---- else tgt->transient_state.out_count -= count; SBIC_TC_PUT (regs, 0); ! if (sbic->script->condition.csr ! == (SBIC_CSR_XFERRED | SCSI_PHASE_STATUS)) { if (sbic->script->action (sbic, csr, pha)) sbic->script++; *************** printf("generic err\n"); *** 2596,2603 **** } else { ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI /*| SBIC_CTL_IDI*/ ! /* | SBIC_CTL_HSP*/ | SBIC_MACHINE_DMA_MODE)); SET_SBIC_cmd_phase (regs, 0x46); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); } --- 2625,2633 ---- } else { ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI ! /*| SBIC_CTL_IDI*//*| SBIC_CTL_HSP*/ ! | SBIC_MACHINE_DMA_MODE)); SET_SBIC_cmd_phase (regs, 0x46); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); } *************** printf("generic err\n"); *** 2662,2668 **** tgt->flags &= ~TGT_TRY_SYNCH; sbic->done = SCSI_RET_RETRY; /* Tell DMA engine we are done */ ! (*sbic->dma_ops->end_xfer)(sbic->dma_state, tgt, tgt->transient_state.in_count); sbic_end (sbic, csr, pha); return; } --- 2692,2699 ---- tgt->flags &= ~TGT_TRY_SYNCH; sbic->done = SCSI_RET_RETRY; /* Tell DMA engine we are done */ ! (*sbic->dma_ops->end_xfer)(sbic->dma_state, tgt, ! tgt->transient_state.in_count); sbic_end (sbic, csr, pha); return; } *************** printf("generic err\n"); *** 2678,2684 **** case SBIC_CSR_MIS_2 | SCSI_PHASE_STATUS: /* this error occurs if a too large size was given for a certain ! command. For example size 255 for an inquiry command using fewer bytes */ SBIC_TC_GET (regs, count); /* the sbic contains the number of bytes transferred in the TC */ if (sbic->state & SBIC_STATE_DMA_IN) --- 2709,2716 ---- case SBIC_CSR_MIS_2 | SCSI_PHASE_STATUS: /* this error occurs if a too large size was given for a certain ! command. For example size 255 for an inquiry command using fewer ! bytes */ SBIC_TC_GET (regs, count); /* the sbic contains the number of bytes transferred in the TC */ if (sbic->state & SBIC_STATE_DMA_IN) *************** printf("generic err\n"); *** 2686,2693 **** else tgt->transient_state.out_count -= count; SBIC_TC_PUT (regs, 0); ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI /*| SBIC_CTL_IDI*/ ! /* | SBIC_CTL_HSP*/ | SBIC_MACHINE_DMA_MODE)); SET_SBIC_cmd_phase (regs, 0x46); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); return; --- 2718,2726 ---- else tgt->transient_state.out_count -= count; SBIC_TC_PUT (regs, 0); ! SET_SBIC_control (regs, (/*SBIC_CTL_HHP | */ SBIC_CTL_EDI ! /*| SBIC_CTL_IDI*//*| SBIC_CTL_HSP*/ ! | SBIC_MACHINE_DMA_MODE)); SET_SBIC_cmd_phase (regs, 0x46); SET_SBIC_cmd (regs, SBIC_CMD_SEL_ATN_XFER); return; *************** printf("generic err\n"); *** 2709,2715 **** case SBIC_CSR_MIS_2 | SCSI_PHASE_CMD: /* in that case, we sent a non-simple command without identify message. Check, and increment the script */ ! if (sbic->script->condition.csr == (SBIC_CSR_MIS_2|SCSI_PHASE_MSG_OUT)) { sbic->script++; if (sbic->script->action (sbic, csr, pha)) --- 2742,2749 ---- case SBIC_CSR_MIS_2 | SCSI_PHASE_CMD: /* in that case, we sent a non-simple command without identify message. Check, and increment the script */ ! if (sbic->script->condition.csr ! == (SBIC_CSR_MIS_2 | SCSI_PHASE_MSG_OUT)) { sbic->script++; if (sbic->script->action (sbic, csr, pha)) *************** get_outa_here (sbic, tgt) *** 2743,2750 **** regs = sbic->regs; #define DUMP_THEM(regs) \ ! GET_SBIC_asr(regs, asr); GET_SBIC_csr(regs, csr); GET_SBIC_cmd_phase(regs, pha); \ ! printf ("asr = $%02lx, csr = $%02lx, pha = $%02lx\n", asr, csr, pha); for (;;) { --- 2777,2791 ---- regs = sbic->regs; #define DUMP_THEM(regs) \ ! do \ ! { \ ! GET_SBIC_asr(regs, asr); \ ! GET_SBIC_csr(regs, csr); \ ! GET_SBIC_cmd_phase(regs, pha); \ ! printf ("asr = $%02lx, csr = $%02lx, pha = $%02lx\n", \ ! asr, csr, pha); \ ! } \ ! while (0) for (;;) { *************** sbic_err_disconn(sbic, csr, pha) *** 2777,2946 **** register sbic_softc_t sbic; register unsigned char csr, pha; { ! register sbic_padded_regmap_t *regs; ! register target_info_t *tgt; ! register int xferred, offset; ! int count; ! boolean_t callback = FALSE; ! ! #if 0 ! printf("discon err\n"); #endif ! ! LOG(0x16,"err_disconn"); ! ! regs = sbic->regs; ! tgt = sbic->active_target; ! /* other drivers differentiate between a disconnect in the ! status phase, and a disconnect in one of the data phases. ! However, with this chip we should only get *intermediate* ! disconnects in here, so don't handle status stuff here. */ #if dont_try_to_be_smart ! SBIC_TC_GET (regs, count); ! ! if (sbic->state & SBIC_STATE_DMA_IN) ! { ! if (sbic->in_count) ! { ! xferred = sbic->in_count - count; ! if (xferred <= 0) ! panic ("sbic_err_disconn-1"); ! ! tgt->transient_state.in_count -= xferred; ! ! callback = ((*sbic->dma_ops->disconn_3) ! (sbic->dma_state, tgt, xferred)); ! } ! } ! else ! { ! if (sbic->out_count) ! { ! xferred = sbic->out_count - count; ! if (xferred <= 0) ! panic ("sbic_err_disconn-2"); ! ! tgt->transient_state.out_count -= xferred; ! ! callback = ((*sbic->dma_ops->disconn_1) ! (sbic->dma_state, tgt, xferred)); ! } ! } ! ! #else ! /* original (53C93-code) */ ! switch (SCSI_PHASE (sbic->script->condition.csr)) { ! case SCSI_PHASE_DATAO: ! LOG(0x1b,"+DATAO"); ! if (sbic->out_count) { ! register int xferred, offset; ! ! SBIC_TC_GET(regs,xferred); ! xferred = sbic->out_count - xferred; /* ok now */ ! tgt->transient_state.out_count -= xferred; ! if (!(tgt->transient_state.out_count > 0)) ! panic ("disco-1"); ! ! callback = (*sbic->dma_ops->disconn_1) ! (sbic->dma_state, tgt, xferred); ! ! } else { ! ! callback = (*sbic->dma_ops->disconn_2) ! (sbic->dma_state, tgt); ! ! } ! tgt->transient_state.script = sbic_script_restart_data_out; ! break; ! ! ! case SCSI_PHASE_DATAI: ! LOG(0x17,"+DATAI"); ! if (sbic->in_count) { ! register int offset, xferred; ! ! SBIC_TC_GET(regs,count); ! xferred = sbic->in_count - count; ! if (! (xferred > 0)) ! panic ("disco-2"); ! ! tgt->transient_state.in_count -= xferred; ! if (!(tgt->transient_state.in_count > 0)) ! panic ("disco-3"); ! ! callback = (*sbic->dma_ops->disconn_3) ! (sbic->dma_state, tgt, xferred); ! ! tgt->transient_state.script = sbic_script_restart_data_in; ! if (tgt->transient_state.in_count == 0) ! tgt->transient_state.script++; ! ! } ! tgt->transient_state.script = sbic->script; ! break; ! ! case SCSI_PHASE_STATUS: ! /* will have to restart dma */ ! SBIC_TC_GET(regs,count); ! if (sbic->state & SBIC_STATE_DMA_IN) { ! register int offset, xferred; ! ! LOG(0x1a,"+STATUS+R"); ! ! xferred = sbic->in_count - count; ! if (!(xferred > 0)) ! panic ("disco-4"); ! ! tgt->transient_state.in_count -= xferred; ! ! callback = (*sbic->dma_ops->disconn_4) ! (sbic->dma_state, tgt, xferred); ! ! tgt->transient_state.script = sbic_script_restart_data_in; ! if (tgt->transient_state.in_count == 0) ! tgt->transient_state.script++; ! ! } else { ! ! LOG(0x19,"+STATUS+W"); ! ! ! if ((count == 0) && (tgt->transient_state.out_count == sbic->out_count)) { ! /* all done */ ! tgt->transient_state.script = sbic->script; ! tgt->transient_state.out_count = 0; ! } else { ! register int xferred, offset; ! ! /* how much we xferred */ ! xferred = sbic->out_count - count; ! ! tgt->transient_state.out_count -= xferred; ! if (!(tgt->transient_state.out_count > 0)) ! panic ("disco-5"); ! ! callback = (*sbic->dma_ops->disconn_5) ! (sbic->dma_state,tgt,xferred); ! ! tgt->transient_state.script = sbic_script_restart_data_out; ! } ! sbic->out_count = 0; ! } ! break; ! default: ! printf ("disco: unknown phase %lx or %lx.. ", ! SCSI_PHASE (sbic->script->condition.csr), ! sbic->script->condition.csr); ! /* gimmeabreak(); */ ! return; ! } #endif /* better idea */ ! sbic_disconnected (sbic, csr, pha); if (callback) ! (*sbic->dma_ops->disconn_callback)(sbic->dma_state, tgt); return TRUE; } --- 2818,2991 ---- register sbic_softc_t sbic; register unsigned char csr, pha; { ! register sbic_padded_regmap_t *regs; ! register target_info_t *tgt; ! register int xferred, offset; ! int count; ! boolean_t callback = FALSE; ! ! #if SCSI_DEBUG ! printf("discon err\n"); #endif ! ! LOG(0x16,"err_disconn"); ! regs = sbic->regs; ! tgt = sbic->active_target; ! ! /* other drivers differentiate between a disconnect in the ! status phase, and a disconnect in one of the data phases. ! However, with this chip we should only get *intermediate* ! disconnects in here, so don't handle status stuff here. */ #if dont_try_to_be_smart ! SBIC_TC_GET (regs, count); ! ! if (sbic->state & SBIC_STATE_DMA_IN) ! { ! if (sbic->in_count) ! { ! xferred = sbic->in_count - count; ! if (xferred <= 0) ! panic ("sbic_err_disconn-1"); ! ! tgt->transient_state.in_count -= xferred; ! ! callback = (*sbic->dma_ops->disconn_3) (sbic->dma_state, tgt, ! xferred); ! } ! } ! else ! { ! if (sbic->out_count) ! { ! xferred = sbic->out_count - count; ! if (xferred <= 0) ! panic ("sbic_err_disconn-2"); ! ! tgt->transient_state.out_count -= xferred; ! ! callback = (*sbic->dma_ops->disconn_1) (sbic->dma_state, tgt, ! xferred); ! } ! } ! ! #else ! /* original (53C93-code) */ ! switch (SCSI_PHASE (sbic->script->condition.csr)) ! { ! case SCSI_PHASE_DATAO: ! LOG(0x1b,"+DATAO"); ! if (sbic->out_count) ! { ! register int xferred, offset; ! ! SBIC_TC_GET(regs,xferred); ! xferred = sbic->out_count - xferred; /* ok now */ ! tgt->transient_state.out_count -= xferred; ! if (!(tgt->transient_state.out_count > 0)) ! panic ("disco-1"); ! ! callback = (*sbic->dma_ops->disconn_1) (sbic->dma_state, tgt, ! xferred); ! } ! else ! callback = (*sbic->dma_ops->disconn_2) (sbic->dma_state, tgt); ! tgt->transient_state.script = sbic_script_restart_data_out; ! break; ! ! ! case SCSI_PHASE_DATAI: ! LOG(0x17,"+DATAI"); ! if (sbic->in_count) ! { ! register int offset, xferred; ! ! SBIC_TC_GET(regs,count); ! xferred = sbic->in_count - count; ! if (! (xferred > 0)) ! panic ("disco-2"); ! ! tgt->transient_state.in_count -= xferred; ! if (!(tgt->transient_state.in_count > 0)) ! panic ("disco-3"); ! ! callback = (*sbic->dma_ops->disconn_3) (sbic->dma_state, tgt, ! xferred); ! ! tgt->transient_state.script = sbic_script_restart_data_in; ! if (tgt->transient_state.in_count == 0) ! tgt->transient_state.script++; ! ! } ! tgt->transient_state.script = sbic->script; ! break; ! ! case SCSI_PHASE_STATUS: ! /* will have to restart dma */ ! SBIC_TC_GET(regs,count); ! if (sbic->state & SBIC_STATE_DMA_IN) ! { ! register int offset, xferred; ! ! LOG(0x1a,"+STATUS+R"); ! ! xferred = sbic->in_count - count; ! if (!(xferred > 0)) ! panic ("disco-4"); ! ! tgt->transient_state.in_count -= xferred; ! ! callback = (*sbic->dma_ops->disconn_4) (sbic->dma_state, tgt, ! xferred); ! ! tgt->transient_state.script = sbic_script_restart_data_in; ! if (tgt->transient_state.in_count == 0) ! tgt->transient_state.script++; ! ! } ! else ! { ! LOG(0x19,"+STATUS+W"); ! ! if ((count == 0) ! && (tgt->transient_state.out_count == sbic->out_count)) ! { ! /* all done */ ! tgt->transient_state.script = sbic->script; ! tgt->transient_state.out_count = 0; ! } ! else ! { ! register int xferred, offset; ! ! /* how much we xferred */ ! xferred = sbic->out_count - count; ! ! tgt->transient_state.out_count -= xferred; ! if (!(tgt->transient_state.out_count > 0)) ! panic ("disco-5"); ! ! callback = (*sbic->dma_ops->disconn_5) (sbic->dma_state, tgt, ! xferred); ! ! tgt->transient_state.script = sbic_script_restart_data_out; ! } ! sbic->out_count = 0; ! } ! break; ! default: ! printf ("disco: unknown phase %lx or %lx.. ", ! SCSI_PHASE (sbic->script->condition.csr), ! sbic->script->condition.csr); ! /* gimmeabreak(); */ ! return; ! } #endif /* better idea */ ! sbic_disconnected (sbic, csr, pha); if (callback) ! (*sbic->dma_ops->disconn_callback) (sbic->dma_state, tgt); return TRUE; } *************** printf("discon err\n"); *** 2954,2988 **** sbic_reset_scsibus(sbic) register sbic_softc_t sbic; { ! register target_info_t *tgt = sbic->active_target; ! register sbic_padded_regmap_t *regs = sbic->regs; ! if (scsi_debug && tgt) { ! int dmalen; ! SBIC_TC_GET(sbic->regs,dmalen); ! printf("Target %d was active, cmd x%x in x%x out x%x Sin x%x Sou x%x dmalen x%x\n", ! tgt->target_id, tgt->cur_cmd, ! tgt->transient_state.in_count, tgt->transient_state.out_count, ! sbic->in_count, sbic->out_count, ! dmalen); ! } ! #if 0 ! ir = regs->sbic_intr; ! if ((ir & SBIC_INT_RESEL) && (SCSI_PHASE(regs->sbic_csr) == SCSI_PHASE_MSG_IN)) { ! /* getting it out of the woods is a bit tricky */ ! int s = splbio(); ! ! (void) sbic_reconnect(sbic, regs->sbic_csr, ir); ! sbic_wait(regs, SBIC_CSR_INT); ! ir = regs->sbic_intr; ! regs->sbic_cmd = SBIC_CMD_MSG_ACPT; ! splx(s); ! } else #endif ! { ! SET_SBIC_cmd (regs, SBIC_CMD_RESET); ! delay(35); ! } } #endif NSBIC > 0 --- 2999,3038 ---- sbic_reset_scsibus(sbic) register sbic_softc_t sbic; { ! register target_info_t *tgt = sbic->active_target; ! register sbic_padded_regmap_t *regs = sbic->regs; ! if (scsi_debug && tgt) ! { ! int dmalen; ! SBIC_TC_GET(sbic->regs,dmalen); ! printf ("Target %d was active, cmd x%x in x%x out x%x Sin x%x " ! "Sou x%x dmalen x%x\n", ! tgt->target_id, tgt->cur_cmd, ! tgt->transient_state.in_count, tgt->transient_state.out_count, ! sbic->in_count, sbic->out_count, ! dmalen); ! } ! #if 0 ! ir = regs->sbic_intr; ! if ((ir & SBIC_INT_RESEL) ! && (SCSI_PHASE(regs->sbic_csr) == SCSI_PHASE_MSG_IN)) ! { ! /* getting it out of the woods is a bit tricky */ ! int s = splbio(); ! ! (void) sbic_reconnect(sbic, regs->sbic_csr, ir); ! sbic_wait(regs, SBIC_CSR_INT); ! ir = regs->sbic_intr; ! regs->sbic_cmd = SBIC_CMD_MSG_ACPT; ! splx(s); ! } ! else #endif ! { ! SET_SBIC_cmd (regs, SBIC_CMD_RESET); ! delay(35); ! } } #endif NSBIC > 0 *** /tmp/rz_disk.c Tue May 18 01:43:17 1993 --- ./kernel/scsi/rz_disk.c Tue May 18 01:09:58 1993 *************** void scdisk_start(tgt, done) *** 522,528 **** ior->io_op = ior->io_temporary; sns = (scsi_sense_data_t *)tgt->cmd_ptr; ! if (sns->u.xtended.addr_valid) blockno = sns->u.xtended.info0 << 24 | sns->u.xtended.info1 << 16 | sns->u.xtended.info2 << 8 | --- 522,528 ---- ior->io_op = ior->io_temporary; sns = (scsi_sense_data_t *)tgt->cmd_ptr; ! if (sns->addr_valid) blockno = sns->u.xtended.info0 << 24 | sns->u.xtended.info1 << 16 | sns->u.xtended.info2 << 8 | *************** void scdisk_start(tgt, done) *** 557,563 **** * event, the queue of requests is effectively frozen. */ if (ior->io_error && ! ((sns->u.xtended.error_class == SCSI_SNS_XTENDED_SENSE_DATA) && ((sns->u.xtended.sense_key == SCSI_SNS_HW_ERR) || (sns->u.xtended.sense_key == SCSI_SNS_MEDIUM_ERR))) && scdisk_bad_block_repl(tgt, blockno)) --- 557,563 ---- * event, the queue of requests is effectively frozen. */ if (ior->io_error && ! ((sns->error_class == SCSI_SNS_XTENDED_SENSE_DATA) && ((sns->u.xtended.sense_key == SCSI_SNS_HW_ERR) || (sns->u.xtended.sense_key == SCSI_SNS_MEDIUM_ERR))) && scdisk_bad_block_repl(tgt, blockno)) *** /tmp/scsi.c Tue May 18 01:43:24 1993 --- ./kernel/scsi/scsi.c Tue May 18 01:11:27 1993 *************** int scsi_slave( ui, reg) *** 302,311 **** scsi_softc_t *sc = scsi_softc[(unsigned char)ui->ctlr]; target_info_t *tgt = sc->target[(unsigned char)ui->slave]; scsi_inquiry_data_t *inq; ! #ifdef SCSI2 int scsi_std; ! #endif ! int ptype, s; if (!tgt || !(tgt->flags & TGT_ALIVE)) return 0; --- 302,312 ---- scsi_softc_t *sc = scsi_softc[(unsigned char)ui->ctlr]; target_info_t *tgt = sc->target[(unsigned char)ui->slave]; scsi_inquiry_data_t *inq; ! /*#ifdef SCSI2*/ int scsi_std; ! /*#endif*/ ! int ptype, s, ret; ! unsigned char buf[255]; if (!tgt || !(tgt->flags & TGT_ALIVE)) return 0; *************** int scsi_slave( ui, reg) *** 329,334 **** --- 330,341 ---- if (BGET(scsi_no_synchronous_xfer,(unsigned char)sc->masterno,tgt->target_id)) tgt->flags |= TGT_DID_SYNCH; + printf ("scsi_slave: %d\n", ui->slave); + + + /* do sync-handshake without transfer of data */ + /* scsi_test_unit_ready (tgt, 0);*/ + /* * Ok, it is time to see what type of device this is, * send an INQUIRY cmd and wait till done. *************** int scsi_slave( ui, reg) *** 336,342 **** */ scsi_inquiry(tgt, SCSI_INQ_STD_DATA); ! inq = (scsi_inquiry_data_t*)tgt->cmd_ptr; ptype = (inq->periph_type) & 0x1f; /* scsi2 safe */ switch (ptype) { --- 343,372 ---- */ scsi_inquiry(tgt, SCSI_INQ_STD_DATA); ! /* save the obtained data */ ! bcopy (tgt->cmd_ptr, buf, sizeof (buf)); ! ! /* this is a simplified protocol (without actually looking at the ! result values.. */ ! ! ret = scsi_test_unit_ready (tgt, 0); ! if (ret == SCSI_RET_NEED_SENSE) ! { ! printf ("need sense #1\n"); ! scsi_request_sense(tgt, 0, 0); ! ! ret = scsi_test_unit_ready (tgt, 0); ! if (ret == SCSI_RET_NEED_SENSE) ! { ! printf ("need sense #2\n"); ! scsi_request_sense(tgt, 0, 0); ! ! ret = scsi_test_unit_ready (tgt, 0); ! printf ("ret after sense #2, %d\n", ret); ! } ! } ! ! inq = (scsi_inquiry_data_t*) buf; ptype = (inq->periph_type) & 0x1f; /* scsi2 safe */ switch (ptype) { *************** int scsi_slave( ui, reg) *** 380,386 **** scsi_print_inquiry((scsi2_inquiry_data_t*)inq, SCSI_INQ_STD_DATA, 0); ! #ifdef SCSI2 /* * The above says if it currently behaves as a scsi2, * however scsi1 might just be the default setting. --- 410,416 ---- scsi_print_inquiry((scsi2_inquiry_data_t*)inq, SCSI_INQ_STD_DATA, 0); ! /*#ifdef SCSI2*/ /* * The above says if it currently behaves as a scsi2, * however scsi1 might just be the default setting. *************** int scsi_slave( ui, reg) *** 387,393 **** * The spec say that even if in scsi1 mode the target * should answer to the full scsi2 inquiry spec. */ ! scsi_std = (inq->ansi == 2 || inq->response_fmt == 2) ? 2 : 1; #if nosey if (scsi_std == 2) { unsigned char supp_pages[256], i; --- 417,423 ---- * The spec say that even if in scsi1 mode the target * should answer to the full scsi2 inquiry spec. */ ! scsi_std = (inq->ansi == 2 /*|| inq->response_fmt == 2*/) ? 2 : 1; #if nosey if (scsi_std == 2) { unsigned char supp_pages[256], i; *************** int scsi_slave( ui, reg) *** 405,410 **** --- 435,441 ---- } #endif nosey + #if 0 if (scsi_std == 2) { scsi2_impl_opdef_page_t *impl; int i; *************** int scsi_slave( ui, reg) *** 419,425 **** break; } } ! #endif SCSI2 splx(s); out: --- 450,457 ---- break; } } ! #endif ! /*#endif SCSI2*/ splx(s); out: *** /tmp/scsi.h Tue May 18 01:43:30 1993 --- ./kernel/scsi/scsi.h Tue May 18 01:15:40 1993 *************** typedef struct { *** 502,514 **** #define SCSI_SNS_RESERVED 0xf typedef struct { union { struct { BITFIELD_3( unsigned char, ! error_code : 4, ! error_class : 3, ! addr_valid : 1); ! # define SCSI_SNS_XTENDED_SENSE_DATA 0x7 /* e.g. error_class=7 */ BITFIELD_2(unsigned char, lba_msb : 5, vuqe : 3); --- 502,514 ---- #define SCSI_SNS_RESERVED 0xf typedef struct { + # define SCSI_SNS_XTENDED_SENSE_DATA 0x7 /* e.g. error_class=7 */ union { struct { BITFIELD_3( unsigned char, ! _error_code : 4, ! _error_class : 3, ! _addr_valid : 1); BITFIELD_2(unsigned char, lba_msb : 5, vuqe : 3); *************** typedef struct { *** 517,525 **** } non_xtnded; struct { BITFIELD_3( unsigned char, ! error_code : 4, ! error_class : 3, ! addr_valid : 1); unsigned char segment_number; BITFIELD_5(unsigned char, sense_key : 4, --- 517,525 ---- } non_xtnded; struct { BITFIELD_3( unsigned char, ! _error_code : 4, ! _error_class : 3, ! _addr_valid : 1); unsigned char segment_number; BITFIELD_5(unsigned char, sense_key : 4, *************** typedef struct { *** 536,541 **** --- 536,544 ---- } xtended; } u; } scsi_sense_data_t; + #define error_code u.non_xtnded._error_code + #define error_class u.non_xtnded._error_class + #define addr_valid u.non_xtnded._addr_valid /* mode select params */ *** /tmp/rz_labels.c Tue May 18 01:43:36 1993 --- ./kernel/scsi/rz_labels.c Tue May 18 01:17:42 1993 *************** *** 26,31 **** --- 26,35 ---- /* * HISTORY * $Log$ + * Revision 2.8 93/05/15 18:58:00 mlh + * Support for AmigaDOS RigidDiskBlocks + * [93/05/15 18:58:00 mlh] + * * Revision 2.7 92/08/03 17:53:58 jfriedl * removed silly prototypes * [92/08/02 jfriedl] *************** rz_bios_label(tgt, label, ior) *** 188,193 **** --- 192,284 ---- } /* + * Find and convert from an AmigaDOS label (RigidDiskBlock) to BSD + */ + + inline long rz_amiga_checksum (buf, len) + long *buf; + long len; + { + long sum = 0; + while (len--) + sum += *buf++; + return (sum); + } + + boolean_t + rz_amiga_label(tgt, label, ior) + target_info_t *tgt; + struct disklabel *label; + io_req_t ior; + { + /* here look for an AmigaDOS label */ + register struct amiga_rdb *rdb; + register struct amiga_part *pb; + char *data; + int i; + int block; + char dostype[5]; + + ior->io_count = DEV_BSIZE; + ior->io_op = IO_READ; + tgt->ior = ior; + for (i = 0; i < RDB_LOCATION_LIMIT; i++) { + scdisk_read( tgt, i, ior); + iowait(ior); + data = (char *)ior->io_data; + rdb = (struct amiga_rdb*) data; + if (rdb->rdb_ID == IDNAME_RIGIDDISK && + rz_amiga_checksum ((long *)data, rdb->rdb_SummedLongs) == 0) { + if (scsi_debug) + printf("{Found AmigaDOS RigidDiskBlock}"); + /* fill in BSD label from each Partition Block */ + label->d_partitions[0].p_size = rdb->rdb_Cylinders * + rdb->rdb_Sectors * rdb->rdb_Heads; + label->d_partitions[0].p_offset = 0; + if (scsi_debug) + printf ("{partition 0 size = %d}\n", + label->d_partitions[0].p_size); + i = 1; + block = rdb->rdb_PartitionList; + while (i < 8 && block != ~0) { + ior->io_count = DEV_BSIZE; + ior->io_op = IO_READ; + tgt->ior = ior; + scdisk_read(tgt, block, ior); + iowait(ior); + data = (char *)ior->io_data; + pb = (struct amiga_part*) data; + if (pb->pb_ID != IDNAME_PARTITION || + rz_amiga_checksum ((long *) data, pb->pb_SummedLongs) != 0) + break; + label->d_partitions[i].p_size = + (pb->pb_Environment[DE_UPPERCYL] - pb->pb_Environment[DE_LOWCYL] + 1) * + pb->pb_Environment[DE_NUMHEADS] * + pb->pb_Environment[DE_BLKSPERTRACK]; + label->d_partitions[i].p_offset = + pb->pb_Environment[DE_LOWCYL] * + pb->pb_Environment[DE_NUMHEADS] * + pb->pb_Environment[DE_BLKSPERTRACK]; + strncpy (dostype, &pb->pb_Environment[DE_DOSTYPE], 4); + dostype[4] = 0; + if (dostype[3] <= 9) + dostype[3] += '0'; + if (scsi_debug) + printf ("Partition %d name=%s offset=%d size=%d type=%s\n", + i, pb->pb_DriveName+1, + label->d_partitions[i].p_offset, + label->d_partitions[i].p_size, dostype); + block = pb->pb_Next; + ++i; + } + label->d_npartitions = i; + return TRUE; + } + } + return FALSE; + } + + /* * Try all of the above */ boolean_t rz_vendor_label(tgt, label, ior) *************** boolean_t rz_vendor_label(tgt, label, io *** 203,208 **** --- 294,300 ---- if (rz_dec_label( tgt, label, ior)) return TRUE; if (rz_bios_label( tgt, label, ior)) return TRUE; if (rz_omron_label( tgt, label, ior)) return TRUE; + if (rz_amiga_label( tgt, label, ior)) return TRUE; return FALSE; } *** /tmp/ChangeLog Tue May 18 01:43:41 1993 --- ./ChangeLog Tue May 18 01:33:50 1993 *************** *** 0 **** --- 1,162 ---- + Tue May 18 01:33:15 1993 Niklas Hallqvist (niklas@appli.se) + + * SIM.doc: Changed to the 1.72 version + + * kernel/motorola/m68k/pmap.h (mach/machine.h): Added include + of this file. + + * kernel/motorola/m68k/pcb.c (switch_context): Don't lose the + CONTINUATION. Fixed a type incompatibility. Removed a + permanent breakpoint. Added a "NOTREACHED" comment. + (thread_setstatus): Fixed a type incompatibility. + + * kernel/motorola/m68k/psl.h: New stub file to be filled in + later. + + * kernel/motorola/m68k/machparam.h (SPL_DEBUG): A set of extern + spl* declarations whose deinitions can be found in + kernel/amiga/spl_debug.c A debugger can make use of these. + (MASKED_SPL): All spl* macros/inline funtions were fixed so + they would not be subjuct to optimization by the compiler. + Furthermore, they were somewhat hand-optimized. + (!MASKED_SPL): An experimental set of spl* macros for the dare + devil. Needs much work. If you don't know what these are for, + don't bother... + + * kernel/motorola/m68k/mmu.h (M68040): Added support for the + 68040 MMU. + + * kernel/motorola/m68k/pcb.h (fp_{save,restore}): Changed beq + opcode to jeq. + + * kernel/motorola/m68k/pmap.c (M68040): Added support for the + 68040 MMU. + + * kernel/amiga/amiga_dma.c (BUFFERED_DMA): Added support for + DMA into a dedicated (vm-transparent) buffer. + + * kernel/amiga/takeover.asm: Added 68040 support. Made dc.w + into real macros. + + * kernel/amiga/init.c (version): bumped version nr to 0.009. + (startrtclock,resettodr): Removed. + (delay): Added a short loop for fast 68040 processors. + + * kernel/amiga/kd.c (cons_buf). A circular buffer for handling + multiplexed uart/kd input. + (kd_putc): Run at spltty. + (kdintr): Put the character input into the circular buffer. + Removed some strange delay loop. + (kd_cnpollc): ifdef'd away. + + * kernel/amiga/uart.c (cons_buf): Added extern declaration. + (utrint): Put the character input into the circular buffer. + (ut_cnputc): Don't output the special EOF value. Inhibit + transmit interrupts while transmitting a character. Changed + flow control to use the circular buffer. + (ut_cnpollc): ifdef'd away. + + * kernel/amiga/kd.h (kd_cnpollc): Removed decl. + (kd_tty): Added extern declaration. + + * kernel/amiga/uart.h (ut_cnpollc): Removed decl. + (uart_tty): Added extern declaration. + + * kernel/amiga/interrupt.c (utxint,kdintr): Decls moved to + beginning of file. Added 'if 0'd support for protecting + against nested SCSI interrupts, something which really + should be impossible, yet it has been observed. I think + the problem were spl-related and now fixed. + (level_6_int_c): Don't disable, just clear the interrupt + when a spurious interrupt is seen. + + * kernel/amiga/cons.c: Added support for multiplexing uart/kd + input via a circular buffer. + + * kernel/amiga/patchSIM-009.c: New utility to patch the SIM + from KM 0.008 to allow the full 32-bit address range. + + * kernel/amiga/machparam.h (spl{clock,sched}): Raised the spl + level due to the moving of the clock to interrupt level 6. + + * kernel/amiga/autoconf.c (machine_init): Added INTF_RBF + interrupts to the default set of accepted interrupts. + Also added a printf before the call to configure_bus_master. + + * kernel/amiga/cia_clock.c: New file dealing with the + initialization of the cia timer which now generates the + KludgeMach clocktick. + + * kernel/amiga/rdb.h: New file containing the declarations + needed to make use of the RDB (Rigid Disk Block) standard on + Amiga harddisks. + + * kernel/amiga/spl_debug: New file containing function + definitions dealing with spl-settings. These are good for + debugging purposes. + + * kernel/amiga/a3000_dma.c: Removed. + + * kernel/amiga/mach_param.h (HZ): Only define if not already + defined. + + * kernel/amiga/conf.c (dev_name_list): Add the "sd" device + even if GVP11 or A2091. + + * kernel/device/ds_routines (splio): Defined to be splsched + again. + (iowait): Removed funny printf. + + * kernel/kern/bootstrap.c (bootstrap_create): Added several + commands including a "help". + (my_format): An untested SCSI format routine. + (read_test): Greatly enhanced SCSI read test with partition + support and timing to mention but a few additions. + + * kernel/Makefile: Cleaned up the CFLAGS and added some + comments on when to choose what options. + + * kernel/scsi/scsi_disk.c (scdisk_mode_select): I don't + really know what the fixes here does, but I trust Wild's + judgement completely. + + * kernel/scsi/rz_labels.h (machine/rdb.h): Include this file. + + * kernel/scsi/scsi_alldevs.c (scsi_go_and_wait): Removed a + shortcircuit of an if, there for some obscure reason unclear + to me. + (scsi_{check,print}_sense_data): Use user-friendly union + member macros instead of fully qualified member selectors. + (scsi_change_definition): Quick hack for sending of this + SCSI command. + + * kernel/scsi/adapters/scsi_33C93.h (sbic_{read,write}_reg): + Use the do { .. } while (0) ideom. + + * kernel/scsi/adapters/scsi_33C93_hdw.c: Changed indentation + in order to make more lines shorter than 80 characters. + Added some missing GVP11 code. + (sbic_intr): Removed special kludge dealing with nested + interrupts. If such interrupts come back, try the code in + kernel/amiga/interrupt.c instead. + (sbic_probed): Removed, use sbic_softc != NULL instead. + (SCSI_DEBUG): Put several printfs formerly 'if 0'd under + this compile time controlled preprocessor symbols control. + + * kernel/scsi/rz_disk.c (scdisk_start): Use user-friendly union + member macros instead of fully qualified member selectors. + + * kernel/scsi/scsi.c (scsi_slave): Added calls to + scsi_test_unit_ready in order to do sync handshake. + Changed some SCSI2-conditionalized code to be generic. + + * kernel/scsi/scsi.h (error_code, error_class, addr_valid): + New userfriendly macros to reach far inside a nested struct. + + * kernel/scsi/rz_labels.c: Added Amiga RDB support. + + * ChangeLog: This file. + + * NEWS-009: What is the KludgeMach-0.009 release? + + * README-009: Important notices for KludgeMach-0.009. *** /tmp/NEWS-009 Tue May 18 01:43:46 1993 --- ./NEWS-009 Mon May 17 23:27:59 1993 *************** *** 0 **** --- 1,11 ---- + Basically 0.009 is a bugfix release with some interesting new features. + + I 68040 support (contributed by Michael L. Hitch) + II RDB support (also from Michael) + III DMA to a dedicated (vm-transparent) buffer (Michael's work...) + IV SPL debugging (Markus Wild did this) + + I like to thank Leonard Norrgard as well, for his patch collection. + + Niklas Hallqvist + niklas@appli.se *** /tmp/README-009 Tue May 18 01:43:51 1993 --- ./README-009 Mon May 17 23:20:06 1993 *************** *** 0 **** --- 1,37 ---- + Important notice before building KludgeMach 0.009: + + If you have got this revision as a patch rather than a full archive + you should patch your old SIM binary. This has to be done in order + to make SIM accept the full 32-bit address space (as we use virtual + memory we can choose almost any memory configuration during the kernel + development phase, thus it's bad to make SIM suppose anything about it). + There are two ways to patch the binary, either get the separate archive + sim172.lha (the preferred way) and use SIMconfig according to the docs + therein, or use the following commands (in pdksh, and assuming your + assignments are setup according to the original README): + + cd /mk/amiga + gcc -o patchSIM-009 patchSIM-009.c + cp SIM SIM-008 + patchSIM-009 + + If this fails, check that you had enough memory for the compilation, + and of course enough stack (~150 is OK). + + Note that if you want to configure SIM for 68040 or for any national + keyboard you *definitely* should get sim172.lha and use SIMconfig. + + Well, if you got this package as a fullblown archive, the SIM contained + should already be patched for 68030-68020/68551 CPU memory at + 00000000-FFFFFFFE and a US keymap. If this isn't satisfactory, get + sim172.lha! + + Now, get on to edit mk:Makefile, there are several compile time options + to bet set for your personal system. After that is done just "make" + the kernel as usual. I use GNU make, but the dmake (not Dillon's) at + the site you got KludgeMach from is alright as well. + + Happy hacking... + + Niklas Hallqvist + niklas@appli.se