6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 01, 2024 10:37 am

All times are UTC




Post new topic Reply to topic  [ 321 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9, 10, 11 ... 22  Next
Author Message
PostPosted: Sun Apr 09, 2017 11:21 pm 
Offline

Joined: Sat Mar 11, 2017 1:56 am
Posts: 276
Location: Lynden, WA
GBZM, I fully get that. I think you missed the gist of my question. Why do I need to st side RAM, when no one is accessing it but me?

Garth mostly cleared it up, if I'm understanding him right. Basically, it's go let the assembler do the hard work of arranging RAM usage in an organized way.


Top
 Profile  
Reply with quote  
PostPosted: Sun Apr 09, 2017 11:30 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8468
Location: Midwestern USA
Dan Moos wrote:
ok, still a little hung up on the .DS directive and its various brethren.

Does a directive like that have any use if your program is going in ROM?

Even though your firmware would be running from ROM, you still need RAM for a hardware stack, zero page pointers, indices and counters, and input/output buffers and FIFOs. All of these items must be explicitly declared in your assembly language source code. Otherwise, the MPU won't have a clue as to where to read and write things.

Quote:
I guess what still confuses me is, with my code in ROM, why would I even have to set aside any block of memory in RAM, if nothing goes anywhere in RAM that I don't specifically designate. So if I want $0200 to $02FF to be4 a buffer for instance, I could just not ever use it for anything else.

In order for your program to know that a buffer is at $0200 and extends to $02FF, you have to say so, e.g., BUF = $0200, followed by BUFEND = $02FF. Unlike high level languages, none of this is automatic in assembly language. Also, burying "magic numbers" in code, e.g., LDA $0200 instead of LDA BUFFER, is bad practice. If you later decided to relocate that buffer you will have to find every reference to that address and change it. Let the assembler do its job by explicitly assigning names to each location in RAM that you will be using. You have to declare variables in C, so do the same in assembly language and save yourself some grief. Trust me: as your program gets bigger and bigger you will be cursing yourself if you do not follow this practice.

Quote:
Also, I had read BDD's exposition of the Kowalski directives and operators. I didn't ses mention of the use of the "<" and ">" operators being used that way.

The < and > idioms for referring to the least significant and most significant bytes of a 16 bit value are almost universal in 6502 assembly language programming. Eyes and Lichty discuss their usage in their programming manual.

Attachment:
File comment: Kowalski 6502 Pseudo-Ops
asm_directives.asm [1.62 KiB]
Downloaded 70 times
Attachment:
File comment: Kowalski Logical Expressions
logical_expression_examples.asm [836 Bytes]
Downloaded 60 times

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sun Apr 09, 2017 11:40 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1948
Location: Sacramento, CA, USA
Here's a simple but non-trivial example:

http://rosettacode.org/wiki/FizzBuzz/As ... 2_Assembly

Code:
   .lf  fzbz6502.lst   
   .cr  6502   
   .tf  fzbz6502.obj,ap1
;------------------------------------------------------
; FizzBuzz for the 6502 by barrym95838 2013.04.04
; Thanks to sbprojects.com for a very nice assembler!
; The target for this assembly is an Apple II with
;   mixed-case output capabilities and Applesoft
;   BASIC in ROM (or language card)
; Tested and verified on AppleWin 1.20.0.0
;------------------------------------------------------
; Constant Section   
;         
FizzCt    =   3      ;Fizz Counter (must be < 255)
BuzzCt    =   5      ;Buzz Counter (must be < 255)
Lower    =   1      ;Loop start value (must be 1)
Upper    =   100   ;Loop end value (must be < 255)
CharOut    =   $fded   ;Specific to the Apple II
IntOut    =   $ed24   ;Specific to ROM Applesoft
;======================================================
   .or  $0f00   
;------------------------------------------------------
; The main program   
;         
main   ldx  #Lower   ;init LoopCt   
   lda  #FizzCt   
   sta  Fizz   ;init FizzCt
   lda  #BuzzCt   
   sta  Buzz   ;init BuzzCt
next   ldy  #0      ;reset string pointer (y)
   dec  Fizz   ;LoopCt mod FizzCt == 0?
   bne  noFizz   ;  yes:
   lda  #FizzCt   
   sta  Fizz   ;    restore FizzCt
   ldy  #sFizz-str   ;    point y to "Fizz"
   jsr  puts   ;    output "Fizz"
noFizz   dec  Buzz   ;LoopCt mod BuzzCt == 0?
   bne  noBuzz   ;  yes:
   lda  #BuzzCt   
   sta  Buzz   ;    restore BuzzCt
   ldy  #sBuzz-str   ;    point y to "Buzz"
   jsr  puts   ;    output "Buzz"
noBuzz   dey        ;any output yet this cycle?
   bpl  noInt   ;  no:
   txa        ;    save LoopCt
   pha        
   lda  #0      ;    set up regs for IntOut
   jsr  IntOut   ;    output itoa(LoopCt)
   pla        
   tax        ;    restore LoopCt
noInt   ldy  #sNL-str   
   jsr  puts   ;output "\n"
   inx        ;increment LoopCt
   cpx  #Upper+1   ;LoopCt >= Upper+1?
   bcc  next   ;  no:  loop back
   rts        ;  yes:  end main
;------------------------------------------------------
; Output zero-terminated string @ (str+y)
;   (Entry point is puts, not outch)
;         
outch   jsr  CharOut   ;output string char
   iny        ;advance string ptr
puts   lda  str,y   ;get a string char
   bne  outch   ;output and loop if non-zero
   rts        ;return
;------------------------------------------------------
; String literals (in '+128' ascii, Apple II style)
;         
str:   ;      string base offset
sFizz   .az   -"Fizz"   
sBuzz   .az   -"Buzz"   
sNL   .az   -#13   
;------------------------------------------------------
; Variable Section   
;         
Fizz   .da   #0   
Buzz   .da   #0   
;------------------------------------------------------
   .en        


The top three lines are housekeeping.

The Constant section contains values that don't need storage and don't change after assembly, but are named for the purpose of readability.

The String Literal section doesn't change after assembly, but does need storage allocated, so it is given a label so the assembler can place it directly after the code section. If the code section ever expands or contracts, the address of the String Literal section will change, but the assembler will automatically handle the change and modify the operands accordingly, just like it would for a branch target that moved due to a revision or addition.

The Variable section contains cells that do change during execution (the values, not the addresses), and once again the assembler is trusted to allocate space for them and keep track of their addresses as operands for the instructions using them, no matter how many times the code section may shrink or expand during subsequent revisions.

Mike B.

P.S. This is also an example of how using TABs instead of SPACEs can turn a tidy looking source into a mess, depending on where you post it. :-(


Last edited by barrym95838 on Mon Apr 10, 2017 1:03 am, edited 2 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Sun Apr 09, 2017 11:45 pm 
Offline

Joined: Sat Mar 11, 2017 1:56 am
Posts: 276
Location: Lynden, WA
your example of

Code:
BUFFER = $0200
BUFFEND = $02FF


actually points out my confusion. Doing it THAT way makes perfect sense to me. Is that completely equivalent to a .DS statement?

I wish I were better at wording my questions. Seems to be a lot of confusion over what I am asking.


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 10, 2017 12:00 am 
Offline

Joined: Sat Mar 11, 2017 1:56 am
Posts: 276
Location: Lynden, WA
Ok, in the directive list you posted, we have

Code:
.DS .RS           ;equivalent to *=*+N, where N is arg to .DS


I know what *= means. What does *=* mean?


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 10, 2017 12:17 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8534
Location: Southern California
There's nothing wrong with doing something like the BUFEND = $02FF; but if there's ever any question about how big the buffer is, I would instead tend to have a constant telling the size of the buffer, rather than a label to the last address of the buffer. Then if you ever need to move the buffer, you only have to change the one label, not both.

My original code from the interrupts primer (which I think you started with) assumes the full 256 bytes for the buffer, regardless of where it starts (as long as it's all in RAM). I did it that way partly because I do have a use for that much, and partly because it makes the routines shorter and faster if you don't have to make the pointers wrap at something else like 128 or 64, let alone numbers like 75 or 100 which take more than just ANDing-out a bit or two in binary.

The *=* is part of *="+N.
* in this case is the program counter.
*+N means "Take the program counter's current value and add N to it."
= is the assignment operator; so
the whole things means "Take the program counter, add N to it, and put the result of that addition back in the program counter. (It's like A=A+B in BASIC.)

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 10, 2017 1:47 am 
Offline
User avatar

Joined: Wed Mar 01, 2017 8:54 pm
Posts: 660
Location: North-Germany
Dan Moos wrote:
GBZM, I fully get that. I think you missed the gist of my question. Why do I need to st side RAM, when no one is accessing it but me?

Garth mostly cleared it up, if I'm understanding him right. Basically, it's go let the assembler do the hard work of arranging RAM usage in an organized way.

Dan,

sorry. I don't want to offend you. Just one counterquestion:

How should the assembler you have chosen know about your hardware, how should it know where is ROM,RAM,I/O or perhaps nothing?

I haven't heard about an assembler having a configuration and options settings section like C compilers for µCs have. These settings are part of the asm source.


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 10, 2017 2:13 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8468
Location: Midwestern USA
Dan Moos wrote:
your example of

Code:
BUFFER = $0200
BUFFEND = $02FF

actually points out my confusion. Doing it THAT way makes perfect sense to me. Is that completely equivalent to a .DS statement?

I wish I were better at wording my questions. Seems to be a lot of confusion over what I am asking.

Garth tried to unconfuse you but I'm not sure if it had the desired effect. :D Assembly language concepts can be confusing for anyone who started with a high level language, where a certain amount of behind-the-scenes automation occurs for you—BASIC is a good example of this.

Suppose you have written a keyboard input routine for your program. As the user types you have to collect keystrokes somewhere and when the user types [CR] (symbol for the return key) to "enter" his or her data, you have mark the end of the series of collected keystrokes and then go on to process the input. You collect the keystrokes in a buffer that must be large enough to hold the maximum number of keystrokes you deem to be adequate, as well as one extra space to mark the end of the string of keystrokes. Conventionally, a null ($00) is used as an end-of-string (EOS) marker. You can use whatever you want, or could even have a separate index that tells your program the offset to EOS in the buffer. You're the programmer, so it's your call.

In order to define such a buffer, you could take the following steps:

  1. Define the maximum number of keystrokes you are willing to accept. In assembly language, that definition would be encoded as maxkeys = <some_number>. For example, maxkeys = 60 means just what it says.

  2. Using the maxkeys definition, you would then define your buffer size. If you use a terminator to mark the EOS of the user's input the buffer must be one byte larger than maxkeys. So you would write bufsiz = maxkeys+1. Otherwise, bufsiz would equal maxkeys.

  3. Later on in your program, where you would be declaring dynamic storage, you would define the buffer itself as follows:

    Code:
    inputbuf *=*+bufsiz

    The above would set inputbuf to the current value of the program counter and then advance the latter by bufsiz bytes. You have now reserved 61 bytes for your input buffer. Elsewhere in your program, you can read and write your buffer by using its name, not some arbitrary address.

As you can see, nothing is automatic in assembly language. The programmer defines data structure sizes, the structures themselves, where in memory they are located, the means by which they are manipulated, etc. This characteristic of assembly language has to be understood and accepted in order to successfully write programs. Assembly language enforces no discipline on the programmer. If your thinking is disorganized so will be your program. If you think spaghetti code in BASIC is bad you ain't seen nothin' compared to what assembly language spaghetti code looks like.

Here's the above sequence recapitulated:

Code:
maxkeys  = 60                  ;maximum allowed keyboard input
bufsiz   = maxkeys+1           ;buffer size w/terminator

   ---

         * = $0200             ;set lcation to $0200 (decimal 512)
;
inputbuf *=*+bufsiz            ;define input buffer...
;
;   ———————————————————————————————————————————————————————————
;   The above statement sets the starting location of the input
;   buffer to $0200 and reserves 61 bytes.  The next storage
;   definition will be at $023D.
;   ———————————————————————————————————————————————————————————
;
flag     *=*+1                 ;this flag will be at $023D

Now, if you later on decide to accept more input you'd merely redefine maxkeys and when you reassemble your program everything that refers to maxkeys will be fixed up for you, including the size of the buffer.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 10, 2017 2:14 am 
Offline

Joined: Sat Mar 11, 2017 1:56 am
Posts: 276
Location: Lynden, WA
I realize the assembler is ignorant of the hardware outside the CPU. I understand I have to give it very specific addresses for everything. Like I said, I think you missed what I was asking.

I didn't see why I had to specifically set aside that memory, when I could just not use it for anything else. Since I'm the only one assigning memory, at the time it seemed an unnecessary step. At the time I figured, why couldn't I just label the start of the buffer, and then never assign any memory in the range "buffer + size of buffer" for non buffer use.

What I think I've learned since, is that yeah, I could do it that way, but it's way easier to let the assembler do the hard work, and more importantly, since I'm working with a size, and not specific addresses, I can change the size of the buffer without a cascade of addresses I've foolishly hard-coded becoming invalid.

Ok, that explanation of the "*" operator was what I needed. I didn't realize that "*" actually was the program counter. I thought "*=" was a single directive. Now that I know that "*" is a stand alone symbol, "*=*+N" makes perfect sense.

If that nugget is in any of the 4 books I'm working with, (including the oft cited Lichty and Eyes), I've sure missed it. You see stuff like that used, but not explained.

Like a said before, learning 6502 assembly has been ok for me so far, but I still seems like a massive research effort to find novice level explanations of assembler directives. Just as soon as I think I have a handle, someone posts a code snippet that has yet more directives that are not in common with my assembler. I'll get it, it's just frustrating because no good one stop info source seems to exist for directives.

How did things get to where there was no standard? I guess I know how these things happen, but sheesh!

I've been trying to download the WDC programming manual from their site, but it's a dead link. Anyone know where else to find it?


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 10, 2017 2:19 am 
Offline

Joined: Sat Mar 11, 2017 1:56 am
Posts: 276
Location: Lynden, WA
I crossed posts with you BDD, so sorry if it sounds like I didn't read it. :)


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 10, 2017 2:33 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8468
Location: Midwestern USA
Dan Moos wrote:
Ok, that explanation of the "*" operator was what I needed. I didn't realize that "*" actually was the program counter. I thought "*=" was a single directive. Now that I know that "*" is a stand alone symbol, "*=*+N" makes perfect sense.

The *=*+N construct is basic programming; something like it is found in many languages. If you know C you know you can write X=X+5 and the compiler will understand what you are saying. It's understanding the meaning of * that is key.

Quote:
Like a said before, learning 6502 assembly has been ok for me so far, but I still seems like a massive research effort to find novice level explanations of assembler directives. Just as soon as I think I have a handle, someone posts a code snippet that has yet more directives that are not in common with my assembler. I'll get it, it's just frustrating because no good one stop info source seems to exist for directives.

That's because there really is no standard when it comes to pseudo-ops. The only thing defined in the assembly language is the bits and pieces that actually generate code. That would be the mnemonics and address modes. MOS Technology also defined the minimum requirements for representing quantities, as well as minimum label and symbol sizes. Everything else is subject to a certain amount of interpretation by whomever writes the assembler.

Quote:
How did things get to where there was no standard? I guess I know how these things happen, but sheesh!

There is a standard for the 6502 assembly language, which was promulgated by MOS Technology way back when. WDC has continued with that standard but has added to it to accommodate new instructions and new address modes. Unfortunately, more than a few (mostly amateur-written) assemblers have appeared that don't follow the MOS/WDC standard.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 10, 2017 2:42 am 
Offline

Joined: Sat Mar 11, 2017 1:56 am
Posts: 276
Location: Lynden, WA
yup. once I realized "*" specifically represented the counter, all made sense.


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 10, 2017 3:22 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8534
Location: Southern California
Dan Moos wrote:
Ok, that explanation of the "*" operator was what I needed. I didn't realize that "*" actually was the program counter. I thought "*=" was a single directive. Now that I know that "*" is a stand alone symbol, "*=*+N" makes perfect sense.

[...] still seems like a massive research effort to find novice level explanations of assembler directives. Just as soon as I think I have a handle, someone posts a code snippet that has yet more directives that are not in common with my assembler. I'll get it, it's just frustrating because no good one stop info source seems to exist for directives.

Ok, just to add another one, hopefully ahead of time so it won't mess you up further when you see it: with some assemblers, $ by itself (not followed by hex digits) is the way to get the value of the program counter. So you might see something like
Code:
        ORG   $ + N

which is equivalent to the *=*+N that we had above. Yeah, there's definitely a lack of consistency.

Although the following is in the interrupts primer, including with an illustration, I should comment again that the RS-232 buffer as I'm using it there is a ring, a circle. There is effectively no beginning or end. You don't have to parse an input string all the way to the end before allowing a new string to start being accepted. It's kind of like a gas tank which does not need to be emptied before you put more gas in. (There's probably a better analogy to be had; but you probably get the idea.) Regardless of what's in it, if it's not full, you can add more. Just make sure you tell the sender to stop sending when the buffer is nearly full, so you don't overflow it, ie, you don't overwrite the oldest material in it that's still waiting to be handled.

Also, there's no requirement that the incoming data all be in strings, whether counted or null-terminated. It might for example start with a string to tell it that the next 913 bytes are binary program material to put in memory starting at address xyz. After that many bytes have come in, the next bytes might again be a string giving the computer the next instruction.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Buffers, FIFOs & LIFOs
PostPosted: Mon Apr 10, 2017 4:51 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8468
Location: Midwestern USA
GARTHWILSON wrote:
Ok, just to add another one, hopefully ahead of time so it won't mess you up further when you see it: with some assemblers, $ by itself (not followed by hex digits) is the way to get the value of the program counter. So you might see something like

Code:
        ORG   $ + N

which is equivalent to the *=*+N that we had above. Yeah, there's definitely a lack of consistency.

That is very non-standard. None of the assemblers I have ever used in the past 40 years has used the dollar sign to represent the program counter. I would find that usage to be counter-intuitive.

Quote:
Although the following is in the interrupts primer, including with an illustration, I should comment again that the RS-232 buffer as I'm using it there is a ring, a circle...It's kind of like a gas tank which does not need to be emptied before you put more gas in...

This is more directed to Dan, since Garth already knows this.

In assembly language, it's helpful to think of the structure to which Garth is referring as a FIFO (first-in, first-out), not a buffer. In academic terms, a buffer is a temporary storage structure in which the structure's logical beginning and end are the same as its physical beginning and end. You would use a buffer for collecting typed input, storing a disk block, etc.

On the other hand, a FIFO's logical beginning and end is constantly moving—hence the FIFO is "circular." An index is maintained somewhere to tell the program using the FIFO where the logical beginning is located within the FIFO's boundaries. The same index implies the location of the logical end, which is one less than the beginning. Typically that index is zero-based and is added to the starting address of the FIFO to get the actual address of the logical beginning. As you develop your TIA-232 driver routines you will get very up close and personal with FIFOs.

A stack, whether hardware or software, is a LIFO (last-in, first-out) structure and as is the case with the FIFO, the logical beginning and end constantly moves—making a FIFO "circular." Considering a hardware stack as in the 6502 family, each push to the stack decrements the stack pointer (SP) after the byte has been written to the stack (SP is postdecremented). If a push occurs while SP is $00 the pushed byte will be stored at $0100 (in the eight bit MPUs) and SP will wrap to $FF. Pulling a byte will increment SP before the byte is read from the stack and if SP is $FF when a byte is pulled SP will wrap to $00. Software stacks work in essentially the same fashion, but the "stack pointer" is (sometimes laboriously) maintained in software.

Quote:
Also, there's no requirement that the incoming data all be in strings, whether counted or null-terminated. It might for example start with a string to tell it that the next 913 bytes are binary program material to put in memory starting at address xyz. After that many bytes have come in, the next bytes might again be a string giving the computer the next instruction.

That's true. However, the term "string" most often means "character string," since such data are usually treated as a single entity, e.g., someone's name in a database. What Garth is referring to is commonly referred to in systems software engineering as a "stream," which means it is a series of bytes that individually stand on their own. An example of a stream would be a Motorola S-record, which represents binary values in a (more or less) human-readable format.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 10, 2017 5:48 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8534
Location: Southern California
BigDumbDinosaur wrote:
GARTHWILSON wrote:
Ok, just to add another one, hopefully ahead of time so it won't mess you up further when you see it: with some assemblers, $ by itself (not followed by hex digits) is the way to get the value of the program counter. So you might see something like

Code:
        ORG   $ + N

which is equivalent to the *=*+N that we had above. Yeah, there's definitely a lack of consistency.

That is very non-standard. None of the assemblers I have ever used in the past 40 years has used the dollar sign to represent the program counter. I would find that usage to be counter-intuitive.

All three commercial macro assemblers I've used use the $ to return the current value of the program counter:
  • Cross-32 (C32) originally from Universal Cross-Assemblers. I've used it for 65c02 and '816, but it's also good for lots of other processors. I bought it in the mid-1990's for $99.
  • the 2500AD assembler which I've used for 65c02. My employer paid $250 for in about 1987.
  • Microchip's MPASM assembler for PIC microcontrollers.

My Forth macro assembler (which is simple enough that I wrote it in its original version in one evening), since it's in Forth, uses HERE to put the value of the dictionary pointer (ie, the next address available for code or data) on the data stack. That's not a commercial assembler, but I'm sure you would find everyone else's Forth assemblers using HERE also.

Quote:
In assembly language, it's helpful to think of the structure to which Garth is referring as a FIFO (first-in, first-out), not a buffer. [...]

The ring buffer, or circular buffer, is made (in software) to act as a FIFO, but there's no shift-register action moving data from one end to the other; and if you wanted to violate your own software rules, you could indeed dive into the middle or any part you wanted to. https://en.wikipedia.org/wiki/Circular_buffer


Quote:
Quote:
Also, there's no requirement that the incoming data all be in strings, whether counted or null-terminated. It might for example start with a string to tell it that the next 913 bytes are binary program material to put in memory starting at address xyz. After that many bytes have come in, the next bytes might again be a string giving the computer the next instruction.

That's true. However, the term "string" most often means "character string," since such data are usually treated as a single entity, e.g., someone's name in a database. What Garth is referring to is commonly referred to in systems software engineering as a "stream," which means it is a series of bytes that individually stand on their own. An example of a stream would be a Motorola S-record, which represents binary values in a (more or less) human-readable format.

Yes; the 913 bytes in the example would not be a string. Motorola S records and Intel Hex do come in text strings. The 913 bytes of binary program material I gave as an example would not be human-readable, and will undoubtedly include 00 bytes, and $0D bytes (which is <CR> in ASCII), and $0A bytes (which is <LF> in ASCII), which would be confused for terminators if it were taken as a string. I have a description of how Intel Hex files work at http://wilsonminesco.com/16bitMathTables/IntelHex.html, and an example of one is at http://wilsonminesco.com/16bitMathTables/ATAN.HEX (although it's an arctangent table, not code).

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 321 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9, 10, 11 ... 22  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: