------------------------------------------------------------------------------- ## ## ###### ##### ###### ##### ###### ## ## ##### ## ## ## ## ## # ## ## ## # ## ## ## ## ## ####### ## ## ## ## ## ## ## ## ## ## ## ## # ## ## ## ###### ## ## ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ##### ## ## ##### ###### ##### ##### ------------------------------------------------------------------------------- PROJECT "MICRO BUG - SISTEMA GERENCIADOR DE MODULOS" COORD. RENATO DEGIOVANI - BRASIL - 1984 (C) ATI-EDITORA - "REVISTA MICRO SISTEMAS" ------------------------------------------------------------------------------- CONVERTED BY EINAR GATTONI SAUKAS - BRASIL - 1996 ------------------------------------------------------------------------------- =============================================================================== INTRODUCTION ============ The "MICRO BUG" is a complete development utility for ZX81 compatible machines (including the several brazilian clones TK82C, TK83, TK85, CP200, AS1000, etc). It is described as a "SGM" ("Sistema Gerenciador de Modulos": Modules Manager System) because it implements only a basic set of commands (for memory edition and program development) but its functionality can be easily extended implementing a loadable external "MO" ("Modulo Operacional": Operating Module). This project was produced by the development team of the brazilian magazine "Micro Sistemas" (coordenated by the editor Renato Degiovani) and published in the magazine issues of Abril to December in 1984. It had a great historical importance for brazilian users of Sinclair machines for two main reasons: 1. The magazine published the complete assembler source code of the system, including detailed comments and explanations about its internal structure and implementation, for 9 months (about 4 pages a month). Since it was the most important brazilian computer magazine at the time, it motivated a lot of brazilian ZX81 users to learn Z80 assembler programming and improved the quantity and quality of brazilian programmers. 2. The flexibility of the system provided a common base for the implementation of assembler utilities, as a consequence in the following years several (good) operating modules were produced by the magazine readers: DISASSEMBLER, ED-ART, TRACE, RENUMERGE, etc. =============================================================================== LOADING INSTRUCTIONS ==================== After loading MICRO BUG from tape, the SGM will be installed into memory, the presentation screen will appear and it will wait for a key. Then the system will execute a NEW to reserve the RAMTOP and it will be ready. To enter into the MICRO BUG, execute: RAND USR 31210 The commands "A" to "P" are implemented by the SGM system that is installed at the top 2K of the RAM (address from #783D to #7FFF). The commands "Q" and "R" are not available. The commands "S" to "Z" are available to be implemented by an MO that can be loaded in a reserved memory area of 2.5K of RAM (addresses from #6E00 to #77FF for the operating module, addresses from #7800 to #783C for "interface" informations). =============================================================================== COMMANDS ======== ------------------------------------------------------------------------------- "A $=D" or "A $=H" - Assign numeric base ------------------------------------------------------------------------------- The MICRO BUG interprets numbers as Hexadecimal values by default, all Decimal values must be preceded by '$'. The command A can be used to assign '$' to the Hexadecimal base (then numbers become interpreted as Decimal by default) and vice-versa. Error message "$=D OU $=H" if syntax error. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "B" - Return to BASIC ------------------------------------------------------------------------------- Exit to BASIC. Execute "RAND USR 31210" to restart MICRO BUG. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "C" - Load operating module ------------------------------------------------------------------------------- Load an operating module. If there was already another operating module, it is replaced by the new one. Loading an operating module does not affect BASIC programs. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "D [address]" - Display memory ------------------------------------------------------------------------------- Display a memory block: address and 8 consecutive bytes. Control keys: "K" (+) : forward SHIFT-S : print speed "J" (-) : backward SHIFT-E : address format (hex/dec) SPACE : break SHIFT-4 : byte format (hex/token) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "E line,size[,c]" - Create REM line ------------------------------------------------------------------------------- Create a REM line (containing "size" copies of char "c") to store assembler routines into the BASIC program. For example: "E 1,4,*" creates "1 REM ****". The default value for parameter "c" is SPACE. Error message "LINHA ILEGAL" if "line" > 9999, error "LINHA EXISTENTE" if line already exists. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "F start,end,c" - Fill block with char ------------------------------------------------------------------------------- Fill block from addresses "start" to "end" with char "c". ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "G start" - Execute machine language routine ------------------------------------------------------------------------------- Insert breakpoint if it is implemented (see commands "K" and "L"), load registers from register buffer (see commands "H" and "N"), call routine at address "start", store registers into register buffer, remove breakpoint. This command is useful to debug routines. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "H" - Print registers values ------------------------------------------------------------------------------- Print register values stored into register buffer. These values are updated automatically after command "G" or manually using command "N". ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "I start,end" - Save block to tape ------------------------------------------------------------------------------- Save to tape memory contents between addresses "start" and "end". Use SHIFT-F to select save speed (normal=300 bps, high=1600 bps), SPACE to break. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "J start,end" - Load block from tape ------------------------------------------------------------------------------- Load from tape to memory contents between addresses "start" and "end". Use SHIFT-F to select load speed (normal=300 bps, high=1600 bps), SPACE to break. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "K [address]" - Implement BREAKPOINT ------------------------------------------------------------------------------- Specify an address to insert a breakpoint. Command "G" will insert a breakpoint (replacing 3 consecutive bytes from the specified address) before calling an external routine, when the routine reachs this address it is interrupted and returns immediatelly to MICRO BUG. The breakpoint is removed automatically after an execution of command "G" or manually with command "L", to re-implement it at the same address the command "K" can be called again without a parameter. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "L" - Remove BREAKPOINT ------------------------------------------------------------------------------- Cancel the breakpoint implemented by command "K". ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "M [address]" - Memory edit ------------------------------------------------------------------------------- View and edit a memory area. Works like command "D", but it shows only one byte per line. The memory contents can be changed by just typing new values in Hexadecimal. Additional control keys are SHIFT-3 for byte format (hex/dec) and SHIFT-D for input format (hex/dec), in decimal input format it is necessary to press ENTER after typing each number. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "Nr value" - Change values of register pairs ------------------------------------------------------------------------------- Set the register pair "r" to value "value" in the register buffer. It can be used to debug assembler routines (see command "G"). The complete syntax is: "NB value" : set register pair BC. "ND value" : set register pair DE. "NH value" : set register pair HL. "NA value" : set register pair AF. "NN value" : set all register pairs. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "O start,end,target" - Copy memory blocks ------------------------------------------------------------------------------- Copy the source block (memory area between addresses "start" and "end") to address "target". The source and target blocks may overlap. Error message "BLOCO ILEGAL" if "start" > "end". ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- "P start,end" - Sum of a block ------------------------------------------------------------------------------- Print (last 16 bits of) sum of bytes stored inside a memory block. The result is printed in Hexadecimal. It is useful as a simple data checking method. ------------------------------------------------------------------------------- Notes: - In the case of commands that require the specification of a memory area (as "start,end"), the last byte (at address "end") is not considered. - The symbols "[" and "]" indicate an optional parameter. If the parameter is ommited, the command will continue from the previous execution point. =============================================================================== CONTROL KEYS ============ The input and output modes of the commands are controlled by the variable MFLAG, stored at address 7926. This is the complete list of control keys: +-----------+-------------------------------------+------------------+ | KEY | DESCRIPTION | STORAGE | +-----------+-------------------------------------+------------------+ | SHIFT-3 | Output format for "M" (hex/dec) | Bit 0 of MFLAG | | SHIFT-4 | Output format for "D" (hex/token) | Bit 1 of MFLAG | | SHIFT-E | Address format (hex/dec) | Bit 2 of MFLAG | | SHIFT-S | Print speed (slow/fast) | Bit 3 of MFLAG | | SHIFT-G | Available | Bit 4 of MFLAG | | SHIFT-A | Available | Bit 5 of MFLAG | | SHIFT-D | Input format for "M" (hex/dec) | Bit 6 of MFLAG | | SHIFT-F | Save speed (slow/fast) | Bit 7 of MFLAG | | SHIFT-9 | Graphics mode | -------------- | | SHIFT-Q | Clear screen | -------------- | | SHIFT-1 | Reset to initial screen | -------------- | | SHIFT-T | Copy screen to printer | -------------- | +-----------+-------------------------------------+------------------+ =============================================================================== TECHNICAL NOTES =============== To save the MICRO BUG system into tape, it's necessary to execute this: +-------------------------------+ | >BASIC | | NEW | | RAND USR 31210 | | >E 6,0802,* | | >O 7800,7FFF,4082 | | >E 1,1A,* | | >BASIC | | 2 RAND USR 31210 | | 3 FAST | | 4 SAVE "MICRO BUG" | | 5 RAND USR 16514 | | RUN | | >M 4082 (type this block:) | | 31 EC 6D 21 00 6E 22 04 | | 40 21 DD 40 11 00 78 01 | | 00 08 ED B0 CD 29 02 C3 | | C3 03 | | (reset with SHIFT-1) | | (start the record tape) | | >BASIC | +-------------------------------+ The loading system can be used to copy protected programs: +-----------------------------------------------------------------------------+ | 1. Remove the area reserved for MO: "POKE 16389,120" and "NEW" | | 2. Fill memory with known values: ">F 4400,7700,*" | | 3. Load program (at normal speed): ">J 4410,7700" | | 4. After the program was loaded, press BREAK and use command "D" to find | | end address of program (first address of memory area only with asteriscs) | | 5. Save program: ">I 4410,end" | +-----------------------------------------------------------------------------+ =============================================================================== DEFINING AN OPERATING MODULE ============================ An operating module can define the commands from "S" to "Z" and it can call any MICRO BUG code as sub-routine. The module code size should be at most 2.5K (occupying addresses from #6E00 to #77FF) and the module name should have at most 15 chars. After the module code is implemented, it must be integrated into MICRO BUG. The start address of each module command must be defined into the module commands table (addresses from #7800 to #780F), the start address #7A34 must be used in undefined commands. The routine $MORG must be typed, defining the module name between addresses #7819 and #7827. The sum obtained executing "P 6E00,783A" must be stored into addresses #783A and #783B, it will be used to check if the operating module was loaded correctly. Finally the operating module must be saved using the command "I 6E00,783C" set at normal speed. The command "C" can now be used to load the operating module. This command will automatically execute "J 6E00,783C" at normal speed, check the module sum and copy the module commands table into the commands definition table. Now the new commands defined by the module can be used normally and SHIFT-1 will present the module name together with the MICRO BUG logo. =============================================================================== APPENDIX: USING MICRO BUG WITH EMULATORS ======================================== As far as I know there are no ZX81 emulators available that can emulate it at I/O level, so the tape access commands "I", "J" and "C" will not work. However it is still possible to load external operating modules in ZX81 emulators that provide another way to load data directly into specific memory locations: 1. Load the operating module (that should have exactly 2620 bytes) into memory starting at address 28160. In emulator EightyOne use menu option "File" / "Load Memory Block" specifying address 28160. In emulator Xtender it is necessary to execute: +--------------------------------+ | >BASIC | | LOAD "*LOAD:C:filename:28160:" | | RAND USR 31210 | +--------------------------------+ 2. Now execute this command below to run part of the command "C" but skipping the tape access routines: +--------------------------------+ | >G 7FAA | +--------------------------------+ To save a new operating module, instead of executing "I 6E00,783C" set at normal speed, it is also necessary to use the specific tape access facilities of the emulator. In emulator EightyOne use menu option "File" / "Save Memory Block" specifying address 28160 and size 2620. In emulator Xtender use: +--------------------------------+ | LOAD "*SAVE:C:28160:2620:" | +--------------------------------+ =============================================================================== FINAL NOTES =========== The system documentation here presented (and comments in the included source code) is not a direct translation of the original articles, just a brief resume based on my old personnal notes. However I believe it contains all important informations and it should be enough, not only to learn how to use the system, but also to understand its internal implementation. Einar =============================================================================== THE END ===============================================================================