Appendix C

Simple Assembler
Notes On Assembling


This program is written in BASIC because there is no reason not to. Since the program runs quickly enough and there is some complicated arithmetic involved, BASIC is the language of choice. There are assemblers in ML which make two "passes" through the source code and do need the extra speed. But this is a simple, "one-pass" assembler. The virtue of simplicity is that you can easily and quickly make small ML routines, test them, and debug them. An added bonus is that modifying the Simple Assembler is easy in BASIC. We'll see how you can customize it in a minute.

     The assembler accepts your opcodes and their arguments, translates them into the correct numeric values, and POKES them into RAM memory. You have a choice between using hex or decimal during your ML programming on the Simple Assembler (SA). If you remove line 10, the SA will accept only decimal numbers as arguments, will print all addresses in decimal, and will display the object code (the numbers it is POKEing) in decimal. Leaving line 10 in the program will result in the SA accepting, addressing, and displaying only hexadecimal numbers.

     The circumflex in lines 4010 and 5030 - the character following the number 16 - means "to the power of" and generally appears on computer keyboards as an arrow pointing up. Since this is not a complicated assembler, a decision had to be made concerning whether or not to include two of the conventions which have been traditional in ML programming. They were left out because it saves programming time to avoid them and they are unnecessary.

     The first one is the dollar sign ($). When an assembler can accept either hex or decimal simultaneously it must have a way to tell, if you type in "10", whether you mean decimal 10 or hex 10 (decimal 16). The convention requires that you write decimal ten as "10" and hex as "$10. "However, this can quickly become a burden. In the SA, you let it know which kinds of numbers you are using by setting H in line ten. After that, just type in the numbers. No $ is used. The second convention that is not included in the SA is the use of the comma. Again, there is no particular reason to use commas, but it has been the tradition to include them for certain addressing modes. They, too, can become burdensome when you are programming. Also, each line of your ML program is brought into the computer via the INPUT statement in line 240. Microsoft BASIC's INPUT statement dislikes seeing commas. So, it is expedient in several ways to drop the comma convention. There is just no reason to use them.

     One additional note. The SA does not accept the indirect jump: JMP ($0FFF). You could add it if you wish, but because of a bug in the 6502, it is far safer to avoid it.

     Here is a list of the traditional conventions used in most assemblers compared to the simplified conventions of the SA. Notice that each addressing mode has its own appearance, its own punctuation. This is how an assembler knows which addressing mode you mean to use.

     Spaces are important.

Addressing Mode
Conventions

Simple Assembler
Traditional
Immediate
LDA #15
LDA #$15
Absolute
LDA 1500
LDA $1500
Zero Page
LDA 15
LDA $15
(sometimes LDA *$15)
Accumulator
ASL
ASL A
Zero Page, X
LDA 15X
LDA $15,X
Zero Page, Y
LDX 15Y
LDX $15,Y
Absolute, X
LDA 1500X
LDA $1500,X
Absolute, Y
LDA 1500Y
LDA $1500,Y
Indexed Indirect
LDA (15X)
LDA ($15,X)
Indirect Indexed
LDA (15)Y
LDA ($15),Y

Customizing The Simple Assembler

