[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[no subject]
If you type 300.31F (followed by the <return> that I will no longer indicate)
the first 32 bytes of page 3 will be listed in hexadecimal. This is just
an alternate "view" of what is located there, this time as binary data.
You can enter new data into any location or range of locations by
typing the first address (in hex), followed by a colon, followed by
pairs of hex digits, one pair for each byte to be changed.
For example, typing 300:dd fb 20 60 will change the first four bytes
at $300 to DD, FB, 20, 60, as you can verify by typing 300.303 to
list the four bytes.
If you then type 300L, you will see that the first four bytes of the page
can also be interpreted as two instructions: JSR $FBDD and RTS.
(The ROM routine at $FBDD beeps the Apple II speaker, as documented
in the reference manual.)
This program, if executed, will call the "bell" routine to beep the speaker,
then return (RTS) to the monitor. You can execute it by typing 300G.
Congratulations! You've just entered your first machine language program
and run it! ;-)
>Finally, how do I know what hex values represent which operator. In Debug,
>I'm sure that the command DB 'text' would register the string 'text', and
>you could make a loop to print the contents of it out. What are the
>operators for the 6502 (are they the ones in the red book).
In the above example, you would have had to know where the "bell"
routine is in ROM, and what the hex opcodes are for JSR and RTS.
You can use the mini-assembler to handle the latter translation.
Get into the mini-assembler by typing ! (followed by <return>) at the
monitor prompt. It will respond with a ! prompt character.
You can enter mini-assembler programs by typing the start address
(hex) followed by a colon, followed by the mnemonic of the desired
instruction, followed by any operand of the instruction.
So to enter the program above, you would type:
300:jsr fbdd
rts
Notice that any line that does not reset the destination address must
begin with a space (the space before "rts"). All mini-assembler operands
are interpreted as hex, so you don't need to preface them with "$".
Now type 300L and verify that the program was (again) entered into
memory.
Since the Apple monitor only has routines to output single characters,
a simple "Hello, world!" program requires a loop to output the string of
characters. There are several ways to organize such a loop, so we'll
just pick one here as an exapmle.
An assemly language program to write "Hello, world!" is:
org $300 ; Set program origin
hello: ldy #0 ; Initialize index
loop: lda msg,y ; Get next character
jsr cout ; and print it.
iny ; Advance index
cpy #msglen ; Done?
bne loop ; -No, keep looping.
jsr crout ; -Yes, print CR
rts ; and return.
msg: asc "Hello, world!"
msglen equ *-msg ; length of message
In case you are not familiar with it, the "#" preceding an
operand indicates that it is the actual value of the operand,
not the address of the operand. Familiarity with assembler
syntax is important to success. ;-)
This is written in a form that the Merlin assembler (freeware)
would accept. Notice that everything is referenced symbolically,
even the length of the "Hello, world!" string, so that changing the
content of the string would automatically change the value of
"msglen" so that the program would continue to be correct.
This kind of capability is an example of the value of a real
assembler, relative to the built-in mini-assembler.
Since everything must be in absolute hex addresses for the
mini-assembler, we don't know what address to use for "msg"
when we first type in the program, because we don't know how
long the program is before we get to "msg".
A simple "fudge" to bypass this problem for a simple program
like this is to simply "round up" the address for "msg" to a
value that we know (hope ;-) will be high enough that the program
will not collide with it. In this case, pick a "round" hex number
safely above where the program will be, like $320. ($310 would
work, but we don't immediately know that. ;-)
So this program could be entered using the mini-assembler
like this:
300: ldy #0
lda 320,y
jsr fded
iny
cpy #d
bne 302
jsr fd8e
rts
Notice that we had to count the number of characters to be
output (13) and convert it to hex ($D) for the "cpy" operation.
Also note that we had to look back at the screen to see that
the "bne" target was address $302.
Now, we enter a <return> at the ! prompt to exit the mini-assembler
and use the monitor to fill in the value of the message:
320:c8 e5 ec ec ef ac a0 f7 ef f2 ec e4 a1
Notice that this is "high ASCII", as expected by the Apple COUT
routine, and that we had to look up the hex value for each character.
This problem can be simplified on a IIgs by using the ASCII input
mode of the monitor, like this:
320:"Hello, world!"
which is quite convenient, or a similar mode on the enhanced
//e monitor, like this:
320:'H 'e 'l 'l 'o ', ' 'w 'o 'r 'l 'd '!
where you have to watch the spaces carefully. ;-)
In any case, doing a 300L to verify that the program is correctly
entered and a 320.32f to verify that the message is entered, will
prepare you to execute the program by typing 300g.
The message will be printed, followed by a carriage return, and
the program will return to the monitor to issue another * prompt
on the next line.
This has concentrated mostly on the mechanics of entering a
short program using the monitor facilities, with a little hint of
what convenience a real assembler can provide.
Try it out--in fact, try lots of things out! You'll have fun, learn
fast, and stimulate your imagination in the process.
1MHz and 64KB seem like very slow and small numbers today,
but I think you will find that your machine language programs
run so fast, and are so small, that the Apple II seems like a
huge playground for your experiments--enjoy!
(BTW, don't hesitate to ask further questions--that's what learning
is all about!)
-michael
Check out parallel computing for 8-bit Apples on my
Home page: http://members.aol.com/MJMahon/