6502 Assembler (part 1 of 3)

Eric C. Brown brownc at utah-cs.UUCP
Sat May 4 01:49:59 AEST 1985


# Due to overwhelming demand, (15 requests in 3 days), here is the 6502
# assembler in C:

#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	assmtest
#	assmtest.l
#	makefile
#	user.nr
# This archive created: Tue Apr  2 14:21:42 1985
# By:	James Van Ornum (AT&T-Bell Laboratories)
export PATH; PATH=/bin:$PATH
if test -f 'assmtest'
then
	echo shar: over-writing existing file "'assmtest'"
fi
cat << \SHAR_EOF > 'assmtest'
;******************************************
; Test file for the 6502 assembler - as6502
; assemble as
;     as6502 -nisv assmtest
; and compare output with assmtest.l
;******************************************
;; comment treatment
;******************************************
aa = $10; ';' immediately after the '0'
B = $20 space to comment subfield
C = $30	tab to comment subfield
DEFGHIjkl = $FFEE
D =DEFGHIjkl
;******************************************
; Number formats
;******************************************
start *= $4 ; location counter adjust
 .byte %0101 ; binary number
 .byte 022, at 22 ; octal numbers - two forms
 .byte 22 ; decimal number
 .byte $22,$ff,$FF ; hex - upper/lower case
 .byte 'a,'b ; single ASCII characters
;******************************************
;; ASCII character string
;******************************************
 .byte "abcd\t\n",0 ;   tab and new line escaped
;******************************************
; Operation checks
;******************************************
 .word aa+B ; addition
 .word aa-B ; subtraction
 .word aa*B ; multiplication
 .word B/aa ; division
 .word C%B ; modulo
 .word B^C ; exclusive OR
 .word ~C ; one's complement
 .word B&C ; logical AND
 .word aa|B ; logical OR
 .word <D ; low byte
 .word >D ; high byte
 .word * ; current location
 .word aa,B,C
 .word B*[aa+C] ; one level of parenthesis
 .dbyt D ; high byte-low byte word
 .word D/256,D%256
;******************************************
; Addressing Mode Check
;******************************************
 *=$0100
 lda =aa ; immediate addressing
 lda #aa ; immediate addressing, alternate
 lda D ; direct addessing
 LDA aa ; page zero addressing, aa < 256
a1 = 512
a2 = 500
 lda a1-a2 ; also page zero
 asl A ; accumulator addressing
 AsL a ; accumulator addressing also
 brk ; implied addressing
 lda (aa,X) ; indirect,X addressing
 lda (aa),Y ; indirect,Y addressing
 lda aa,X ; zero page,X addressing
 lda D,X ; absolute,X addressing
 lda D,Y ; absolute,Y addressing
 bcc *-$10 ; relative addressing
 jmp (D) ; indirect addressing
 ldx aa,Y ; zero page,Y addressing
 ldx aa,y ; alternate index name
 .nlst
;******************************************
; opcode check
;******************************************
 adc =01
 and =01
 asl A
 bcc *+2
 bcs *+2
 beq *+2
 bit $01
 bmi *+2
 bne *+2
 bpl *+2
 brk
 bvc *+2
 bvs *+2
 clc
 cld
 cli
 clv
 cmp =01
 cpx =01
 cpy =01
 dec $01
 dex
 dey
 eor =01
 inc $01
 inx
 iny
 jmp *+3
 jsr *+3
 lda =01
 ldx =01
 ldy =01
 lsr A
 nop
 ora =01
 pha
 php
 pla
 plp
 rol A
 ror A
 rti
 rts
 sbc =01
 sec
 sed
 sei
 sta $01
 stx $01
 sty $01
 tax
 tay
 tsx
 txa
 txs
 tya
SHAR_EOF
if test -f 'assmtest.l'
then
	echo shar: over-writing existing file "'assmtest.l'"