An assembler is only supposed to get your typed opcodes and their arguments, translate them into the right numbers, and put them in memory for you. Nevertheless, the assembler is there for your benefit and it is a computer program. It can be taught to do whatever else would assist you in your ML programming. This is where "pseudo-ops" come in. They are not part of the 6502 ML instruction set. They are false opcodes. When you enter one of these, the assembler doesn't put it into 6502 and POKE it. It can't. It does something for you like figure out the hex equivalent of a decimal number or whatever.

     The SA has four built-in pseudo-ops and you can add others. Following the input of the opcode (line 240) there is a short quiz. The first question the computer asks itself is: "did they type the word 'FORWARD'?" If so, it means that you are planning to branch forward, but you don't yet know how far. It will make a mental note of this and later, when you type in another pseudo-op, "RESOLVE," it will go back and put in the correct address for the branch. Also, you can hand-POKE in any number in any address by typing the pseudo-op "POKE". And, when you are finished with a program, type "END" and the assembler will quit, reporting the starting and ending addresses of your program in decimal.

     A full-featured assembler can include dozens of pseudo-ops. Let's briefly examine several popular ones to see if there are some that you might want to add to the SA. Then we'll add a hex/decimal pseudo-op to the SA to show how it's done.

     BA - Begin Assembly. The SA asks you directly for the starting address (variable SA$). BA signifies the location in RAM memory where you want the object code to start. Example: BA $0400

     BY - Bytes. This is for the creation of data tables. The BY is followed by numbers or text characters which are POKEd into memory at the current address. You put these Bytes at the start or end of a program (it could result in havoc if it were in the middle of a program; they would likely be meaningless as instructions). Example: BY 46 46 48 42 12 11 or BY "THIS IS A MESSAGE"

     DE - Define a label. Labels require a two-pass assembler that goes through the source code first to create a table of labels which would look something like this:

      START          1500
      LETTER.A       65
      PRINTROUTINE   64422

     Then, the second time through your source code, the assembler would replace all the labels with their correct values. This is called "resolving" the labels. DE is usually part of the initialization process. A number of the example programs in this book start off with a series of DE pseudo-ops, telling the assembler the meaning of various important labels that will be used later in the source code instead of literal numbers. Example: START DE 1500 or LETTER.A DE 65.

     EN - The end of the source program. Stop assembling at this point. The SA uses END.

     MC - Move code. This interesting pseudo-op takes care of a problem that sometimes comes up when you want your object code to be ultimately used in an address that is now being used by the assembler itself or cannot be directly POKEd at this time with the object code. For instance, if your computer's RAM memory starts at address 2048 like the Commodore 64, and you want to put your final ML object code there, what do you do? If the SA was told to start assembly there, it would begin to nibble away at itself. It's in RAM starting at 2048.

     To allow you to store object code elsewhere, but have it assembled appropriately for final use in 2048, you could instruct the assembler:

     MC 25000 (temporarily store it here)

     BA 2048    (but make internal JMPs, JSRs, and table references correct for this starting address)

     You can add your own pseudo-ops to the SA following line 240. Many times when you are working along in hex you will want to know the decimal equivalent of a number and vice versa. It's nice to be able to just ask for the translation right during assembling. The answer is printed on the screen and you continue on with your programming. The assembler will do nothing to the ML during all this; it's just giving you an answer.

     If you are working in the hex mode and want a decimal number, just type DECIMAL and the computer will accept a hex number from you and give back its decimal equivalent. Conversely, type HEX and give a decimal number for that translation.

     To include this pseudo-op in the SA, add the following lines:

Program C-1 . Adding The Conversion Pseudo-op.

245 IFMN$="HEX"THENGOTO7000
246 IFMN$="DECIMAL"THENGOTO7200
7000 PRINT"ENTER DECIMAL NUMBER";:INPUTDE:IFD
     E>255THENSZ=3:GOTO7020
7010 SZ=1
7020 GOSUB4000:PRINT"                     = $
     "H$:GOTO230
7200 PRINT"ENTER HEX NUMBER";:INPUTH$
7210 SX=LEN(H$):BK$="000":H$=LEFT$(BK$,4-SX)+
     H$
7220 GOSUB5000:PRINT"                     = "
     DE:GOTO230

     The Simple Assembler has a few error messages that it will print when it can't make sense out of something. The primary responsibility for finding errors, however, is yours. You can create and save ML routines and then look at them with the Disassembler to see if they look like they should. SA takes up about 4.5K so it will not run on an unexpanded VIC. A 3K RAM expansion will provide 2000 bytes for storage of your ML routines.

Program C-2. Simple Assembler (VIC, PET, Apple, 64 Version).

10 H=1:REM IF H = 0 THEN ASSEMBLY IS IN DEC
   IMAL
50 HE$="0123456789ABCDEF":SZ=1:ZO$="000"
100 PRINT"   SIMPLE   ASSEMBLER  CONVENTIONS
    :"
110 DIMM$(56),TY(56),OP(56)
120 FORI=1TO56:READM$(I)
122 ROP$=MID$(M$(I),4,1):TY(I)=VAL(ROP$)
124 OP$=RIGHT$(M$(I),3):OP(I)=VAL(OP$)
126 M$(I)=LEFT$(M$(I),3)
140 NEXTI: PRINT
150 PRINT"IMMEDIATE     LDA #15
155 PRINT"ABSOLUTE      LDA 1500
160 PRINT"ZERO PAGE     LDA 15
165 PRINT"ACCUMULATOR   ASL
170 PRINT"INDIRECT X    LDA (15X)
175 PRINT"INDIRECT Y    LDA (15)Y
177 PRINT"ZERO PAGE X   LDA 15X
179 PRINT"ZERO PAGE Y   LDA 15Y
180 PRINT"ABSOLUTE X    LDA 1500X
185 PRINT"ABSOLUTE Y    LDA 1500Y
189 PRINT:PRINT"    ENTER ALL NUMBERS IN ";
190 IFH=1 THENPRINT"HEX":GOTO200
195 PRINT"DECIMAL"
200 PRINT:PRINT"PLEASE INPUT STARTING ADDRES
    S FOR ML PROGRAM":INPUT SA$
210 IFH=1THENH$=SA$:GOSUB5000:SA=DE:GOTO220
215 SA=VAL(SA$)
220 TA=SA:PRINT"{CLEAR}":REM CLEAR THE SCREE
    N
230 IFH=1THENDE=SA:SZ=3:GOSUB4000:PRINTH$;:G
    OTO240
235 PRINTSA" ";
240 INPUTMN$:PRINT"{UP}"SPC(20);:REM GO UP O
    NE LINE AND OVER 20 SPACES
241 REM ADD NEW PSEUDO-OPS HERE
242 IFRIGHT$(MN$,7)="FORWARD"THENFB=SA
243 IFRIGHT$(MN$,7)="RESOLVE"THENFR=SA-FB:PO
    KEFB+1,FR-2:PRINT"  OK":GOTO230
244 IFRIGHT$(MN$,4)="POKE"THENPRINT"ADDR,NUM
    BER(DEC)";:INPUTADR,NUM:POKEADR,NUM
    :GOTO230
250 IFMN$="END"THENPRINT:PRINT"      PROGRAM
     IS FROM"TA"TO"SA:END
260 L=LEN(MN$):L$=LEFT$(MN$,3)
270 FORI=1TO56:IFL$=M$(I)THEN300
280 NEXTI
290 GOTO850
300 REM PRIMARY OPCODE CATEGORIES
301 TY=TY(I):OP=OP(I)
305 IFFB=SATHENTN=0:GOTO2010
310 IFTY=0THENGOTO1000
320 IFTY=3THENTY=1:IFL=3THENOP=OP+8:GOTO1000
330 R$=RIGHT$(MN$,L-4):IFH=1THENGOSUB6000
340 LR$=LEFT$(R$,1):LL=LEN(R$):IFLR$="#"THEN
    480
350 IFLR$="("THEN520
360 IFTY=8THEN600
370 IFTY=3THENOP=OP+8:GOTO1000
380 IFRIGHT$(R$,1)="X"ORRIGHT$(R$,1)="Y"THEN
    630
390 IFLEFT$(L$,1)="J"THEN820
400 TN=VAL(R$):IFTN>255THEN430
410 IFTY=1ORTY=3ORTY=4ORTY=5THENOP=OP+4
420 GOTO2000
430 H%=TN/256:L%=TN-256*H%:IFTY=2ORTY=7THENO
    P=OP+8:GOTO470
440 IFTY=1ORTY=3ORTY=4ORTY=5THENOP=OP+12:GOT
    O470
450 IFTY=6ORTY=9THEN470
460 GOTO850
470 GOTO3000
480 TN=VAL(RIGHT$(R$,LL-1))
490 IFTY=1THENOP=OP+8:GOTO2000
500 IFTY=4ORTY=5THENGOTO2000
510 GOTO850
520 IFRIGHT$(R$,2)=")Y"THEN540
530 IFRIGHT$(R$,2)="X)"THEN570
540 TN=VAL(MID$(R$,2,LL-3))
550 IFTY=1THENOP=OP+16:GOTO2000
560 GOTO850
570 TN=VAL(MID$(R$,2,LL-3))
580 IFTY=1THENGOTO2000
590 GOTO850
600 TN=VAL(R$):TN=TN-SA-2:IFTN<-128ORTN>127T
    HENPRINT"TOO FAR ";:GOTO850
610 IFTN<0THENTN=TN+256
620 GOTO2000
630 IFRIGHT$(R$,2)=")Y"THEN540
640 IFRIGHT$(R$,1)="X"THEN720
650 REM *ZERO Y
660 TN=VAL(LEFT$(R$,LL-l)):IFTN>255THEN680
670 IFTY=2ORTY=5THEN730
675 IFTY=1THEN760
680 GOSUB770:IFTY=1THENOP=OP+24:GOTO710
690 IFTY=5THENOP=OP+28:GOTO710
700 GOTO850
710 GOTO3000
720 TN=VAL(LEFT$(R$,LL-1)):IFTN>255THENGOSUB
    770:GOTO780
730 IFTY=2THENOP=OP+16:GOTO760
740 IFTY=1ORTY=3ORTY=5THENOP=OP+20:GOTO760
750 GOTO850
760 GOTO2000
770 H%=TN/256:L%=TN-256*H%:RETURN
780 IFTY=2THENOP=OP+24:GOTO810
790 IFTY=1ORTY=3ORTY=5THENOP=OP+28:GOTO810
800 GOTO850
810 GOTO3000
820 TN=VAL(R$)
830 GOSUB770
840 GOTO710
850 PRINT"{REV} ERROR ":GOTO230
1000 REM 1 BYTE INSTRUCTIONS
1010 POKESA,OP:SA=SA+1:IFH=1THEN 1030
1020 PRINTOP:GOTO230
1030 DE = OP:GOSUB4000:PRINTH$:GOTO230
2000 REM 2 BYTE INSTRUCTIONS
2005 IFTN>256THENPRINT" INCORRECT ARGUMENT. (
     #5 IN HEX IS #05)":GOTO230
2010 POKESA,OP:POKESA+1,TN:SA=SA+2:IFH=1THEN2
     030
2020 PRINTOP;TN:GOTO230
2030 DE = OP:GOSUB4000:PRINTH$" ";
2040 DE = TN:GOSUB4000:PRINTH$:GOTO230
3000 REM 3 BYTE INSTRUCTIONS
3010 POKESA,OP:POKESA+1,L%:POKESA+2,H%:SA=SA+
     3:IFH=1THEN3030
3020 PRINTOP;L%;H%:GOTO230
3030 DE = OP:GOSUB4000:PRINTH$" ";
3040 DE = L%:GOSUB4000:PRINTH$" ";
3050 DE = H%:GOSUB4000:PRINTH$:GOTO230
4000 REM DECIMAL TO HEX (DE TO H$)
4010 H$="":FORM=SZTO0STEP-1:N%=DE/(16^M):DE=D
     E-N%*16^M:H$=H$+MID$(HE$,N%+1,1)
4020 NEXT:SZ=1:RETURN
5000 REM HEX TO DECIMAL (H$ TO DE)
5010 D=0:Q=3:FORM=1TO4:FORW=0TO15:IFMID$(H$,M
     ,1)=MID$(HE$,W+1,1)THEN5030
5020 NEXTW
5030 Dl=W*(16^(Q)):D=D+D1:Q=Q-1:NEXTM:DE=INT(
     D):RETURN
6000 REM ACCEPT HEX OPCODE INPUT AND TRANSLAT
     E IT TO DECIMAL
6010 IFLEFT$(R$,1)="#"THENH$="00"+RIGHT$(R$,2
     ):GOSUB5000:R$="#"+STR$(DE):RETURN
6020 LS=LEN(R$):AZ$=LEFT$(R$,1):ZA$=MID$(R$,L
     S,1):IFAZ$<>"("THEN6050
6030 IFZA$="Y"THENH$="00"+MID$(R$,2,2):GOSUB5
     000:R$="("+STR$(DE)+")Y":RETURN
6040 IFZA$=")"THENH$="00"+MID$(R$,2,2):GOSUB5
     000:R$="("+STR$(DE)+"X)":RETURN
6050 IFZA$="X"ORZA$="Y"THEN6070
6060 H$=LEFT$(ZO$,4-LS)+R$:GOSUB5000:R$=STR$(
     DE):RETURN
6070 IFLS=5THENH$=LEFT$(R$,4):GOTO6090
6080 H$="00"+LEFT$(R$,2)
6090 GOSUB5000:R$=STR$(DE)+ZA$:RETURN
20000 DATAADC1097,AND1033,ASL3002,BCC8144,
      BCS8176,BEQ8240,BIT7036,BMI8048
