Jump to content
IGNORED

Newbie machine language question..


elviticus

Recommended Posts

..So, I'm thinking about buying an Atari 800 and trying to learn to program in machine language. When I was a kid I had one and programmed in Basic, but machine language scared me off..

 

What would I need to get started? I know I had to use a Basic cartridge to program in Basic...

 

Anybody got any advice? Thanks.

Link to comment
Share on other sites

Yup...Basic is on a cart for the 400 and 800 (it was later put right into the XL and XE machines). That might be all you need for a while...until you get used to the idea of M/L. There are small type-in programs that you can use to do simple assembly...there's even one in the Machine Language For Beginners book archived at

http://www.atariarchives.org

Tho with things like SIO2PC, there's no reason to need to use type-ins at all. When you are ready to try M/L, you can just boot a disk image of a full-fledged assembler like MAC/65.

 

But really, you can also just use an emulator with them as well. No reason to do your assembly on the real thing unless you want to test a beta for glitches IMO. And XASM or DASM are good cross-platform assemblers.

Link to comment
Share on other sites

BTW if you want to experiment using M/L subroutines with Basic via X=(USR(ADDRESS)), keep a couple things in mind...

 

** The USR instruction can be used to pass values FROM Basic to the M/L subroutine. It does this by splitting the integer variable into 2 halves (low byte & high byte) and "pushing" them onto the stack. It also pushes the number of variables passed into the stack...even if there were none (as the above example). So any M/L subroutine would need to use a PLA instruction to "pull" this off the stack. When finished, the routine should end with an unmatched RTS instruction to return control to Basic...right from where it left.

 

** Basic leaves "page 6" virtually untouched. This area of memory runs from $0600 to $06FF (POKE values 1536 to 1701). So you can experiment with small routines very easy by just putting them there. If you don't use the printer or the cassette player, those buffer areas are also free to use.

Printer buffer = $03C0-$03FC (960-1020)

Cassette buffer = $03FD-$047F (1021-1151)

 

That's over 400 bytes of ram space to experiment with just using the Basic cart. And if you write a program to rearrange ram pointers, you can free up pretty much any area of memory to put the M/L code into. But an assembler program is better to use when you get to that point ;)

Link to comment
Share on other sites

Thanks - I didn't realize I could do ML subroutines from BASIC! That probably would be a good place to start... Is there a book that can help me learn to do this? At this point, I wouldn't know even what would be useful to write a subroutine for,,, or how to do it...

Link to comment
Share on other sites

http://www.atariarchives.org/mlb/

That book is a start. It even shows you breakdowns of all the instructions and what they do, as well as lists ways to change Basic instructions to m/l routines. The appendicies are also handy to have around.

 

 

Generally, the m/l routine would need to be translated into decimal values (value 104 for the instruction PLA and 96 for the instruction RTS for example)...and those values are put into Basic's DATA statements. Then you just use a loop to POKE them all into memory when the program initializes. So you would need to do 4 additional steps after writing a m/l routine: use a table to find the appropriate hex value for the instructions, then use a conversion table to tanslate those values into decimal, and then enter those numbers into a DATA line, and then use a loop to POKE them into memory. It's really slow compared to an assembler, but it can be done (and allow you to experiment with m/l).

 

 

For example, here's a real short routine that puts the character set on screen (in the top rows of the display).

     PLA         ;get rid of the USR scrap

    LDY #$00    ;start at the first character, and

                ;using the Y register as a counter

Loop:

    TYA         ;transfer it to the accumulator

    STA ($58),Y ;save it from the start of screen ram

    INY         ;increase the counter (character)

    BNE Loop    ;if it hasn't reached zero again, repeat

    RTS         ;otherwise, exit the routine

 

First convert all of the instructions to the opcode hex value...

$68

$A0,$00

Loop:

$98

$91,$58

$C8

$D0,$FA

$60

 

 

Then convert them to the decimal equalivilants...

104

160,0

--

152

145,88

200

208,250

96

 

 

Put it into a Basic form...

10 DATA 104,160,0,152,145,88,200,208,250,96

 

 

That's 10 bytes...so you would run a loop from 1536 to 1545 to POKE it into memory...

20 FOR I=1536 TO 1545:READ J:POKE I,J:NEXT I

 

 

And then add a USR instruction in the program to execute it...

30 I=USR(1536)

 

 

Naturally, you wouldn't want to be trying to write an entire game like this. But it can be useful to rewrite a slow Basic routine into a m/l version that performs the same task. Getting the most time-consuming parts converted like this can make a Basic program perform more like a commercial game :) And that book shows ways of converting Basic instructions into m/l...tho in addition, Basic compilers also exist...those programs will convert an entire Basic program into m/l. The drawbacks of using compiled Basic is that it's usually much larger than the original program...and isn't as efficient/fast as writing m/l from scratch. But it does do all the work for you...so it's a give-and-take thing.

Link to comment
Share on other sites