fi
cat << \SHAR_EOF > 'assmtest.l'
as6502 - version 4.1 - 11/5/84 - JHV
   1                   ;******************************************
   2                   ; Test file for the 6502 assembler - as6502
   3                   ; assemble as
   4                   ;     as6502 -nisv assmtest
   5                   ; and compare output with assmtest.l
   6                   ;******************************************
   7                   ;                      ; comment treatment
   8                   ;******************************************
   9         0010      aa      =     $10      ; ';' immediately after the '0'
  10         0020      B       =     $20      space to comment subfield
  11         0030      C       =     $30      tab to comment subfield
  12         FFEE      DEFGHIjkl =   $FFEE
  13         FFEE      D       =DEFGHIjkl
  14                   ;******************************************
  15                   ; Number formats
  16                   ;******************************************
  17         0004      start   *=    $4        ; location counter adjust
  18  0004   05                .byte %0101     ; binary number
  19  0005   12 12             .byte 022, at 22   ; octal numbers - two forms
  20  0007   16                .byte 22        ; decimal number
  21  0008   22 FF FF          .byte $22,$ff,$FF  ; hex - upper/lower case
  22  000B   61 62             .byte 'a,'b     ; single ASCII characters
  23                   ;******************************************
  24                   ;                      ; ASCII character string
  25                   ;******************************************
  26  000D   61 62 63          .byte "abcd\t\n",0  ;   tab and new line escaped
      0010   64 09 0A  
      0013   00        
  27                   ;******************************************
  28                   ; Operation checks
  29                   ;******************************************
  30  0014   30 00             .word aa+B      ; addition
  31  0016   F0 FF             .word aa-B      ; subtraction
  32  0018   00 02             .word aa*B      ; multiplication
  33  001A   02 00             .word B/aa      ; division
  34  001C   10 00             .word C%B       ; modulo
  35  001E   10 00             .word B^C       ; exclusive OR
  36  0020   CF FF             .word ~C        ; one's complement
  37  0022   20 00             .word B&C       ; logical AND
  38  0024   30 00             .word aa|B      ; logical OR
  39  0026   EE 00             .word <D        ; low byte
  40  0028   FF 00             .word >D        ; high byte
  41  002A   2A 00             .word *         ; current location
  42  002C   10 00             .word aa,B,C
      002E   20 00     
      0030   30 00     
  43  0032   00 08             .word B*[aa+C]  ; one level of parenthesis
  44  0034   FF EE             .dbyt D         ; high byte-low byte word
  45  0036   FF 00             .word D/256,D%256
      0038   EE 00     
  46                   ;******************************************
  47                   ; Addressing Mode Check
  48                   ;******************************************
  49         0100              *=$0100
  50  0100   A9 10             lda   =aa       ; immediate addressing
  51  0102   A9 10             lda   #aa       ; immediate addressing, alternate
  52  0104   AD EE FF          lda   D         ; direct addessing
  53  0107   A5 10             LDA   aa        ; page zero addressing, aa < 256
  54         0200      a1      =     512
  55         01F4      a2      =     500
  56  0109   A5 0C             lda   a1-a2     ; also page zero
  57  010B   0A                asl   A         ; accumulator addressing
  58  010C   0A                AsL   a         ; accumulator addressing also
  59  010D   00                brk            ; implied addressing
  60  010E   A1 10             lda   (aa,X)    ; indirect,X addressing
  61  0110   B1 10             lda   (aa),Y    ; indirect,Y addressing
  62  0112   B5 10             lda   aa,X      ; zero page,X addressing
  63  0114   BD EE FF          lda   D,X       ; absolute,X addressing
  64  0117   B9 EE FF          lda   D,Y       ; absolute,Y addressing
  65  011A   90 EE             bcc   *-$10     ; relative addressing
  66  011C   6C EE FF          jmp   (D)       ; indirect addressing
  67  011F   B6 10             ldx   aa,Y      ; zero page,Y addressing
  68  0121   B6 10             ldx   aa,y      ; alternate index name
  70                   ;******************************************
  71                   ; opcode check
  72                   ;******************************************
  73  0123   69 01             adc   =01
  74  0125   29 01             and   =01
  75  0127   0A                asl   A
  76  0128   90 00             bcc   *+2
  77  012A   B0 00             bcs   *+2
  78  012C   F0 00             beq   *+2
  79  012E   24 01             bit   $01
  80  0130   30 00             bmi   *+2
  81  0132   D0 00             bne   *+2
  82  0134   10 00             bpl   *+2
  83  0136   00                brk
  84  0137   50 00             bvc   *+2
  85  0139   70 00             bvs   *+2
  86  013B   18                clc
  87  013C   D8                cld
  88  013D   58                cli
  89  013E   B8                clv
  90  013F   C9 01             cmp   =01
  91  0141   E0 01             cpx   =01
  92  0143   C0 01             cpy   =01
  93  0145   C6 01             dec   $01
  94  0147   CA                dex
  95  0148   88                dey
  96  0149   49 01             eor   =01
  97  014B   E6 01             inc   $01
  98  014D   E8                inx
  99  014E   C8                iny
 100  014F   4C 52 01          jmp   *+3
 101  0152   20 55 01          jsr   *+3
 102  0155   A9 01             lda   =01
 103  0157   A2 01             ldx   =01
 104  0159   A0 01             ldy   =01
 105  015B   4A                lsr   A
 106  015C   EA                nop
 107  015D   09 01             ora   =01
 108  015F   48                pha
 109  0160   08                php
 110  0161   68                pla
 111  0162   28                plp
 112  0163   2A                rol   A
 113  0164   6A                ror   A
 114  0165   40                rti
 115  0166   60                rts
 116  0167   E9 01             sbc   =01
 117  0169   38                sec
 118  016A   F8                sed
 119  016B   78                sei
 120  016C   85 01             sta   $01
 121  016E   86 01             stx   $01
 122  0170   84 01             sty   $01
 123  0172   AA                tax
 124  0173   A8                tay
 125  0174   BA                tsx
 126  0175   8A                txa
 127  0176   9A                txs
 128  0177   98                tya