20010 DATABNE8208,BPL8016,BRK0000,BVC8080,BVS8
      112,CLC0024,CLD0216,CLI0088
20020 DATACLV0184,CMP1193,CPX4224,CPY4192,DEC2
      198,DEX0202,DEY0136,EOR1065
20030 DATAINC2230,INX0232,INY0200,JMP6076,JSR9
      032,LDA1161,LDX5162,LDY5160
20040 DATALSR3066,NOP0234,ORA1001,PHA0072,PHP0
      008,PLA0104,PLP0040,ROL3034
20050 DATAROR3098,RTI0064,RTS0096,SBC1225,SEC0
      056,SED0248,SEI0120,STA1129
20060 DATASTX2134,STY2132,TAX0170,TAY0168,TSX0
      186,TXA0138,TXS0154,TYA0152

Program C-3. Simple Assembler: Atari Version.

10 HX=1:REM IF HX= 0 THEN ASSEMBLY I
   S IN DECIMAL
20 DIM HE$(16),ZO$(3),R$(10),MN$(12)
   ,ZA$(1),AZ$(1),L$(3),SA$(4),H$(4)
   ,LR$(1)
30 OPEN #1,12,0,"E:"
50 HE$="0123456789ABCDEF":SZ=1:ZO$="
   000"
100 PRINT "{3 SPACES}SIMPLE
    {3 SPACES}ASSEMBLER  CONVENTIONS
    :";
110 DIM M$(56*3),TY(56),OP(56)
120 FOR I=1 TO 56:READ MN$:M$(I*3-2,
    I*3)=MN$(1,3)
122 TY(I)=VAL(MN$(4,4)):OP(I)=VAL(MN
    $(5))
130 NEXT I
140 PRINT :?
150 PRINT "Immediate{5 SPACES}LDA #1
    5"
155 PRINT "Absolute{6 SPACES}LDA 150
    0"
160 PRINT "Zero page{5 SPACES}LDA 15
    "
165 PRINT "Accumulator{3 SPACES}ASL"
170 PRINT "Indirect X{4 SPACES}LDA (
    15X)"
175 PRINT "Indirect Y{4 SPACES}LDA (
    15)Y"
177 PRINT "Zero page X{3 SPACES}LDA
    15X"
179 PRINT "Zero page Y{3 SPACES}LDA
    15Y"
180 PRINT "Absolute X{4 SPACES}LDA 1
    500X"
185 PRINT "Absolute Y{4 SPACES}LDA 1
    500Y"
189 PRINT :PRINT :{4 SPACES}Enter al
    l numbers in ";
190 IF HX=1 THEN PRINT "hexa";
195 PRINT "decimal"
197 ? :? "Addresses: Use 1536-1791 ($
    0600-$06FF)":? :?
200 PRINT "{2 DEL LINE}Please enter
    starting":? "address for ML prog
    ram";:INPUT SA$:IF SA$="" THEN ?
     "{2 UP}";:GOTO 200
210 IF HX=1 THEN H$=SA$:GOSUB 5000:S
    A=DE:GOTO 217
215 SA=VAL(SA$)
217 IF SA<256 OR SA>=40960 THEN ? "
    {4 UP}Not ZPAGE or ROM!":? :GOTO
    200
220 TA=SA:PRINT "{CLEAR}":GOTO 230
225 ? :? "{BELL} INPUT ERROR ":? :IF
     HX=1 THEN ? "(e.g. #5 should be
     #05)":?
230 IF HX=1 THEN DE=SA:SZ=3:GOSUB 40
    00:PRINT H$;": ";:GOTO 240
235 PRINT SA;": ";
240 TRAP 225:INPUT # 1;MN$:? "{UP}";:
    POKE 85,20:IF MN$="" THEN ? "
    {DEL LINE}";:GOTO 230
241 REM ADD NEW PSEUDO-OPS HERE
242 IF LEN(MN$)>6 THEN IF MN$(LEN(MN
    $)-6)="FORWARD" THEN FB=SA
243 IF MN$="RESOLVE" THEN FR=SA-FB:P
    OKE FB+1,FR-2:PRINT "  OK":GOTO
    230
244 IF MN$="POKE" THEN PRINT "ADDR, N
    UMBER (DEC)";:INPUT ADDR,NUM:POKE
     ADDR,NUM:GOTO 230
