-------------------------------------------------------------------------------
       ##   ## ######  #####  ######   #####    ######  ##   ##  #####
        ## ##    ##   ##   ##  #   ## ##   ##    #   ## ##   ## ##   ##
       #######   ##   ##      ##   ## ##   ##   ##   ## ##   ## ##
       ## # ##   ##   ##      ######  ##   ##   ######  ##   ## ##
       ##   ##   ##   ##      ## ##   ##   ##   ##   ## ##   ## ##  ###
       ##   ##   ##   ##   ## ##  ##  ##   ##   ##   ## ##   ## ##   ##
       ##   ## ######  #####  ##   ##  #####    ######   #####   #####
-------------------------------------------------------------------------------
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.
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
"N r,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:
"N B,value" : set register pair BC.    "N D,value" : set register pair DE.
"N H,value" : set register pair HL.    "N A,value" : set register pair AF.
"N N,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 was 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 could 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
provides another way to load data directly into specific memory locations:

1. Load the operating module (that should have exactly 2621 bytes) into memory
starting at address 28160. In the emulator Xtender it is necessary to execute:
+--------------------------------+
| >BASIC                         |
| LOAD "*LOAD:C:filename:28160:" |
| RAND USR 31210                 |
+--------------------------------+

2. Now execute this to run part of the command "C" but skipping the tape access
routines:

+--------------------------------+
| >K 7FC6                        |
| >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 the 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.

For additional information about this system, I can be contacted by e-mail at
"einar@ime.usp.br".



                Adzubla!

                                Einar



===============================================================================
THE END - This is part of TKPAK001.ZIP and cannot be sold separately!
===============================================================================