aa                  	10:00	0010
B                   	20:00	0020
C                   	30:00	0030
DEFGHIjkl           	EE:FF	FFEE
D                   	EE:FF	FFEE
start               	04:00	0004
a1                  	00:02	0200
a2                  	F4:01	01F4
SHAR_EOF
if test -f 'makefile'
then
	echo shar: over-writing existing file "'makefile'"
fi
cat << \SHAR_EOF > 'makefile'
as6502:		assm0.o assm1.o assm2.o assm3.o
		cc -s -i assm0.o assm1.o assm2.o assm3.o -o as6502

assm0.o:	assm.d1 assm.d2 assm0.c
		cc -c -O assm0.c

assm1.o:	assm.d1 assm.d2 assm1.c
		cc -c -O assm1.c

assm2.o:	assm.d1 assm.d2	assm2.c
		cc -c -O assm2.c

assm3.o:	assm.d1 assm.d2 assm3.c
		cc -c -O assm3.c

check:		assmtest.l

assmtest.l:	as6502
		as6502 -nisv assmtest > temp
		touch assmtest.l
		diff assmtest.l temp

manuals:	as6502.l user.l

as6502.l:	as6502.1
		man -d as6502.1 > as6502.l

user.l:		user.nr
		nroff user.nr > user.l

clean:
		rm assm0.o assm1.o assm2.o assm3.o temp as6502.l user.l
SHAR_EOF
if test -f 'user.nr'
then
	echo shar: over-writing existing file "'user.nr'"