250 IF MN$="END" THEN 8000
260 L=LEN(MN$):L$=MN$(1,3)
270 FOR I=1 TO 56:IF L$=M$(I*3-2,I*3
    ) THEN 300
280 NEXT I
290 GOTO 850
300 REM PRIMARY OPCODE CATEGORIES
301 TY=TY(I):OP=OP(I)
305 IF FB=SA THEN TN=0:GOTO 2010
310 IF TY=0 THEN GOTO 1000
320 IF TY=3 THEN TY=1:lF L=3 THEN OP
    =OP+8:GOTO 1000
330 R$=MN$(5):IF HX=1 THEN GOSUB 600
    0
340 LR$=R$(1,1):LL=LEN(R$):IF LR$="#
    " THEN 480
350 IF LR$="(" THEN 520
360 IF TY=8 THEN 600
370 IF TY=3 THEN OP=OP+8:GOTO 1000
380 IF R$(LL)="X" OR R$(LL)="Y" THEN
     630
390 IF L$(1,1)="J" THEN 820
400 TN=VAL(R$):IF TN>255 THEN 430
410 IF TY=1 OR TY=3 OR TY=4 OR TY=5
    THEN OP=OP+4
420 GOTO 2000
430 H=INT(TN/256):L=(TN-256*H):IF TY
    =2 OR TY=7 THEN OP=OP+8:GOTO 470
440 IF TY=1 OR TY=3 OR TY=4 OR TY=5
    THEN OP=OP+12:GOTO 470
450 IF TY=6 OR TY=9 THEN 470
460 GOTO 850
470 G0TO 3000
480 TN=VAL(R$(2))
490 IF TY=1 THEN OP=OP+8:GOTO 2000
500 IF TY=4 OR TY=5 THEN GOTO 2000
510 GOTO 850
520 IF R$(LL-1)=")Y" THEN 540
530 IF R$(LL-1)="X)" THEN 570
540 TN=VAL(R$(2,LL-1))
550 IF TY=1 THEN OP=OP+16:GOTO 2000
560 GOTO 850
570 TN=VAL(R$(2,LL-1))
580 IF TY=1 THEN GOTO 2000
590 GOTO 850
600 TN=VAL(R$):TN=TN-SA-2:IF TN<-128
    OR TN>127 THEN PRINT "TOO FAR";
    :GOTO 850
610 IF TN<0 THEN TN=TN+256
620 GOTO 2000
630 IF R$(LL-1)=")Y" THEN 540
640 IF R$(LL-1)="X" THEN 720
650 REM *ZERO Y
660 TN=VAL(R$(1,LL-1)):IF TN>255 THE
    N 680
670 IF TY=2 OR TY=5 THEN 730
675 IF TY=1 THEN 760
680 GOSUB 770: IF TY=1 THEN OP=OP+24:
    GOTO 710
690 IF TY=5 THEN OP=OP+28:GOTO 710
700 GOTO 850
710 GOTO 3000
720 TN=VAL(R$(1,LL-1)):IF T>255 THE
    N GOSUB 770:GOTO 780
730 IF TY=2 THEN OP=OP+16:GOTO 760
740 IF TY=1 OR TY=3 OR TY=5 THEN OP=
    OP+20:GOTO 760
750 GOTO 850
760 GOTO 2000
770 H=INT(TN/256):L=TN-256*H:RETURN
780 IF TY=2 THEN OP=OP+24:GOTO 810
790 IF TY=1 OR TY=3 OR TY=5 THEN OP=
    OP+28:GOTO 810
800 GOTO 850
810 GOTO 3000
820 TN=VAL(R$)
830 GOSUB 770
840 GOTO 710
850 PRINT "{BELL}ERROR ":GOTO 230
1000 REM 1 BYTE INSTRUCTIONS
1010 POKE SA,OP:SA=SA+1:IF HX=1 THEN
     1030
1020 PRINT OP:GOTO 230
1030 DE=OP:GOSUB 4000:PRINT H$:GOTO
     230
2000 REM 2 BYTE INSTRUCTIONS
2005 IF TN>256 THEN ? :? "Error--";T
     N;">256 ($100)":GOTO 230
2010 POKE SA,OP:POKE SA+1,TN:SA=SA+2
     :IF HX=1 THEN 2030
