💾 Archived View for spam.works › mirrors › textfiles › programming › address.txt captured on 2023-11-14 at 11:47:14.

View Raw

More Information

⬅️ Previous capture (2023-06-16)

-=-=-=-=-=-=-

      ====================================================================
	DR  6502    AER 201S Engineering Design 6502 Execution Simulator
      ====================================================================

      Supplementary Notes                                   By: M.J.Malone

      
      	      Addressing Modes - The Meaning of Arg, Offset and Dest
      	      ======================================================
      
	   Arg,  Offset  and  Dest   are   the   arguments   for   various
      instructions.   Since  the  arguments  of  instructions  are usually
      referred to by their addresses, the different methods of  expressing
      arguments  are called addressing modes.  'Arg' type addressing modes
      refer to a piece of data  usually  by  its  address.   The  'Offset'
      addressing  mode  is  used  by  branch  statements to give a program
      destination by an offset byte.  'Dest' addressing modes are used  to
      point to a destination in the program.


      The Use of Labels
      =================

	   Assembly  code  more  often  uses  assembler labels than actual
      numbers as arguments to increase the readability.  In the  following
      example  the  address  of  the  VIA  port,  a  commonly  used memory
      location, will be assigned a descriptive  name  to  make  its  later
      occurrences in assembly code more legible:
 
      ;
      Port_A = $A001
      ;
 
      Here  is  another  example  where a label is assigned the value of a
      commonly used constant for improved readability:
 
      ;
      MotorBit_Mask = %0000111
      ;
 
	   The use of labels can vastly change the appearance of  assembly
      but does not alter the behavior of addressing modes at all.
 
      The Addressing Modes
      ====================
 
      If there are No Arguments:
      --------------------------
 
 
      0) Implied
 
	   Some  instructions (ie.  CLC, SEC, CLD, NOP, BRK, PHA, RTI, RTS
      etc) do not require arguments.  In this case the argument is said to
      be 'IMPLIED'  in  the  instruction.   This  is  called  the  implied
      addressing mode.
 
      In Assembly:       CLC
 
 
 
 
 
 
 
 
 
                                                            page 2 
 
      'Arg':  Refers to a place to find data, usually a memory location
      -----------------------------------------------------------------
 
 
      1) Accumulator
 
	   The vast majority of statements manipulate data in one  way  or
      another and require data for arguments.  The first and easiest piece
      of  data  to  use  as  an  argument is the .A accumulator.  Operator
      instructions such as ROL, ROR, ASL and LSR (and INC and DEC  in  the
      65C02) can use the ACCUMULATOR addressing mode.
 
      In Assembly:       ROR A
 
 
 
      2) Immediate
 
	   Often a constant (a number) is required in  calculations.   LDA
      #$00  takes  the  number  (#)  $00 and places it in the accumulator.
      This  is  called  the  IMMEDIATE  addressing  mode.   The  following
      statements can be used with the immediate addressing mode: ADC, AND,
      CMP, CPX, CPY, EOR, LDA, LDX, LDY, ORA and SBC.
 
      In Assembly:  ADC #$01
		    LDA #Constant
		    EOR #Bit_Mask
		    CMP #5
 
 
      3) Zero Page
 
	   The  memory  of  the  6502  is divided into $100 (256) pages of
      $100 (256) bytes each.  The pages are numbered from 0  through  $FF.
      Page  0  address  are in the range $0000-$00FF.  Because 'Zero Page'
      addresses can be specified in just one byte, instructions using them
      as arguments  can  be  executed  more  quickly  by  the  6502.   The
      statement  LDA  $80  causes  the 6502 to fetch the value from memory
      location $0080 and place it in the accumulator.  Note that the  only
      difference  between  the  immediate  and  zero  page syntax is the #
      number sign.  LDA #$80 means  load  the  number  (#)  $80  into  the
      accumulator.   LDA  $80  means  load the contents of memory location
      $0080  into  the  accumulator.   When  reading  assembly  code,  the
      difference  is  subtle but very important.  Zero page addressing can
      be used with every instruction  that  uses  a  data  type  argument.
      (This  excludes  only those that use no argument: CLC, RTI, NOP etc.
      or a program go to type argument JMP xxxx, JSR xxxx etc.)
 
      In Assembly: ADC $80
		   LDA Temp        ( Assuming  $00 <= Temp <= $FF )
 
 
      4) X and Y Indexed Zero Page
 
	   Often data is organized into groups of bytes  as  a  table,  an
      array  or  a  record.   In  this case it is convenient to specify an
      address  as  an  offset  relative  to  the  beginning  of  the  data
 
 
 
 
 
 
 
                                                            page 3 
 
      structure.    The   6502   implements   this  method  using  INDEXED
      addressing.  In this case the .X or .Y register is used to add to  a
      zero  page address to result in an effective address.  IE: LDA $80,X
      (when  .X=#$05)  results   in   a   fetch   from   memory   location
      ($0080+$05)=$0085.    This   is  called  the  ZERO  PAGE  X  INDEXED
      addressing mode.  The zero page x indexed  addressing  mode  can  be
      used  with all instructions except BIT, CPX, CPY, LDX and STX.  Note
      that the .X and .Y registers can take on values of only  $00-$FF  so
      the data table is limited in size to $100 bytes.
 
	   There  is also a Y indexed zero page addressing mode but it can
      be used only with the LDX and STX instructions.  This may seem  very
      limiting at first but consider the high level expression:
 
	   code = Data[ Index_Pointer[i] ];
 
      Where  Index_Pointer[]  is a small look-up table of pointers to data
      in the look-up table Data[].  This can be coded easily as:
 
		  LDY i
		  LDX Index_Pointer,Y
		  LDA Data,X
		  STA code             ;  14 machine cycles total
 
      Note that indexed zero page addressing cannot result in an effective
      address outside the zero page.  If the sum of the value  in  the  .X
      register  and  the  base address exceed $FF then the fetch will wrap
      around to $00 again.  For example if the .X register were #$20  then
      the following memory fetch 'LDA $F0,X' would result in the effective
      address  of  ($00F0+$20)=$0110 but the memory fetch would be done on
      address $0010, still on the zero page.
 
	   Note that indexed zero page addressing always takes one machine
      cycle more than non-indexed zero page addressing and hence should be
      avoided.  Often programmers get  in  the  habit  of  creating  small
      indexed loops to perform operations resulting in a shorter length of
      assembly   code.   In  the  case  of  mathematics  subroutines  that
      manipulate multibyte numbers on the zero page, loops should never be
      used.  The extra overhead required in the INcrement or DEcrement and
      the Branch instructions as well as the extra machine cycle  in  each
      indexed  reference can make these routines take almost twice as long
      to execute as the unravelled equivalent  non-indexed  routines.   5)
      Absolute
 
	    Usually  arguments  are  not  stored only on the zero page but
      come from anywhere in memory.  The easiest way to specify a  general
      memory  address is to give the full 16 bit address.  For example LDA
      $8000, loads the 8 bit number ($00-$FF)  from  the  memory  location
      $8000.   This method of specifying an address is called the ABSOLUTE
      addressing mode.
 
      In Assembly:       LDA Port_A
			 ADC $C000
 
 
 
 
 
 
 
 
 
 
 
                                                            page 4 
 
      6) X and Y Indexed Absolute
 
	   As with  zero  page  addressing,  absolute  addressing  can  be
      indexed  as well allowing the entire address space of the 6502 to be
      used in data tables.  The X indexed absolute addressing mode may not
      be used with: BIT, CPX, CPY, LDX, STX or STY but may  be  used  with
      LDY.  The Y indexed absolute addressing has a similar list except it
      can  be used for LDX and not LDY and cannot be used for the operator
      instructions ASL, DEC, INC, LSR, ROL or ROR.
	   The absolute X and Y indexed addressing modes require the  SAME
      number  of clock cycles to perform as the non-indexed absolute mode.
      There is therefore NO PENALTY in access time for referring  to  data
      as  part  of  a  table  through indexed addressing in absolute mode.
      There is of course the INcrement or DEcrement statement, the  Branch
      and possibly the ComParison to create the indexed loop that requires
      more time over sequential, direct, absolute fetches.  The large size
      of   data  tables  located  outside  the  zero  page  usually  makes
      sequential absolute fetches impractical since the number of assembly
      language statements is directly dependent on the size of the  table.
      If the size of the table is variable then indexing must be used.  It
      is  often desirable therefore to use indexed absolute addressing and
      data tables to organize data and  reduce  the  length  of  the  code
      through indexed loops.
	   There  are  exceptions  to the above statement that indexed and
      non-indexed absolute addressing require the same number of cycles to
      execute.  The first exception is the use  of  X  indexing  with  the
      operator  instructions  (Y indexing is not available) ASL, DEC, INC,
      LSR, ROL and ROR.  For  these  instructions,  the  indexed  absolute
      addressing  mode  always takes one additional cycle over the regular
      absolute addressing mode.
	   The second exception has to do with memory pages.  For absolute
      indexed addressing, if the effective address calculation crosses  to
      the  next  memory  page then an additional machine cycle is required
      for the calculation of the effective address.  If  the  .Y  register
      is  #$80  then  the  memory  fetch 'LDA $80C0,Y' crosses from memory
      page $80 into memory page $81, since the effective address is $8140,
      and therefore requires an extra machine cycle  to  perform.   It  is
      recommended  that  data tables be placed entirely on one memory page
      whenever possible to speed  program  execution.
 
      In Assembly:  LDA Game_Board,X
		    STA $1000,Y
 
 
      7) Indirect
 
	   The indirect addressing mode is available on  the  65C02  only.
      In  this  mode  a  pointer  is used to point to an address where the
      actual data is  stored.   The  16  bit  pointer  is  stored  in  two
      consecutive  memory locations on the zero page.  The indirect memory
      fetch 'LDA ($80)' causes the 6502 to look at memory locations  $0080
      and  $0081  to  form  a  16  bit  address.  Memory location $0080 is
      interpreted as the low byte of the address and  $0081  as  the  high
      byte.   If  the memory locations $0080 and $0081 hold the values $00
      and $20 respectively then the vector  ($80)  is  said  to  point  to
      address $2000.  This method of indirection is standard in high level
 
 
 
 
 
 
 
 
                                                            page 5 
 
      languages  and  is  very  useful  for pointer operations as in the C
      programming language.  The indirect addressing mode is used only for
      the ADC, AND, CMP, EOR, LDA, ORA, SBC and STA.
 
 
      In Assembly:   LDA ($80)
		     STA (Data_Pointer)
 
 
      8) Indexed Indirect
 
	   This addressing mode is used for tables of  pointers  to  data.
      Only  the  X  index  register  can  be used for the indexed indirect
      addressing mode.  In this case the .X  register  indexes  through  a
      data  table  that  is  interpreted  as  16  bit  pointers.  If the X
      register is $04 then the statement: LDA ($80,X) takes  value  stored
      in  ($0080+$04)=$0084  as the low byte of the 16 bit pointer and the
      value in $0085 as the high byte of the pointer.  If the vector fetch
      address exceeds $FF then it wraps around to $00  again  as  in  zero
      page  indexed addressing.  Note that the X register can only take on
      meaningful values as an even number since each pointer is two  bytes
      long.   One  can  easily remember how this mode works by remembering
      that it is called 'Indexed Indirect'  where  the  indexing  is  done
      first and then the indirect pointer interpretation is done.  Indexed
      indirect  addressing  is used only for ADC, AND, CMP, EOR, LDA, ORA,
      SBC and STA.  Page boundaries have no effect on the indexed indirect
      addressing mode.
 
 
      In Assembly:       LDA ($80,X)
			 ADC (Array_of_Pointers,X)
 
 
      9) Indirectly Indexed
 
	   This  addressing mode is used to index within a data table that
      is pointed to by a vector on the zero page.  Only the Y register can
      be used for the indirectly indexed address mode.   In  this  case  a
      vector  on the zero page points to the first address in a data table
      and then the Y  register  indexes  through  the  table.   If  the  Y
      register  is  $04 and $0080 and $0081 contain the values $00 and $20
      respectively then the instruction 'LDA ($80),Y'  first  fetches  the
      vector  at $0080 and $0081 which points to $2000.  The Y register is
      then added for an effective fetch address of ($2000+$04)=$2004.  One
      can easily remember how this mode works by remembering  that  it  is
      called  'Indirectly  Indexed'.   This mode does the indirect pointer
      interpretation first and then  performs  the  indexing.   Indirectly
      indexed  addressing  is  used only for ADC, AND, CMP, EOR, LDA, ORA,
      SBC and STA.
	   Page boundaries do effect the indirectly indexed address  mode.
      If  the  Y index causes the effective address to cross into the next
      memory page then the fetch requires an additional machine cycle.
	   The indirectly indexed  addressing  mode  is  very  useful  for
      accessing  very  large  arrays  of data.  When the size of the array
      surpasses the $00-$FF limit of the Y index register, the high  order
      byte of the pointer can be incremented to point into the next memory
 
 
 
 
 
 
 
 
                                                            page 6 
 
      page.   The  following  is  an  example  of  addressing such a large
      array.
 
      ;
		  LDY #$00
      Next_Char   LDA (String_of_Char),Y   ; Get the character from the
					   ; string
		  BEQ End_Of_String        ; String ends with a NULL - #$00
		  JSR Print_Char           ; A Subroutine to print
					   ; characters
		  INY                      ; Go on to next character
		  BNE Next_Char            ; If have not finished the page
					   ; - Next
		  INC String_of_Char+1     ; Finished page - Point to next
					   ; page
		  JMP Next_Char            ; Go on to first char of next
					   ; page
      ;
      ;
      End_Of_String
 
 
 
      'Offset':  Branch Destination
      -----------------------------
 
 
      10) Relative
 
	   The relative addressing mode is used by the Branch  statements:
      BCC,  BCS,  BEQ,  BMI,  BNE, BPL, BRA, BVC and BVS.  The argument in
      this case uses one byte as an offset byte.  This offset byte  allows
      the  branch  instruction  to  branch up to 128 bytes forward and 127
      bytes backward in the program machine code.  This must seem  like  a
      very  'coded',  inconvenient,  method of doing things.  In actuality
      this is taken care of by the assembler.   This  is  one  case  where
      assembler  directives are used to make life easy for the programmer.
      The programmer must however keep in mind that there  are  limits  to
      the range of relative branches when using them.  The following is an
      example of the assembly code use of a relative branch statement:
 
      ;
      Check_Again LDA Port_A       ; Wait for a bit to go high on Port A
		  BEQ Check_Again
      ;
 
      In  this  example,  the  assembler records the position of the label
      'Check_Again'.  When the  label  is  used  in  the  relative  branch
      statement  'BEQ'  the  ASSEMBLER calculates the required offset byte
      for the relative addressing mode used  for  the  argument  of  'BEQ'
      instruction.
	   For  the  user, the only worry is a 'Branch Out of Range Error'
      at assembly time.  If this occurs, then the logic of the branch must
 
 
 
 
 
 
 
 
 
 
 
                                                            page 7 
 
      be reversed and a JuMP statement used.  For example:
 
      ;
		  BEQ Where_to_Go  ; <=== This branch is out of range
      ;
 
      becomes:
 
      ;
		  BNE Continue_On  ; <=== This branch is short - No problem
		  JMP Where_to_Go  ; <=== JMP instructions are never out of
				   ;       range
      Continue_On
      ;
 
      The addition of the BRA - branch always statement to  the  65C02  is
      very  helpful.  If the user knows that the length of a JMP is within
      range of a branch, it can be converted to a 'BRA Label'  instruction
      saving  one  machine  cycle,  critical on maximum repeat rate loops.
 
 
      'Dest':  Jump Destination
      -------------------------
 
      11) Absolute
 
	   This addressing mode is exactly  the  same  in  syntax  as  the
      absolute addressing mode (see 5 above) except the memory location is
      not  used  as  a data argument as before but as a memory location at
      which to find the next instruction  operation  code.   The  absolute
      mode  is  used by the JMP and JSR instructions and is not influenced
      by memory pages.  Once again as in the relative addressing mode, the
      ASSEMBLER keeps track of actual addresses within  programs  and  the
      program merely communicates their desires through the use of labels.
 
 
      In Assembly:      JMP Try_Another
			JSR Print_a_Char
			JMP $E000
 
 
      12) Absolute Indirect
 
	   This  addressing  mode is used by the JuMP statement to jump to
      an address pointed to by a  vector.   The  vector,  similar  to  the
      pointers  used  in  indirect  data addressing, is stored as a 16 bit
      pointer, low byte and  high  byte.   The  vector  used  in  absolute
      indirect   addressing   may  be  located  anywhere  in  memory,  not
      necessarily based on the zero page as with  indirect  data  argument
      addressing.  The following is an example:
 
      ;
		  JMP ($2000)
		  JMP (Prog_Start_Vector)
		  JMP ($FFFC)               ; Simulate a Reset
      ;
      Note  that  the address given in the instructions is an absolute, 16
      bit address.
 
 
 
 
 
 
                                                            page 8 
 
      13) Indexed Absolute Indirect
 
	   This addressing mode is also used by the JuMP statement to jump
      to an address pointed to by a vector.  As in absolute indirect,  the
      vector  is  stored  as  a 16 bit pointer, the low byte then the high
      byte.  In indexed absolute indirect addressing, the  X  register  is
      used  to  index a table of JuMP vectors in very much the same way as
      Indexed Indirect (mode 8) data addressing indexes a  table  of  data
      pointers.   Unlike  the absolute indirect address mode, the table of
      jump vectors must be based on the zero page.  The  following  is  an
      example:
 
      ;
		  LDX Control_Var
		  JMP (On_Goto_List,X)
      ;
 
      This is an example of using the indexed absolute indirect addressing
      mode  to  simulate  a BASIC 'ON GOTO' statement, similar to the case
      and switch statements of structured languages.
 
      In Assembly:      JMP ($80,X)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                                                            page 9 
 
      Summary Table of Addressing Modes
      ---------------------------------
 
      Type of Addressing    Example          Comments
      =====================================================================
       Implied              CLC          What no arguments is called
 
       Accumulator          ROR A        When the .A accumulator is the arg
       Immediate            LDA #$00     When a (#) number is the argument
       Zero Page            LDA $00      When an address <$100 is used
       Zero Page,X          LDA $00,X    Indexes a table starting at <$100
       Zero Page,Y          LDX $00,Y    Indexes a table starting at <$100
       Absolute             LDA $1000    When a general address is used
       Absolute,X           LDA $1000,X  Indexes a table anywhere in memory
       Absolute,Y           LDA $1000,Y  Indexes a table anywhere in memory
      *Indirect             LDA ($80)    Uses $80, $81 as a pointer to arg
       Indexed Indirect     LDA ($80,X)  For a table of pointers to arg
       Indirectly Indexed   LDA ($80),Y  For a pointer to a table of args
 
       Relative             BEQ $FE      For relative branches
 
       Absolute             JMP $E000    JMPs to a particular address
       Absolute Indirect    JMP ($0080)  Uses $80,$81 as a JMP vector
      *Indexed Absolute
		  Indirect  JMP ($80,X)  Uses a table of JMP vectors
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                                                            page 10 
 
      Summary of Addressing Mode Restrictions:
      ----------------------------------------
 
	   The instruction classes are listed from the most to  the  least
      limiting  and the modes available or unavailable to each instruction
      class.  Simply, BIT, TRB and TSB, the bit manipulating  instructions
      are  most  restrictive.   CPx, LDx and STx for the X and Y registers
      are next most restrictive.  The operator instructions ASL, ROR, ROL,
      LSR, INC and DEC are next  most  restrictive.   The  arithmetic  and
      logical  instructions:  ADC,  AND, EOR, ORA, SBC and the accumulator
      LDA, CMP and STA are least restrictive.
 
 
      Instructions            6502                          65C02
      ====================================================================
 
 
	BIT             Zero Page and      Added: Immediate, and X indexed
			Absolute only              Zero Page and Absolute
 
 
 
	TRB, TSB                            Zero Page and Absolute only
 
 
 
	CPX, CPY        Immediate, Zero Page
      			and Absolute only
 
 
 
	STX              Zero Page,Y \
      				      Zero Page and Absolute
	STY              Zero Page,X /
 
 
 
	STZ                                       Absolute, Zero Page and
					 X indexed Absolute and Zero Page
 
 
 
	LDX               Y indexed Zero Page and Absolute \
							   and:
	LDY               X indexed Zero Page and Absolute /
 
			  Immediate, Zero Page and Absolute
 
 
 
 
	ASL, LSR,         Accumulator, Zero Page,
	ROR, ROL          Absolute, X indexed
      			Zero Page and Absolute
 
 
 
 
 
 
 
 
 
 
                                                            page 11 
 
	DEC, INC,       Zero Page, Absolute and     Added: Accumulator
      			X indexed Zero Page and
      			Absolute
 
 
 
	STA             All except Immediate
			      and:
						     Added: Indirect
 
	ADC, AND, CMP,  All except Accumulator
	EOR, LDA, ORA,    and Zero Page,Y
        SBC