Hello User, Here is the latest pack in the MEMOTECH firmware family. It enables you to roll up your software sleeves and get down to the job of closely controlling your ZX81 processor. You do this by by-passing BASIC when you wish and coding directly with the Z80 Assembler language. You can now write economic routines tailor-made to your needs. If you are an absolute beginner at machine code then you should pay close attention to our introductory paragraphs and also get hold of a good teach-yourself Z80 handbook. Good Luck from all at MEMOTECH! What does an ASSEMBLER do? If a ZX81 program is written in BASIC, the program is interpreted and executed a line at a time. While many users are quite happy with this, by modern computer standards the processing is very slow. It is rather like a man trying to speak French with a phrase book and looking up each and every word as he goes along. Z80 Assembler code on the other hand is really the language spoken by the ZX81. You speak to it directly. Furthermore, by assembling the source code into machine code prior to execution, you make the execution itself extremely drapid - in some cases hundreds of times faster than BASIC. AOur Assembler pack offers two services: it allows you to enter and edit your source code, and it can then 'assemble' that code into executable code. What can I run the ASSEMBLER with? The ASSEMBLER has been designed to be compatible with MEMOTECH and Sinclair products wherever possible. It can be used with either 16K, 32K or 48K of RAM addresses above the 16K mark. Note however that the ASSEMBLER EPROM resides between 12K and 16K and therefore cannot be used simultaneously with the MEMOTEXT Word Processor or the MEMOCALC Spreadsheet Analysis Pack which also occupy the same area. These three software packs can be fitted together physically on the same system, but only one should be switched on (at the side) at a time. The ASSEMBLER pack should precede any memory packs and go behind the High Resolution Graphics pack (if used). How do I set RAMTOP? At a later stage, when the ASSEMBLER is generating an object program for you, it saves your source labels in a Label Stack which is situated above RAMTOP. Each label will occupy 8 bytes there, and you will have to set RAMTOP so that enough space is left above it (and below the physical limit of your RAM) to house the Label Stack. In the case of a 16K memory pack alone, this will mean setting RAMTOP lower than the default setting of 128 {byte address 32768}. Suppose you have a 16K configuration, and you need 50 labels: Upper address: 32768 Space for Label Stack: 400 New RAMTOP: 32368 To lower RAMTOP by 400: POKE 16388, 112 POKE 16389, 126 NEW To calculate RAMTOP precisely, you should multiply the contents of 16389 by 256 and add the contents of 16388. How do I begin creating SOURCE Z80 CODE7 The ADD and EDIT options allow you to create a source code program in a character array. THIS ARRAY MUST LIE AT THE START OF THE VARIABLES AREA. Thus, before you start a new piece of source code you must first clear out any variables already defined and dimension your array. The array can contain as many lines as you like (as long as your memory is large enough) but must have a line length of exactly 22 characters. The last character of each line is used by the assembler routine to calculate addresses. Two extra lines are reserved for use by the editor. So if you wanted to have space for 50 lines You would type: CLEAR DIM A$ (52, 22) The array can be saved and reloaded like any normal array, within a program. However if you wish to continue processing an existing saved string of source code, then you must be careful nor to clear the variables or dimension the area again or to activate the program with RUN . Re-entry to the program ,should take place with a GOTO statement (which can be stored with the original SAVE internal to the program). Now you can summon the menu of editor/assembler routines by making a USR call RAND USR 16258 This call can be used whenever you wish to move from BASIC to Assembler. To return, you simply use the QUIT option (5) list below. The source and object codes are preserved after QUIT. If all is well you will get the following display after the USR call: 1-ADD (to initiate or extend your source code} 2-EDIT (to amend existing source code) 3-LIST (to list source code) 4-ASSM (to assemble object code from source code) 5-QUIT (to quit the ASSEMBLER routine) Enter the value associated with the function you require. Each of the four options is described in detail How does the EDIT facility deal with the SOURCE STRING? The assembler software has one entry point. This has two functions. The first time the editor is used on a particular array, it finds the number of lines in your array, initialises the line and end-of-source-code pointers and places these variables in the first line of the array. This line is then transferred into the calculator stack. On exiting the editor these variables are transferred back into the array. Thus the variables always stay with the source code array, even when it is saved. All subsequent entries to the editor miss out the initialisation stage, allowing you to re-enter and carry on where you left off . ADD On entering the ADD option a listing is made of the last twenty lines of code (if they exist). The next line number is then printed, together with the cursor, at the bottom left of the screen, ready for the line to be built up and entered to the array. In order for the assembler to interpret the source code correctly it must be in the right format. Each line has three parts; the label field, the operation field and the operand field. Each of these must be seperated by at least one space and must start from columns 1, 7 and 11 respectively. Here is a little piece of code 1 7 11 ORG 16514 Start column numbers POS 60000 LABEL LD BC,1000 RET END What are ORG, POS and END for? Each source code program must start with an ORG and POS statement and terminate with an END statement. ORG tells the assembler where the object code is designed to run from. ORG should be below 32K. POS tells the assembler where the object code will be assembled in memory. END denotes the end of the source program. For example: ORG 16514 POS 16514 ... ... END This assembles the object code at 16514 and also runs it from 16514. If POS is set to 60000 then the program will still contain calls etc relative to 16514 but the program will reside at 60000. Error signals: First statement is nor ORG Second statement is not POS Last statement is not END Are there any special format aids for ADD mode? A TAB function has been added to the normal SINCLAIR cursor operation. The TAB function is accessed via the colon key (shifted Z) and causes the cursor to jump from anywhere in a given field to the start of the next one. Thus the keying sequence for the first line of the above program should be: :ORG: 16514 followed by NEWLINE. In any case, lines with characters at coloumn 6 or coloumn 10 cannot be entered in the array. After each NEWLINE a new screen listing will be made with the latest line at the bottom. The next line number and cursor will then be printed ready for you to complete. If you try to add more code than there are lines in your array then the control will return to BASIC with error report 4. How can I return to the menu when in ADD mode? Position the cursor to the first column of the line (it may already be there) and type STOP (shifted A}. This will return you directly to the menu. The current line is not added to the array. Can comments be placed in the program? Yes. They must be placed on a line by themselves and preceded by a semi-colon. These are ignored by the Assembler and so are not restricted to any other formatting demands: ; THIS IS A SUB-ROUTINE HEADING Can I save my object code in a BASIC PROGRAM? We recommend using a REM statemen which is the first statement in your BASIC program. The first byte will thus always be located at memory address 16514. To place your object code here, cite 16514 in both your ORG and POS statements. You should first have set up your BASIC program with a sufficiently large REM statement. However, the user normally only needs to save his source program in the string array, and re-assemble it on re-loading. Can I copy a block of Machine Code (as a Subroutine for another program, for example)? Easily! Listed below is a machine code routine to move any amounts of data from one position to another. It loads whatever is 'pointed' to by HL into wherever DE is pointing. It then increments HL & DE. It also decrements BC and carries on loading and incrementing until BC=0 Line 3 loads HL (the from point) with an Address Line 4 loads DE {the to point) with an Address Line 5 loads BC with the number of bytes to ,be transferred When you have written your routine, and if you want to use it in more than one program make sure your assemble it above Ramtop Then run this machine code routine, setting HL, DE and BC to the values you require. Be careful not to overwrite code that you are using. In the example below we copy a block of 200 (BC} bytes of machine code from position 60000 (HL) {which might be above RAMTOP) down to position 20000 (DE), where it can be executed. The copy routine itself resides at 30000. 1 ORG 30000 2 POS 30000 3 LD HL,60000 4 LD DE,20000 5 LD BC,200 6 LDIR 7 RET 8 END 9 ;THIS PROGRAM WILL 10 ;MOVE 200 BYTES 11 ;FROM 60000 12 ;TO 20000 EDIT On entering the EDIT option a listing appears with the last line situated in the centre of the screen. This is the last line used in this or any other option, or the line containing an error -if one has been detected- after the ASSM option. LINE= E is then printed at the base of the screen. You can now choose to edit, insert or delete any line in the array. Press the appropriate initial on the keyboard to make your choice. The current option will be indicated by the cursar. E = EDIT (default) D = DELETE I = INSERT The editor is now waiting for a line number to be entered (followed by NEWLINE). Invalid line numbers will be rejected. Non-numerical characters cannot be entered. Enter 0 (zero) if you wish to return to the menu. The following effects (including that of pressing NEWLINE} vary according to the option (E,D or I). In EDIT mode: Entering a line number causes that line to be brought down to the bottom of the screen where it can be edited in the normal way. Entering NEWLINE alone causes the current line to be brought down (most likely to be the line you have just edited). To return to the menu and keep the line as it was, press STOP with the cursor in column one. To enter the edited line to the array press NEWLINE. In DELETE mode: Entering a line number causes that line to be printed at the bottom of the screen together with the option (Y/N} to delete it or not. Press key Y to delete it and return to the listing or key N to just return to the listing. Entering NEWLINE alone, again causes the current line to be brought down ready for deletion. However, in this case, if a line has just been deleted then this means that the next line will be brought down. Hence blocks of code can be deleted without having to enter the line number each time. In INSERT mode: Entering a line number causes a blank line with that number to be printed at the bottom of the screen. Having built up that line, pressing NEWLINE will insert it ABOVE the line having the same number and shift all the rest of the code down a line. To exit without inserting the line, press STOP (cursor in column one). Entering NEWLINE alone allows a blank line with a line number one greater that the current line to be built up and inserted. Thus after inserting one line, if NEWLINE alone is pressed to the LlNE=prompt, then the next line will be inserted after the last inserted line. In this way blocks of code can be inserted without having to enter the line number every time. Note that in INSERT mode, if you try to insert a line when there is no more room left in the array, then you will be returned to BASIC with error report 4. LIST The LIST option allows you to list the source code either to the screen or to the printer. On entering this option "P/T?" is printed at the lower centre of the screen. Enter "P" if you want your listing on the printer, otherwise enter "T" for TV. Whichever option you choose a listing will be made on the screen, starting at the current line, togethr with the LINE = prompt. If the printer option was chosen then entering a line number will cause a listing to be made on the printer from that line to the end of the source code. If the TV option was chosen, then entering a line number will produce a screen listing of twenty lines of code starting at that line. Press NEWLINE to see the next twenty lines or enter another number to list from there. To return to the menu enter 0 to the LINE= prompt. After you have successfully assembled a source code program, these listings will also include an address at the right hand side of each line. This addresss is the address of the first byte of code produced by that line, relative to ORG. Thus unless ORG is the same as POS this will not be the actual address of that byte, but the address of where that byte will eventually be when the code is moved to its running position. These addresses can either be printed in decimal or in hex. By keying 'D' or 'H' (for decimal or hex) the addressing mode can be changed. 'D' or 'H'-will appear in the cursor. ASSM This option assembles the source code, placing the object code at POS, but assembling it so that it will run when placed at ORG. The assembler works in FAST mode, so the screen wilI go blank while it is in operation and will jump when it finishes. If the assembler finds an error in the source code it will stop with an error report of the form: ERROR x, LlNE=yyy See later for a summary of error codes (x). Pressing any key after an error signal will return you to the menu. The line containing the error is now the current line, so entering EDIT mode and pressing NEWLINE will bring that line down for you to edit before trying to assemble the code again. As the assembler works through the source code, it inserts dummy values for all labels. Then, on its second pass, it replaces these for their true values. If you use a label that is not defined in your source code program, then the dummy values for that label will remain in the object code. These dummy values are as follows: 0 For a single-byte data label. 0 and 0 For a two-byte data label. 0 and 0 For an address label. 255 For a relative jump label. Because of the relatively disastrous consequences of these dummy values in CALLs and JUMPs, the assembler searches the object code for them, and if it finds any, tells you how many it has found using the message xx WARNS Note that no line numbers are given and that only the CALLS and JUMPS to undefined labels are included in the count. Undefined data labels are not included. If the assembler has not found any errors then it will print up the "P/T?" notice in the lower centre of the screen together with the WARNS notice, if any have been found. It is now possible to list the object code, either to the printer or to the TV screen. Press "P" for a listing on the printer, otherwise press "T". Whichever option is chosen the screen will clear and the LINE= prompt will be given. The listing can either be in decimal or in hex. This is signified by the letter of the cursor in exactly the same way as in the listing of source code. Enter "D" for decimal, and "H" for hex. If the "P" option was chosen entering a line number will cause a listing to be made on the printer from that fine to the end of the program. If the "T" option was chosen, entering a line number will cause a listing of twenty lines of object code on the screen, starting at that line. Press NEWLINE to list the next twenty lines; or enter another line number to list from there. The object code listing has the following format: Line ORG POS Object No. Address Address Bytes AA BBBBB CCCCC DDD EEE FFF Enter O to return to the menu. QUIT This will return you to the BASIC mode. Note however that the option code 5 will appear on your BASIC screen. There is a possibility that line 5 of any existing BASIC program may be deleted if NEWLINE is pressed. Either avoid using line number 5 or remember to RUBOUT the 5 when you have re-entered BASIC. Summary of error codes Error Code Error 1 First statement is not ORG. 2 Second statement is not POS. 3 No such op-code or last statement is not END 4 Syntax error in operand. 5 No label space left (only applies to 64K rampacks). 6 Number too large (DEFB ahd DEFS onlyJ). 7 Relative jump out of range or redefined label. Additional information 1. Labels are not allowed in DEFS or DEFS statements. 2. Labels are not allowed as the offset to the index registers. BIT 7, (IY + DATA) is not allowed BIT 7, (IY + 255) is allowed LD (LABEL), IY is allowed 3. One statement is too long to fit in the twenty-one character line. This must be written in two lines as follows, for correct assembly. LD (IY + disp) {disp and data being numbers, labels are not allowed} data 4. A label in a program is given the value of the (ORG ) address at which it occurs . To assign an absolute address to a label, use the EQUATE directive. For example: LABEL EQU 16514 LD HL,(LABEL) 5. When using relative jumps, note that the displacement as specified in the source code is placed directly into the object code. Thus JR 253 assembles as 24,253 6. The assembler assumes numbers are in decimal unless preceded by a "$" sign. E.G. LD A,255 OR LD A,$FF 7. Labels can be three to five characters long. The first character must be a letter. Subsequent characters can be anything. All characters are significant. DO NOT USE REGISTER PAIRS TO START OFF LABELS . 8. The DEFINE BYTE directive can be used to place single bytes of data within the obsect code. When placing more than one byte at a time on a line, separate the numbers with SPACES. Also ensure that there is space at the end of the line. For example DEFB 255 100 10 One space at end of line DEFB 255 100 100 No spaces - will not assemble 9. The DEFINE SPACE (DEFS) directive can be used to reserve up to 255 bytes at a time for data, tables etc. When found in the source code it simply moves the address pointer on by the specified number of bytes. MEMOTECH Z80 ASSEMBLER was written by Philip Le Sueur for MEMOTECH LIMITED. MEMOTECH Z80 ASSEMBLER C) R. BRANTON & G.A.C. BOYD