2020 PRINT OP;" ";TN:GOTO 230
2030 DE=OP:GOSUB 4000:PRINT H$;" ";
2040 DE=TN:GOSUB 4000:PRINT H$:GOTO
     230
3000 REM 3 BYTE INSTRUCTIONS
3010 POKE SA,OP:POKE SA+1,L:POKE SA+
     2,H:SA=SA+3:IF HX=1 THEN 3030
3020 PRINT OP;" ";L;" ";H:GOTO 230
3030 DE=OP:GOSUB 4000:PRINT H$;" ";
3040 DE=L:GOSUB 4000:PRINT H$;" ";
3050 DE=H:GOSUB 4000:PRINT H$:GOTO 2
     30
4000 REM DECIMAL TO HEX (DE TO H$)
4010 H$="":A=INT(DE/256):IF A>0 THEN
     AH=INT(A/16):AL=A-AH*16:H$=HE$
     (AH+1,AH+1):H$(2)=HE$(AL+1,AL+1
     )
4020 A=DE-A*256:AH=INT(A/16):AL=A-AH
     *16:H$(LEN(H$)+1)=HE$(AH+1,AH+1
     ):H$(LEN(H$)+1)=HE$(AL+1,AL+1):
     SZ=1:RETURN
5000 REM HEX TO DECIMAL (H$ TO DE)
5010 D=0:Q=3:FOR M=1 TO 4:W=ASC(H$(M
     ))-48:IF W>9 THEN W=W-7
5030 D=D*16+W:NEXT M:DE=INT(D):RETUR
     N
6000 REM ACCEPT HEX OPCODE INPUT AND
      TRANSLATE IT TO DECIMAL
6010 IF R$(1,1)="#" THEN H$="00":H$(
     3)=R$(2):GOSUB 5000:R$="#":R$(2
     )=STR$(DE):RETURN
6020 LS=LEN(R$):AZ$=R$(1,1):ZA$=R$(L
     S):IF AZ$<>"(" THEN 6050
6030 IF ZA$="Y" THEN H$="00":H$(3)=R
     $(2,4):GOSUB 5000:R$="(":R$(2)=
     STR$(DE):R$(LEN(R$)+1)=")Y":RET
     URN
6040 IF ZA$=")" THEN H$="00":H$(3)=R
     $(2,4):GOSUB 5000:R$="(":R$(2)=
     STR$(DE):R$(LEN(R$)+1)="X)":RET
     URN
6050 IF ZA$="X" OR ZA$="Y" THEN 6070
6060 H$="":IF LS<4 THEN H$=ZO$(1,4-L
     S)
6065 H$(LEN(H$)+1)=R$:GOSUB 5000:R$=
     STR$(DE):RETURN
6070 IF LS=5 THEN H$=R$(1,4):GOTO 60
     90
6080 H$="00": H$(3)=R$(1,2)
6090 GOSUB 5000:R$=STR$(DE):R$(LEN(R
     $)+1)=ZA$:RETURN
8000 PRINT :PRINT "*STARTS ";TA;:SZ=
     3:DE=TA:GOSUB 4000:PRINT " ($";
     H$;")"
8010 PRINT " ENDS{3 SPACES}";SA;:DE=
     SA:SZ=3:GOSUB 4000:PRINT " ($";
     H$;")":END
20000 DATA ADC1097,AND1033,ASL3002,B
      CC8144,BCS8176,BEQ8240,BIT7036
      ,BMI8048
20010 DATA BNE8208,BPL8016,BRK0000,B
      VC8080,BVS8112,CLC0024,CLD0216
      ,CLI0088
20020 DATA CLV0184,CMP1193,CPX4224,C
      PY4192,DEC2198,DEX0202,DEY0136
      ,EOR1065
20030 DATA INC2230,INX0232,INY0200,J
      MP6076,JSR9032,LDA1161,LDX5162
      ,LDY5160
20040 DATA LSR3066,NOP0234,ORA1001,P
      HA0072,PHP0008,PLA0104,PLP0040
      ,ROL3034
20050 DATA ROR3098,RTI0064,RTS0096,S
      BC1225,SEC0056,SED0248,SEI0120
      ,STA1129
20060 DATA STX2134,STY2132,TAX0170,T
      AY0168,TSX0186,TXA0138,TXS0154
      ,TYA0152


Return to Table of Contents | Previous Chapter | Next Chapter