[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 'Hello world' for monitor mode and an assembler?



Hi Michael et al,

Thank you for all for your earlier advice on this subject, it has helped
me a great deal. I now feel competent enough to start doing things a
little bit more than a hello world program, apart from a few things. Sorry
if I appear slow on this subject, but it's completely new to me, but I'm
really keen to learn and it's been something I've always wanted to do.

Michael especially - your patient and authorative answers are very easy to
follow, you must have been a teacher/lecturer at some point!

I have decided to stick with the monitor mini-assembler for now, as I'm
having issues with Merlin, for example, it loads up PRODOS (i'm not
au'fais with prodos yet - first time i'd seen it apart from on the kegs
emulator in system 6). I can't seem to view the disk that i write source
to in Merlin, when in AppleSoft etc. I think I know the reason for this
(prodos incompat. with other dos systems -- too many bloody DOS systems if
you ask me!)

Anyway, here is Michael's (thank you!) earlier 'Hello World!' program:

On Wed, 08 Sep 2004 19:28:08 +0000, Michael J. Mahon wrote:

> 300: ldy #0
>  lda 320,y
>  jsr fded
>  iny
>  cpy #d
>  bne 302
>  jsr fd8e
>  rts

I tapped it in and got it working just fine. This is what I made out of
it:

300: ldy #0  	; y register (index) set equal to 0 
302: lda 320,y	; place contents of $320 into the y register 
305: jsr fded	; jump to subroutine at $fded (for outputting text) 
308: iny	; increment y register (index) 
309: cpy #d	; compare y register -has loop gone on for #d ? 
30B: bne 302	; branch not equal. Branch to $302
30D: jsr fd8e	; jump to subroutine at $fd8e 
310: rts	; return from subroutine
	...

      1  2  3  4  5  6  7  8  9  a  b  c  d
320: c8 e5 ec ec ef ac a0 f7 ef 42 ec e4 a1   === $d
      H  e  l  l  o  ,     w  o  r  l  d  !


Here are the things which I can't quite understand yet:

30B: bne 302	; branch not equal. Branch to $302

I understand this quite well, it is basically a goto. It goes to $302 to
perform a loop to print out the whole 'string' of characters. However, Why
is is bne? What makes it 'not-equal'? Is it the value of $y to #d? If so,
how does bne work this out?

30D: jsr fd8e	; jump to subroutine at $fd8e

Okay, I understand that a subroutine is at $fd8e, but what's it doing, and
more importantly, how can I find out what all the other subroutines in the
Monitor / Basic routines are (as I note from the Apple II reference guide
that 56k - 64k or E000-FFFF is used for just this). Line number 305 also
goes to FDED, which I someone else said is used to display characters. How
does a mere mortal know that these areas in memory do such wonderful
things?!

310: rts	; return from subroutine

Next up is the final line of the main code - what subroutine are we
returning from here? Is it the one from 30D above? (I would have logically
thought a return would be issued up near FD8E).

On to my final point, about inputting text:

> 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 '!

I am now an owner of a //e and have been using it for 2 days.
Before I was just using a ][+, so now can I access this 'enhanced'
monitor? So far, the only way I have been able to use the mini-assembler
is to load up my system master dos disk, and then do 'load applesoft' at
the ] prompt. Then doing a call-151 and then an F666G. Certainly typing
the text in as above would be a lot easier than looking up the hex for
each char. I have printed off the ascii table but it's still a bit slow to
do!

I will get using a proper assembler at some point as I immediately see the
benefit of using one. I have tapped this program into merlin, as I say and
I did see how everything fitted in easier - less manual calculation, but
for now, for the real learning curve, I'll do it all the old fashioned way
to make sure I have the best understanding.

> Alistair J Ross wrote:
> 
>>I'm looking for a little piece of advice from someone who has knowledge
>>of writing low level code on the Apple II (Michael Mahon?).
> 
> Thanks, Alistair, but I'm sure there are quite a few folks who frequent
> this forum who have more A2 coding experience than I do.  ;-)
> 
> Your curiousity andf enthusiasm for learning to use the Apple II at the
> machine language level is the major requirement for success, and you
> already have it!
> 
>>Basically I want to learn the very basics of the 6502, but more
>>particularly, just how to code on the machines level. I know a number of
>>high level languages, but every time I go to low level I get confused
>>between typing programs into an assembler (I take it I need to get an
>>assembler to do this?), and maybe finding out how to just entering the
>>hex into the monitor to get the program running. If I need an assembler,
>>what one should I use?
> 
> You will certainly want an assembler as you begin to write programs more
> than a few lines long.  An assembler provides a symbolic way to create
> machine code that allows you to easily make changes.
> 
> The mini-assembler built into the enhanced //e and IIgs monitors
> provides some assistance, such as translating between mnemonics and hex
> opcodes and calculating branch displacements, but it does not provide
> any capability for labelling data or code, instead requiring you to keep
> track of the addresses corresponding to things on a separate piece of
> paper.  Since addresses typically change whenever any code is inserted
> or removed from a routine, the manual bookkeeping required to document
> and modify code created with the mini-assembler becomes quite onerous
> for longer routines.
> 
>>All I want to do at the moment is enter the monitor (from call-151) and
>>type a 'hello world' program which dumps me back to the prompt. However,
>>I would love to have a line-by-line step through. I've looked everywhere
>>on the net for such a thing and I can't find that little kickstart I
>>need. I even bought the Apple II 'Red Book' Reference from Ebay, but it
>>doesn't really cover this.
>>
>>The only time I ever did assembler was using DEBUG in MS DOS a long time
>>ago. Now was that assembler, or was that just adding raw hex into the
>>system for it to do stuff? Or am I completely confused?
> 
> No, you are very close to a correct understanding of what's going on.
> 
> The Apple monitor and mini-assembler are similar in many respects to the
> MSDOS DEBUG routine.  Both allow you to examine and change the contents
> of memory and call programs in memory.
> 
> Once you enter the Apple monitor by typing "call-151<return>", you will
> see the monitor prompt, the asterisk (*).  This prompt means that
> whatever you type in will be interpreted by the monitor (and not by some
> other program, like Applesoft BASIC).
> 
> Since you have the Red Book (and probably an Apple Reference Manual),
> you already have documentation of the commands accepted by the monitor
> and what they do.  This would be good to review if you have not already
> done so.
> 
> You may also know that the lower part of "page 3", the region of memory
> from $0300 to $03CF, is commonly used for short machine language
> programs, because it is unused for other purposes.
> 
> From the monitor prompt, you can easily examine any code at $300 by
> typing 300L<return>.  This will disassemble the first 20 instructions
> --if any code is there--or the "interpretation" of whatever _is_ there
> as if it were instructions in any case.
> 
> 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/

-- 
-----------------------------------------------------------[ Alistair J Ross]--
Alistair Ross
XBOLT Network 
--[ www.xbolt.net ]------------------------------------------------------------