fi
cat << \SHAR_EOF > 'user.nr'
.de hd
'sp 3
.tl ''\fBas6502 User Notes\fR'Page %'
'sp 2
..
.de fo
'bp
..
.wh 0 hd
.wh -3 fo
.br
\fBSOURCE LINE FORMAT\fR:
.ti 0.5i
.sp 1
<label> <operation> <operand> <comment>
.sp 1
Each field is terminated by one or more spaces, a tab or a ';' (which
begins the comment field immediately).
.sp
\fBLABEL FIELD\fR:
.sp 1
If first character is ';', entire line is a comment.
If first character is space, label field is null.
Labels are alphanumeric strings beginning
with 'a' through 'z', 'A' through 'Z',
underscore or period followed by any of the above
characters or '0' through '9'.
Currently, labels are limited to 19 characters.
A, X, Y, a, x and y are reserved labels.
.sp
\fBOPERATION FIELD\fR:
.sp 1
Upper and lower case letters are equivalent.
Machine operation mnemonics are:
.in 0.5i
.nf
.sp 1
ADC     BMI     CLD     DEX     JSR     PHA     RTS     STY
AND     BNE     CLI     DEY     LDA     PHP     SBC     TAX
ASL     BPL     CLV     EOR     LDX     PLA     SEC     TAY
BCC     BRK     CMP     INC     LDY     PLP     SED     TSX
BCS     BVC     CPX     INX     LSR     ROL     SEI     TXA
BEQ     BVS     CPY     INY     NOP     ROR     STA     TXS
BIT     CLC     DEC     JMP     ORA     RTI     STX     TYA
.in 0
.fi
.sp 1
Pseudo operation mnemonics are:
.in 1.2i
.ti 0.5i
.sp 1
=      equate label name to operand field value
(space is not needed to terminate this operation).
.ti 0.5i
*=     set location counter to operand field value
(space is not needed to terminate this operation).
.ti 0.5i
.tr*.
*WORD  assign 16 bit value of operand field to next
two locations; low byte of value first, then high byte.
.ti 0.5i
*DBYT  assign 16 bit value of operand field to next
two locations; high byte of value first, then low byte.
.ti 0.5i
*BYTE  assign 8 bit value of operand field to next
location.
.ti 0.5i
*NLST  turn listing mode off (this source
line is not listed).
.ti 0.5i
*LIST  turn listing mode on (normal mode) (this
source line is not listed).
.tr**
.in 0
.sp 1
\fBOPERAND FIELD\fR:
.sp 1
Operand field expressions use infix notation and are evaluated strictly
from left to right.
No imbedded spaces are permitted.
.sp 1
Operand field terms include labels and numbers.
Asterisk (*) is the label for the location counter value.
Numbers are binary, octal, decimal, hexadecimal or ASCII.
Number type is indicated by the first character of the number string as follows:
.nf
.in 0.5i
.sp 1
%       binary prefix
@ or 0  octal prefix
1 - 9   decimal by default (prefix is part of number)
$       hexadecimal prefix
.tr,'
,       ASCII character prefix
.tr,,
"       ASCII character string prefix and suffix; in the
        string, \\t is a tab character, \\n is a new line.
.in 0
.fi
.sp 1
Operand field operations and the corresponding symbols are:
.in 0.5i
.nf
.sp 1
+       addition
-       subtraction
/       division
*       multiplication
%       modulo (remainder after integer division)
^       logical exclusive OR
&       logical AND
|       logical OR
<       low byte
>       high byte
.in 0
.fi
.sp 1
\fBERROR MESSAGES\fR:
.in 0.5i
.nf
.sp 1
Invalid operation code
Invalid argument count (when as6502 was invoked)
Open error for file
Creat error for object file 6502.out
Close error
Close error (6502.out)
Symbol table full
Label multiply defined
Sync error (pass 1 symbol value not equal pass 2 symbol value)
Invalid branch address
Operand field missing
Invalid addressing mode
Operand field size error
Undefined symbol in operand field
Invalid operand field
.fi
.in 0
.sp 1
\fBINVOKING as6502\fR:
.sp 1
.ti 0.5i
as6502 {-ilnos} <source files descriptions>
.sp 1
Options:
.in 0.5i
.nf
.sp 1
-i   ignore any .nlst pseudo operations
-l   list errors only
-n   print addresses as <high byte><low byte>,
     rather than as <low byte>:<high byte>.
-o   generate ASCII object output in file 6502.out,
     format is
          ;<address lo><address hi><data>
-s   print symbol table at end of listing

                     J. H. Van Ornum  11/5/84
SHAR_EOF
#	End of shell archive
exit 0



More information about the Comp.sources.unix mailing list