The Virtual Assembler 16 - (C) Manuel Nickschas 1. What is the VAss16? 2. Differences to the VAss8 3. General operating instructions of an assembler 3.1 Label operation 3.2 Further characteristics of an assembler 4. File transfer from other assemblers to the VirtualAss, compatibility 5. The functions of the VAss16 5.1 The pseudo Opcodes of the VAss 16 5.2 Functions that can be reached with arrow left 5.3 Further functions of the VAss16 6. The option menu of the VAss16 6.1 Possibilities after assembling 6.2 Memory - options 7. The functions of the VirtualMon 8. Quick reference, Tips 8.1 Support 8.2 Known Problems with the Virtual assembler 16 9. Credits 1. What is the VAss16? The Virtual assembler 16 is an aid to the production of assembler programs. It was written particularly for the development of SuperCPU programs. It is however likewise possible to use it for conventional 8-bit code. In the 64k standard RAM of the c64 it belgt straight times four bytes (off $d3f0), everything else lies in the Super-RAM, which is presupposed. Where in the super-RAM the VA16 is located, can be selected freely. Like that it is possible to program the entire memory that is available. Apart from the assembler the VAss16 also contains a monitor. The Virtual Mon can represent and work on the entire c64-memory including Super-RAM. It possesses all important basic functions of a monitor. Who looks for still more comfort, may refer to the DreaMon (GO64! 7/2000). 2. Differences to the Virtual assembler 8 Even when using the Virtual assembler 16 for conventional 8-bit code, it offers some advantages. The Virtual assembler 8 actually was like a turbo-ASS with REU support. The VAss8 beside the REU also super-RAM only supported and permitted longer source code and more labels. Unfortunately the VAss8 had never completely developed and as with other C64-Assemblers had to always watch out one that one does not overwrite the assembler or source code by mistake or some Zeropage addresses not correctly resetted, before one returned to the assembler. The Virtual ASS 16 goes completely different ways, it doesnt use much the usual 64k, therefore it is only with difficulty possible to overwrite it at all. Up to 62 characters per line can be used. Also in the 40-Columns-Mode they can scroll through to be used. In addition the VAss16 possesses an integrated monitor. The Virtual Mon can access the entire super-Ram. The VirtualAss 16 has some new functions and controlled naturally also SuperCPU opcodes perfectly. 3. General operating instructions of an assembler This chapter is particularly dedicated to those, who so far worked with a monitor. It is more easily to learn to deal with a monitor than with an assembler. Switching to an assembler is, however, absolutely worth the effort. The lost time is regained fastly. 3.1 Label operation In a monitor all code is written directly into the memory. If one notices later that the code is to be changed in the middle of it or a completely different memory position would be better - then hard works awaits the monitor user, he has to "relocate" has own code by hand. Everything must be adapted by hand (all jumps, some lda's...). An assembler does this work by itself for the programmer. This is why you have to give instructions to the assembler, telling it for example where the code should later on be located (simply write '* = $adress' before the code) But how should you refer to a certain memory location or use modifying code? For this there are so-called labels, which replace fixed storage locations. A monitor code of this kind... $C000 lda #$01 $C002 jmp $C000 now looks like this... * = $c000 label lda #$01 jmp label the advantage of a label becomes recognizable quickly, if the code is to be moved, for example to $a000: $A000 lda #$01 $A002 jmp $C000 jmp must be modified by hand. * = $a000 label lda #$01 jmp label jmp points automatically to the new address, although the user changed only one line. Still, fixed addresses can be used: lda #$01 sta $d000 however, it is recommended to define labels also here: sprite0 = $d000 lda #$01 sta sprite0 this method is particularly important for variables. It can always be necessary to switch to another zeropage adress when you recognize that the one you wanted to use is also used by a particular music or kernal routine. Then all you need to change is the label definition - and in the entire code the new address will be used. Instructions like BEQ/BNE/BMI etc. are relative branch instructions, i.e. they always depend on their own relative situation. They jump for example -seen from their own position- 4 bytes back. As a consequence, they are always set correctly even when moved in a monitor. - but if code in insterted between the branch and the position it branches to, the adress still needs to be changed. example: $c00c sta $3000, x $c00f inx $c010 bne $c00c Everything fine, but if we include a new line... $c008 sta $3000, x $c00c sta $3100, x $c00f inx $c010 bne $c00c ... bne still jumps exactly 4 bytes back - however that is not correct any longer. It must be changed, as it should point to $c008. With the assembler that is different: loop sta $3000, x inx bne loop the bne points to sta $3000, x. loop sta $3000, x sta $3100, x inx bne loop and still it points to sta $3000, x! You will soon love labels. In special cases it is, however, senseful to use relative jumps. An assembler can make even jumps relative. Example: jmp * "*" stands for the current memory location of the command. Jmp * points thus to itself - an endless loop. jmp * +5 lda #$01 sta $3000 jmp now jumps 5 bytes foreward. It points to sta $3000. These functions can be used everywhere. Thus not only for jmp or beq, but also for data, labels or whatever else you can think of. sta (* - 18+$0a)/40 saves to the current position minus 18, counts $0a to it and divides the whole by 40. If the brackets would be missing, VAss would divide only $0a by 40 and would then go one with the other arithmetic operations. This example shows one thing: The VAss does not have problems with different formats of numbers. Can be used thus decimal numbers, binary code and hexadecimal numbers may be mixed. A usual number is decimal. Put a "$" before it, and it is hexadecimal. And if a "%" stands before it, it is binary. The VA16 accepts 8, 16 and 24-bit values. Even more is possible. Also labels can be used with labels. label1 = $3000 label2 = $40 sta label1+label2 Generates sta $3040. So labels can be used in many ways, having different functions. You can also use the same label in different ways: label = $01 lda label reads the value at $01 in the memory. It is thus lda $01. ...but... lda #label reads the value #$01, it is thus lda #$01. The same can be applied also to a 16-bit-value. But there an additional "<" and ">"... is needed to refer to the high- or low-byte of the label. label = $3000 lda #label ;Here a 16-bit-value is read in - only in SuperCPU mode! (lda #$3000) lda #label; reads the upper nibble of the label. (lda #$40) lda label; reads the value, which is at $3000. (lda $3000) This is actually everything that one must know about labels. Beside the labels there are a few few further characteristics of an assembler, but those are not difficult to learn. Here still one more example of the strange possibilities of the arithmetic operations... label1 = %00000001+$4000 label2 = label*(2+1) lda #0 sta #$10+label/4+label2+(*+4) lda #14 The first label amounts to $4001. The second $4001*3, in this case the "*" means multiply. The result is $c003. Then the Akku is filled with zero. Sta points to address $d021 - the background colour is thus set on black. The assembler calculates in such a way: $10+$4001/4+$c003+(*+4). First it executes what's in the brackets. The star indicates the current position (because there is nothing to multiply), so *+4 points to the current position plus 4 - which is the number 14 in the next sta. Then the assembler devides 4001/4. (the 1 is rounded and gone). Now it looks like this: $10+$1000+$c003+14, or: $d013+14. The value 14 in hexadecimal is $0e. Adding it all together, the result is $d021. To conclude this still one example for self-modifying code in an assembler: lda #$03 sta accusaving+1 ;store the value in the accu for later use lda #$40 ;Fill accu with new value.. sta $4000 accusaving lda #$ee ;Reinstall the saved value from above Due to modifying code, not #$ee is read in, but the value, which was written here through 'sta accusaving+1'. So, #$03 will be read here. 3.2 Further characteristics of an assembler As known from BASIC, one can comment the code of an assembler. In BASIC there is the Rem instruction. Behind a REM you can write what you want: the basic interpreter just ignores it. Exactly the same is implemented in an assembler. After one ";" you can (should!!) make notes. These don't bother the assembler but will help you understand your own code better later when you forgot what the one or the other routine does. Normally data such as a music, a Charset etc. is simply loaded (with Virtual Mon) into the memory. But sometimes it is helpful to include the data into the code, so you can edit it with ease. For data, VAss has several "pseudo Opcodes" available. .by stands for bytes. Behind it one can place as many 8-bit values (separated with commas), as he wants. Example: .by $01, $42, 3, 6, 9, $4000-$3000, %01010101 .wo (word) is the same for 16-bit-values .lo (long) for 24-bit-values .tx stands for text. Here you can place texts in the ASCII format. .tx "this is a text" If you wrote a program in an assembler and want to take a look at the final code, you might use the VirtualMon and look at it with this monitor. But in the beginning you will not find it at all. It is not yet existing. The assembler first has to generate the code. This happens with the function "assembling". (press arrow left, and then press 3). Now the assembler tells you what he doesn't understand or tells you about some mistakes you made. (for example a branch might be out of range because it points to an adress that is too far away) If no errors occur, the program can be started, or you can return to the assembler. Now the code is generated and you may look at it with VirtualMon or any other monitor. The VAss offers some nice options for this. Read the section "the option menu of the VAss16" for details. 4. File transfer from other assemblers to the VirtualAss, compatibility The functions and handling of the Virtual assembler 16 is very similar to the Turbo assembler. It has some additional functions, but files transferred from the turbo-ASS should hardly make any problems. What you have to do is to export the sourcecode from the old assembler to ASCII format. With the turbo-ASS (and also with the VirtualAss) this is done by pressing arrow left + W (write file). The source code is stored in a Sequencial file and can be read in by the VAss later with arrow left + E (enter file). Any assembler, which supports ASCII import/export can transfer files with VA16 (besides the TAss this is also ACME for example). Depending on the previously used assembler, still some minor changes in the syntax must be changed. First thing to do is exchange the return routine to the assembler, if you had one. Just now jump to $00d3f0 and all the initialisation stuff is done by VA16. They are not no more needed with the VAss. Now press arrow left + 3 to test if any errors are reported. There is only one thing to change when you import TAss sourcecodes: complex labels. An example is this line: lda adresslabel-$4000/64 This line was recognized by the TAss as correct, although a 16-bit-value would have to be read in, if the TAss would calculate correctly! But it doesn't! TAss can accept this inaccuracy because it knows a 16-bit value is never meant. However, VAss also allows 16-bit code, so it cannot accept inaccuracy with brackets. In VAss, the same line would have to be lda (adresslabel-$4000)/64 Another thing about brackets: The VA16 always refers to what follows directly afterwards, and not more. "<" in lda - if nothing is specified, the values are decimal. 5.2 Functions that can be reached with arrow left All of these functions can be reached by first pressing arrow left, then (afterwards, NOT at the same time, so you need not be quick or anything) you may press the following keys: shift+M - to the Virtual Mon O - to the option screen run/stop - break. Stops operations such as searching/hunting or just undos that you pressed arrow left. arrow left - writes arrow left as a character. Disk operations: L - Load sourcecode (overwrites the existing source code) S - Save source code in the VAss16-Format E - ASCII file import. The existing soucrecode is not replaced, the new lines are included at the current position of the cursor. The cursor should be on a blank line, otherwise one line will be overwritten. W - export entire source code as ASCII file (caution! The file can become very long!) If you want to export/write only a part of your code, see block functions. * - Display directory D - Enter Disk Command @ - Read the error channel Search and replace: F - Find text H - Find text again R - replacing: Define text to be replaced. R also finds the text once, but does not yet replace. Press arrow T to replace and arrow H to skip replacing and hunt on. Copy line functions: DEL - delete line / - delete the rest of the line arrow up - copy line Pound - insert line RETURN - split line into two lines = - join two lines into one 2 - include seperator (defined in the Options Menu) Marking and block functions: M - define block or mark It is also possible to define blocks by CTRL+S and CTRL+E (without arrow left) G - jump to defined mark N - jump to a certain line B - block functions. You can copy, delete or Write a block. Controls: CRSR up - 200 lines upwards CRSR down - 200 lines downwards Q - Go to the beginning of a line SHIFT+HOME - INSERT char mode on/out SHIFT+DEL - INSERT LINE mode on/out 7 - sets the tabulator for RETURN (the distance of the cursor from the border) 8 - sets the tabulator for Opcodes (the distance of the Opcode from the border) 1 - leave the VAss. Get back with SYS 54256 3 - assembling the source code C - cold start. All values will become resettet, all data deleted! SHIFT+X - hard reset. Emulates a press on the reset button 6 - read data from the RAM into the sourcecode (as .by, .wo, .tx ...) + - add two hex numbers (replaces the calculator) - - substract two hex numbers A - ASCII mode : - displays a list of the current marks ; - delete mark U - functions only after an assembly. Indicates any label. SHIFT+P - park CMD hp SHIFT+U - UnPark CMD hp SHIFT+4,5,6 - Charset change 5.3 further functions of the VAss16 RESTORE - Undo. Restores the last changed line CONTROL+D - change drive number (as known from JiffyDos) The F-keys F3-f6 are freely configurable in the option menu. Defaults for the F-keys are: F1 - 200 lines upwards F2 - go to beginning F3 - .by F4 - .tx " F5 - assemble and start code with s F6 - delete line F7 - 200 lines downwards F8 - go to end 6. The options menu of the VAss16 With arrow left + O you get into this menu. Here, general settings can be made. Column mode (the VAss offers not only a 40-Column-Mode, but up to 63 chars per line!), colours, the Seperator, the allocation of the F-keys as well as the allocation of "s" and "S" of the assembling screen (see section 6,2). Allocation of the F-keys: Put here exactly what you would otherwise type in by hand. Example: You would like to start assembling with F3. Simply type arrow left and 3 into the option line of F3. The arrow left appears only when pressed twice, since it otherwise await a function. If you want not only to assemble, but also to start the program when pressing F3, type s or S right behind the 3. Allocation of s and S: (starting line 1 and 2) after assembling a program, you can start it either with s or S. If one of these are pressed, VA16 executes a reset, and executes the according starting line. If the starting line is *, the code can be started at any position defined by a star in the code (see section 6.1). However, you can also type in any BASIC-commands you like here. If you want to start your program at another location, simply type a sys here. The SYS still needs a RETURN to be executed. Type arrow left + A to get to the ASCII mode. If you press RETURN now, the RETURN will be displayed as a character. The ASCII mode is the same as typing " in BASIC. To exit the ASCII mode, press arrow left + A once more. Do not forget to save the options. 6.1 Possibilities after assembling After the code was successfully assembled with arrow left + 3, you have several possibilities to choose from. To the right of the screen, all code areas that you defined through "* = address" are listed. There is also over it information how long the finished code is. These code areas can be selected with the CRSR-keys and saved with RETURN. With s or S the assembler will execute the starting line 1 or two defined in the options menu. If this line is "*", then the code will be started at the selected code area. Space brings you back to the assembler. 6.2 MEMORY options In the options menu you may a link that leads to the MEMORY options menu. Here you can specify where in the memory your assembler and sourcecode should be located. Another important option here is the way VA16 reacts when you return to it after exiting. It is possible to leave VA16, do some other things like drawing sprites or whatever you like and then return to your sourcecode. VA16 is still in the memory, your code aswell, but what about the data you loaded with Virtual Mon to Bank 0?? It is also still there! But maybe you want VA16 to take over the changes made in Bank 0? This you can specify in the memory options. 7. The functions of the VirtualMon If VMon doesn't fit your needs, please use DreaMon from the Dreams. The functions and the syntax of the Virtual Mon: x - exit CONTROL+D - change drive number l - load. There is a lot of possibilities. E.g.: l "name" - load a file to its start address (2-byte start address) l "name" address - loads a file to 'adress', no matter what the original start addy was The address is indicated in hexadecimal, but without "$". s - save. The syntax: s "name" from-adress to-adress c - compare memory areas, c from-address to-adress with-adress d - disassemble m - view memory. All adresses can be a value from 8bit to 24bit, e.g. m58 - displays 0058 in the current databank. m340058 - displays 340058 and changes the current databank to 34. 8. Quick reference, Tips The back-jump-adress is: $d3f0 (SYS54256). No reset routines necessarily. If the NMI vector is not used, you can also use RESTORE to get back to the assembler. s and S can be configured in the option menu. Do not forget to save the options to the config file! With '* = address' start addresses are defined. Each source code needs at least a start address. For testing a finished code independently from the VAss, you can save out each code area after assembling. Keep in mind that whatever you do when leaving VAss usually does not affect or destroy the VA16, the sourcecode, not even the data placed in bank 0 (see section 6.2). You can compile your code, turn off SCPU, use your favourite freezer module (e.g. to debug the code), switch to SCPU again and type sys54256 - and just work on on your code. Even if the back-jump was overwritten (happens VERY rarely), you don't have to reload VA. When you try, a window will appear, telling you that VA was found in the memory already and you can choose to reload or not. The sourcecode remains unharmed either way. Load data with the VirtualMon and not with BASIC. Press arrow left + SHIFT+M to get to VMon, x to get back. 8.1 support If you still have questions, or you find a serious error in the VA16, then write us! General support: mailto:contact@protovision-online.de And visit our homepage: http://www.protovision online.de 8.2 Known Problems with the Virtual assembler 16 VA16 has proved to be a stable program in all the years we used and improved it. For games like Team Patrol, Hockey Mania, Snacks 4 Snakes, Pac It and also Metal Dust the VA16 was the most important development tool. However, sometimes problems occur. Without reason, VA16 might crash and your sourcecode might get corrupted. The reason is not the VA16, but your equipment: A SuperCPU needs a very reliable power source and a stronger PSU than the one shipped with the C64. When using a SuperCPU, PLEASE OBTAIN A STRONG POWER SUPPLY!!! Otherwise you may damage your computer and it will behave strange. Note that the RAM you put into a SCPU is also not always of high quality. Some RAM tends to create more problems than other RAM, needs more or less power and so on and so on. Yet another problem is the power connector of your C64. Even tiny contact problems may have a huge effect on the C64 with SCPU, might perform a reset, or destroy some data. Have it carefully plugged in (sometimes it is best not to plug it in completely) and do not touch it at all afterwards. For some obscure reason VA16 crashes less while using it or while arrow left was pressed. So if you turn away from the computer for a minute, leave VAss or press arrow left. All these problems only occur on some c64s. On others, VA16 will never crash. Get familiar with the peculiarities of your own system... 9. Credits, thank saying of the Virtual assembler 16 is a PROTOVISION production. Copyright (c)2000 Manuel Nickschas program, concept and Design: Manuel "Sputnick" Nickschas character sets: Joerg "DATAland" Heyltjes Ideas, assistance, betatesting, unnerving and begging, motivation: Malte "Thunderblade" Mundt, Chester "CKX" Kollschen, Jakob "Jak T Rip" Voos Manual: Jakob Voos, Manuel Nickschas English Version: Barbat Mihai, Michael Kraemer, Jakob Voos