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 ($OFFF). 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 "pseudoops" 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 pseudoop "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"THENGOT07000 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 LDX 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"fCLEAR)":REM CLEAR THE SCREE
N 230 IFH=ITHENDE=SA:SZ=3:GOSUB4000:PRINTH$;:G
OT0240 235 PRINTSA" "; 240
INPUTMN$:PRINT"(UP)"SPC(20);:REM GO UP O NE
TINE 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=0P+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+B:GOTO2000 500 IFTY=40RTY=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=10RTY=30RTY=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=ITHEN 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=0T015: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$="01234567B9ABCDEF":SZ=1:ZO$="
000" 100 PRINT "{3 {3 "; 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 oage{5 SPACES}LDA 15
" 165 PRINT "Accum"lator{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}LDX
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 " "; 195 PRINT " " 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} ":? :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+l. 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=l 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 lF 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 " "; :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(F$(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:RETURIN 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} ":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 |
|