Machine Language for Beginners (Part 2)
by Lyle Giese
DELPHI Mail: LYLEG
One of the Tools of the trade for Machine Language Programming!
When you wanted to learn about BASIC you read and played directly with BASIC programs. Using the BASIC editor, you listed programs to the screen and printer, wrote simple programs, and modified others. In order to do that you used BASIC itself in the form of its editor. The equivalent of that for ML is the Monitor. There are several good PD monitors available and we have some of them in our databases in the Flagship under Languages & ML.
One of the simpler ones is Supermon, written by Jim Butterfield. It's features became the standard for monitors and most monitors have more features, but they are generally supersets of the instructions found in Supermon. That is, the other monitors took Supermon and added more features with out changing any of the features or syntax of the commands found in Supermon. Micromon is one of them and there is more that one version of it around. The main difference in them is where in memory the program is loaded and run from. One of the features that Micromon added was to be ability to output the disassembly to a printer.
So if you use Supermon and can use all of the instruction in it, you won't have much trouble upgrading to a better one. By the way one of my favourites that I use is 'HESMON' from Hesware. When I am doing some heavy duty work I use that because it is in cartridge form. When I lock up the computer, it is right there when I power back up, but it does have the disadvantage of occupying memory from $8000 to $9FFF. It too follows the basic syntax of Supermon.
To use Supermon, load "SUPERMON",8 and run. It has now sealed itself off up at the top of basic. If you exit Supermon, you can go back by SYS(peek(55)+peek(56)*256). When it first boots up and after the title you see:
PC SR AC XR YR SP
.; 0000 01 02 03 04 05 .
If you type any commands they will be displayed on the third line right after the period. This will be the same display that you will get after typing the 'R' command.
Two notes: all commands are followed by a carriage return in order to be executed and all addresses and numbers are in Hex even though they are not prefixed with a '$'. The 'R' command is for displaying the registers. The first line identifies the registers. The second line shows the contents of them, and of course will be different that that shown. The first is the Program Counter. The second is the Status Register, this is where those flags are that we use in our branch instructions. The next one is the A register or Accumulator. The fourth is the X register followed by Y Register. And the last one is the Stack Pointer, that is the index into the stack pointing to the next available storage position.
The rest of the commands are as follows:
.A C000 LDA #$00
This starts a single line assembly at $C000 (49152) with the instruction LDA #$00. Of course you will use any instruction that your program needs. The assembler will check the syntax of the instruction (if it doesn't like it, it will respond with a ? on the same line.) and on the next line respond with the next address for you. Like this:
.A C002
So after the first line the assembler will supply the address. When you are finished simply type a return to get out of the assemble mode.
.C 1000 1010 0E
This command calculates the offset needed for branch instructions. The first address is where the branch instruction is and the second is the destination address. The monitor will calculate the offset ($0E). This command, in my opinion, is of little value. When writing with this assembler, it calculates branches for you by you specifying the target address in the instruction, such as;
.A C011 BNE C01F
However, sometimes you need to do a forward branch (as in the above example) and you are not sure where the target will be until you code all the instructions. In that case it would be easy to branch to the same instruction as you are on. Jot down the address for that instruction and later fill in the exact address you will need.
.A C011 BNE C011
You would need to write down $C011. Later after you wrote the code you want to branch around, you find out you want to branch to C01F:
.A C011 BNE C01F
.D C000
This will disassemble 22 instructions starting at $C000. The display can be modified and entered by using the cursor keys and hitting the return key while on the line being modified. To see the next set of instructions, (the cursor is on the space after the period of the last line) type 'D' and return.
.F CE00 CF00 FF
This monitor instruction will fill the memory from $CE00 to $CF00, inclusive, with the value $FF.
.G C000
This is simular to the 'SYS' instruction in BASIC except the number is expected to be in Hex instead of decimal. Also if no start address is given, the monitor will go to the address currently shown in the PC register.
.H C000 D000 'READ
This command will Hunt from $C000 to $D000 for the occurrence of the ASCII string 'READ'. It will respond with the addresses where it is found (if any).
.L "Filename" 08
Will load the program 'Filename' from device 8. If you don't specify a device Supermon will default to the cassette drive.
.M C000 C02F
This command will show a hex dump of the memory locations from $C000 to $C02F. Like this:
.: C000 00 01 02 03 04 05 06 07
Some of the newer monitors also give you an ASCII representation of the bytes to the right of the numbers. Again the information can be modified and changed by editing and hitting return for each line.
.R
PC SR AC XR YR SP
.; C000 01 02 03 04 05
This command returns a display of the current register commands in the following order: Program Counter, Status Register, Accumulator, X Register, Y Register, and Stack Register.
.S "filename",08,C000,C101
This command saves an area of memory under 'filename' to device 08. The memory saved is from $C000 to $C100. THIS IS IMPORTANT! All Commodore monitors do NOT save that byte under the specified ending address. You must specify the ending address +1 of your program.
.T C000 C100 CE00
This command copies or transfers the contents of memory locations $C000-$C100 to $CE00-$CF00.
.X
This is the last command in our long journey today. This command returns to our friendly (?) BASIC. Remember to return to Supermon-SYS(PEEK(55)+256*PEEK(56)).
This was a journey one of the tools of the trade for ML work. For more information stay tuned for an article on help with MADS, Commodore's label based assembler.