BTW to see the Basic version of that subroutine...add this to the program:

 

 

21 FOR I=0 TO 255

22 POKE I+PEEK(88)+256*PEEK(89)+400,I

23 NEXT I

 

 

That will put all the characters on the screen as well (starting from the 10th row). When it finishes, the USR instruction will run the routine in page 6 and do the same job at the top of the screen. Lot faster, eh?

Link to comment
Share on other sites

Oh, I forgot to mention about the branch used for the loop (BNE). The way you get the value for those is by counting the number of bytes from where you are. Subract it from 255 if you are going backward...or just list the number of bytes you want to skip over if you are going forward. In that example, the stretch of bytes $98 to $D0 is a span of 5 bytes. So 255-5=250 ($FA). You can only branch up to 128 bytes in either direction...values below 128 ($80) will branch forward, $80 and higher branches backward (a bit confusing...but the higher the number, the LESS far back you go!).

 

To go larger steps, you'd have to use a JMP instruction instead and list the actual address that you want to jump to...low byte first, high byte second.

 

JMP $0600;go to the start of page 6

equals

$4C,$00,$06

equals

DATA 76,0,6

Link to comment
Share on other sites

..So, I'm thinking about buying an Atari 800 and trying to learn to program in machine language.   When I was a kid I had one and programmed in Basic, but machine language scared me off..

 

What would I need to get started?   I know I had to use a Basic cartridge to program in Basic...

 

Anybody got any advice?   Thanks.

 

You can also program in C. Take a look at http://www.cc65.org for the C compiler. You can write code in C, if you already know C, have the compiler generate an assembly listing, and see what the code looks like.

Link to comment
Share on other sites

Another possibility is one of the proprietary languages that came out for the 8-bits. The only problem there is that most of them seem to have appeared on disk only.

 

The reason I raise this possibility is that it's how I first got started on 6502 assembly (I actually learned 68000 on the ST first, though). I have a programming language called PL65. One of its neat features is that you can add inline 6502 assembler for extra oomph! 8)

 

The language itself is procedural (no nasty line numbers) and more like Pascal than C but produces some of the fastest compiled code I've come across on the Atari. The inline assembly feature means that you can add 6502 routines in your code. One way of learning 6502 with such a language is to first write a program in the native language syntax and then try to convert some, or all, of it into 6502 using the same compiler and see if your program still works.

 

PL65 was only available on disk, though. Nir Dary was kind enough to make me a backup of my original disk a few years ago. You need a Happy to copy it, which I don't have.

 

I also own a copy of the Action! cartridge, which a lot of people hold in high regard. Someone did tell me a while ago that Action also allows inline assembler but I don't know how true that is. Again, though, I prefer PL65 for its simplicity and the fact that you don't need a separate runtime library (it's included automatically into your compiled programs).

Link to comment
Share on other sites

I used to use Advan Basic a lot. That functions pretty much the same as a glorified Atari Basic, except that it interprets the entire program the moment you run it (rather than interpreting line-by-line)...and most existing Atari Basic programs can be imported. You can "drop down" into m/l whenever you need it...which is a plus (particularly since it's really only about 10x faster than Atari's Basic). A seperate runtime module wasn't even available when I got it (you'd have to buy the whole package)...so I dunno if that one ever caught on ;)

Link to comment
Share on other sites

LOL

 

It is easier to write in Mac 65 then use user in basic.

 

I never learned basic at all only ever used Assembly. Get your self a copy of mapping the atari that will become your bible if you are going to write machine code.

 

You could take a look at this lint too for some stuff to get ideas how things are done.

http://www.jetbootjack.com/JBJ_oldgamesdownloads.html

 

there is quite a bit stuff for you to play with there.

 

Andy

Link to comment
Share on other sites

LOL

 

It is easier to write in Mac 65 then use user in basic.

 

I never learned basic at all only ever used Assembly.

 

Umm... So how can you compare them? It all has to do with what you want to write. If your program won't be graphics intensive, and instead requires a lot of user input and disk access, then BASIC may be a good choice. If you want to write high-quality games, then Assembly is just about the only choice.

 

Get your self a copy of mapping the atari that will become your bible if you are going to write machine code.

 

I would also get Atari's Hardware Reference Manual.

 

-Bry

Link to comment
Share on other sites

LOL

 

It is easier to write in Mac 65 then use user in basic.

 

I never learned basic at all only ever used Assembly. Get your self a copy of mapping the atari that will become your bible if you are going to write machine code.

 

You could take a look at this lint too for some stuff to get ideas how things are done.

http://www.jetbootjack.com/JBJ_oldgamesdownloads.html

 

there is quite a bit stuff for you to play with there.

 

Andy

 

He already knows Basic (he said so in the top post)...so I'm just suggesting building upon what he already knows to help ease into assembly...which was too much to handle for him before (you are correct that some of that has to do with unlearning Basic's bad practices tho).

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...