mirror of
https://github.com/agn453/RSTS-E.git
synced 2026-01-11 23:22:42 +00:00
249 lines
6.8 KiB
QBasic
249 lines
6.8 KiB
QBasic
1010 REM &
|
|
REM !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! &
|
|
REM !! !! &
|
|
REM !! SC/MP DIS ASSEMBLER !! &
|
|
REM !! !!
|
|
1020 REM !! A.G. NICHOLSON, NEWCASTLE UNI. !! &
|
|
REM !! !! &
|
|
REM !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! &
|
|
|
|
1030 REM ! LAST EDITED 13-MAY-77 ! &
|
|
|
|
1040 DIM O$(46%), O%(46%), X(3%), L(100%), C$(32%)
|
|
1050 ! INITIALISE
|
|
1060 D%,F%,N0%,T%=0% &
|
|
\ P%=1%
|
|
1070 L(0%)=-1%
|
|
1080 U$=" #### \ \ \\ \\ \ \ \ \ \ \ "
|
|
1090 H$="0123456789ABCDEF" &
|
|
\ READ X(I%) FOR I%=0% TO 3%
|
|
1100 DATA 1,16,256,4096
|
|
1110 READ O$(I%), O%(I%) FOR I%=1% TO 46%
|
|
1120 ! MEMORY REFERENCE INSTRUCTIONS 1-8
|
|
1130 DATA LD,192,ST,200,AND,208,OR,216,XOR,224,DAD,232,ADD,240,CAD,248
|
|
1140 ! TRANSFER INSTRUCTIONS 9-12
|
|
1150 DATA JMP,144,JP,148,JZ,152,JNZ,156
|
|
1160 ! MEMORY INCREMENT, DECREMENT INSTRUCTIONS 13-14
|
|
1170 DATA ILD,168,DLD,184
|
|
1180 ! IMMEDIATE INSTRUCTIONS 15-21
|
|
1190 DATA LDI,196,ANI,212,ORI,220,XRI,228,DAI,236,ADI,244,CAI,252
|
|
1200 ! DELAY INSTRUCTION 22
|
|
1210 DATA DLY,143
|
|
1220 ! POINTER MOVE INSTRUCTIONS 23-25
|
|
1230 DATA XPAL,48,XPAH,52,XPPC,60
|
|
1240 ! EXTENSION REGISTER INSTRUCTIONS 26-33
|
|
1250 DATA LDE,64,XAE,1,ANE,80,ORE,88,XRE,96,DAE,104,ADE,112,CAE,120
|
|
1260 ! SERIAL I/O, SHIFT & ROTATE INSTRUCTIONS 34-38
|
|
1270 DATA SIO,25,SR,28,SRL,29,RR,30,RRL,31
|
|
1280 ! MISCELLANEOUS INSTRUCTIONS 39-46
|
|
1290 DATA HALT,0,CCL,2,SCL,3,IEN,5,DINT,4,CSA,6,CAS,7,NOP,8
|
|
1300 MAT READ C$
|
|
1310 ! ASCII CHARACTERS 0 TO 32
|
|
1320 DATA NUL,SOH,STX,EXT,EOT,ENQ,ACK,BEL,BS,HT,LF,VT,FF,CR,SO,SI
|
|
1330 DATA DEL,DC1,DC2,DC3,DC4,NAK,SYN,ETB,CAN,EM,SUB,ESC,FS,GS,RS,US
|
|
1340 OPEN "KB:" AS FILE 1%
|
|
1350 Z%=1% ! OUTPUT CHANNEL NUMBER
|
|
1360 PRINT #1% &
|
|
\ PRINT #1%,"SC/MP DIS-ASSEMBLER" &
|
|
\ PRINT #1%
|
|
1370 PRINT #1%,"#"; &
|
|
\ INPUT LINE #1%,F$ &
|
|
\ F$=CVT$$(F$,4%)
|
|
1380 I%=INSTR(1%,F$,"<") OR INSTR(1%,F$,"=")
|
|
1390 IF I% THEN X$=LEFT(F$,I%-1%) &
|
|
\ OPEN X$ FOR OUTPUT AS FILE 3% &
|
|
\ PRINT #1%," OUTPUT TO ";X$ &
|
|
\ Z%=3% &
|
|
\ F$=RIGHT(F$,I%+1%) &
|
|
\ PRINT #1%
|
|
1400 OPEN F$ FOR INPUT AS FILE 2% &
|
|
\ PRINT #1%
|
|
1410 PRINT #1%," STARTING ADDRESS (HEX) ?"; &
|
|
\ INPUT #1%,A$ &
|
|
\ N1=FND(A$) &
|
|
\ PRINT #1%
|
|
1420 ! PASS 1
|
|
1430 PRINT #1%," PASS 1"
|
|
1440 GOSUB 2240%
|
|
1450 ! GET SINGLE BYTE PORTIONS AND DECODE
|
|
1460 FOR J%=2% TO L% STEP 2%
|
|
1470 B$=MID(L$,J%-1%,2%) &
|
|
\ GOTO 1530% IF D% &
|
|
\ GOTO 1630% IF B$="XX"
|
|
1480 B%=FND(B$) &
|
|
\ N0%=N0%+1%
|
|
1490 GOTO 1610% IF B%<128%
|
|
1500 ! TWO BYTE INSTRUCTIONS
|
|
1510 IF J%=L% THEN D%=-1% &
|
|
\ GOTO 1610%
|
|
1520 J%=J%+2% &
|
|
\ B$=MID(L$,J%-1%,2%)
|
|
1530 IF B$="XX" THEN PRINT #1%, &
|
|
"MISSING ARGUMENT AT LINE ";FNH$(N1+N0%);" (HEX)" &
|
|
\ GOTO 1630%
|
|
1540 D%=0% ! RESET CONTINUATION BYTE
|
|
1550 N0%=N0%+1%
|
|
1560 ! TEST FOR A TRANSFER INSTRUCTION
|
|
1570 IF B%<144% OR B%>159% THEN B%=FND(B$) &
|
|
\ GOTO 1610%
|
|
1580 B%=FND(B$)
|
|
1590 ! ENTER LINE NUMBER REFERENCED IN TABLE T()
|
|
1600 B%=B%-256% IF B%>127% &
|
|
\ GOTO 1610% IF L(I%)=N1+N0%+B%+1% FOR I%=0% TO T% &
|
|
\ T%=T%+1% &
|
|
\ L(T%)=N1+N0%+B%+1%
|
|
1610 NEXT J% ! PROCESS NEXT CHARACTER
|
|
1620 GOTO 1440%
|
|
1630 ! END PASS 1
|
|
1640 CLOSE 2%
|
|
1650 D%,F%=0%
|
|
1660 ! PASS 2
|
|
1670 OPEN F$ FOR INPUT AS FILE 2% &
|
|
\ PRINT #1%," PASS 2" &
|
|
\ PRINT #1%
|
|
1680 PRINT #Z%," ADDR B1 B2 LABEL OPCODE ARGUMENT "; &
|
|
"[DECIMAL] <ASCII>" &
|
|
\ PRINT #Z%
|
|
1690 PRINT #Z%
|
|
1700 P%=2% &
|
|
\ N0%=0%
|
|
1710 GOSUB 2240%
|
|
1720 FOR J%=2% TO L% STEP 2%
|
|
1730 B$=MID(L$,J%-1%,2%) &
|
|
\ GOTO 1950% IF D% &
|
|
\ B1$=B$ &
|
|
\ GOTO 2210% IF B$="XX"
|
|
1740 B%=FND(B$) &
|
|
\ N0%=N0%+1%
|
|
1750 S$,O$,A$=""
|
|
1760 ! CHECK TO SEE WHETHER STATEMENT IS LABELED
|
|
1770 S$="L"+CVT$$(NUM$(I%),2%)+":" IF L(I%)=N1+N0% FOR I%=0% TO T%
|
|
1780 O%=B% &
|
|
\ GOTO 2060% IF B%<128%
|
|
1790 ! TWO BYTE INSTRUCTIONS
|
|
1800 N1%=2% ! NUMBER OF BYTES
|
|
1810 ! POINTER REFERENCE CHECK FOR TRANSFER, MEMORY INC/DEC
|
|
1820 FOR I%=1% TO 3% &
|
|
\ FOR K%=9% TO 14%
|
|
1830 IF O%(K%)+I%=O% THEN A$=A$+"("+CVT$$(NUM$(I%),2%)+")" &
|
|
\ O%=O%-I% &
|
|
\ GOTO 1910%
|
|
1840 NEXT K% &
|
|
\ NEXT I%
|
|
1850 ! AUTO INDEX AND POINTER CHECK FOR MEMORY REFERENCE
|
|
1860 FOR K%=1% TO 8% &
|
|
\ FOR I%=1% TO 3%
|
|
1870 IF O%(K%)+4%+I%=O% THEN A$="@("+CVT$$(NUM$(I%),2%)+")" &
|
|
\ O%=O%-4%-I% &
|
|
\ GOTO 1910%
|
|
1880 IF O%(K%)+I%=O% THEN A$="("+CVT$$(NUM$(I%),2%)+")" &
|
|
\ O%=O%-I% &
|
|
\ GOTO 1910%
|
|
1890 NEXT I% &
|
|
\ NEXT K%
|
|
1900 ! FIND OPCODE FOR DOUBLE BYTE INSTRUCTION
|
|
1910 O$=O$(I%) IF O%(I%)=O% FOR I%=1% TO 22%
|
|
1920 ! GET SECOND BYTE
|
|
1930 IF J%=L% THEN D%=-1% &
|
|
\ GOTO 2180% ! SECOND BYTE ON NEXT PHYSICAL LINE IN FILE F$
|
|
1940 J%=J%+2% &
|
|
\ B$=MID(L$,J%-1%,2%)
|
|
1950 GOTO 2210% IF B$="XX"
|
|
1960 D%=0%
|
|
1970 B2$=B$
|
|
1980 N0%=N0%+1%
|
|
1990 ! CHECK FOR TRANSFER INSTRUCTION
|
|
2000 GOTO 2030% IF B%<144% OR B%>159%
|
|
2010 ! ADD LABEL REFERENCED TO ARGUMENT
|
|
2020 B%=FND(B$) &
|
|
\ B%=B%-256% IF B%>127% &
|
|
\ A$=A$+"L"+CVT$$(NUM$(I%),2%) IF L(I%)=N1+N0%+B%+1% FOR I%=0% TO T% &
|
|
\ GOTO 2050%
|
|
2030 A$=A$+"X'"+B2$
|
|
2040 ! OUTPUT TO CHANNEL 1
|
|
2050 GOSUB 2300% &
|
|
\ GOTO 2180%
|
|
2060 ! SINGLE BYTE INSTRUCTIONS
|
|
2070 N1%=1% ! NUMBER OF BYTES
|
|
2080 ! CHECK POINTER MOVE
|
|
2090 FOR K%=23% TO 25% &
|
|
\ FOR I%=0% TO 3%
|
|
2100 IF O%(K%)+I%=O% THEN A$=CVT$$(NUM$(I%),2%) &
|
|
\ O%=O%-I% &
|
|
\ GOTO 2130%
|
|
2110 NEXT I% &
|
|
\ NEXT K%
|
|
2120 ! SET OPCODE FOR SINGLE BYTE INSTRUCTION
|
|
2130 O$=O$(I%) IF O%(I%)=O% FOR I%=23% TO 46%
|
|
2140 IF O$="" THEN O$=".BYTE" \ A$="X'"+B1$
|
|
2150 B2$=""
|
|
2160 ! OUTPUT TO CHANNEL 1
|
|
2170 GOSUB 2300%
|
|
2180 NEXT J%
|
|
2190 ! GET NEXT LINE FROM FILE F$
|
|
2200 GOTO 1710%
|
|
2210 ! EXIT
|
|
2220 CLOSE 2% &
|
|
\ PRINT #Z% FOR I%=1% TO 3% &
|
|
\ CLOSE 1%,3%
|
|
2230 GOTO 32767%
|
|
2240 ! SUBROUTINE TO GET A LINE FROM FILE F$
|
|
2250 INPUT LINE #2%,L$ &
|
|
\ L$=CVT$$(L$,6%) &
|
|
\ L%=LEN(L$) &
|
|
\ GOTO 2250% IF L%=0%
|
|
2260 ! F% IS THE NUMBER OF THE LINE READ FROM FILE F$
|
|
2270 F%=F%+1%
|
|
2280 IF (L%/2%)*2%<>L% THEN PRINT #1%, &
|
|
"INCOMPLETE BYTE READ FROM ";F$;", LINE";F% &
|
|
\ L$=L$+" "
|
|
2290 RETURN
|
|
2300 ! OUTPUT ROUTINE TO CHANNEL Z%
|
|
2310 PRINT #Z% USING U$,N0%-N1%,FNH$(N1+N0%-N1%),B1$,B2$,S$,O$,A$;
|
|
2320 ! LINE NUMBER, ADDR B1 B2 LABEL: OPCODE ARGUMENT
|
|
2330 IF B2$="" THEN B$=B1$ ELSE B$=B2$ &
|
|
\ B%=FND(B$)
|
|
2340 IF B%<32% THEN C$=C$(B%+1%) ELSE IF B%<96% THEN C$=CHR$(B%)
|
|
2350 B%=B%-256% IF B%>127%
|
|
2360 PRINT #Z% USING "[ #### ]",B%;
|
|
2370 IF C$<>"" THEN PRINT #Z% USING " < \ \ >",C$ ELSE PRINT #Z%
|
|
2380 C$=""
|
|
2390 RETURN
|
|
2400 DEF* FNH$(X) ! HEXADECIMAL CONVERSION
|
|
2410 X0=X &
|
|
\ X0=X0+65536 IF X0<0% &
|
|
\ X0=INT(X0+0.1) &
|
|
\ GOTO 2440% IF X0>65536 &
|
|
\ X$=""
|
|
2420 FOR X%=3% TO 1% STEP -1% &
|
|
\ X1=X(X%) &
|
|
\ X2=INT(X0/X1) &
|
|
\ X0=X0-X1*X2 &
|
|
\ X2=X2+1% &
|
|
\ X$=X$+MID(H$,X2,1%)
|
|
2430 NEXT X% &
|
|
\ FNH$=X$+MID(H$,X0+1%,1%) &
|
|
\ GOTO 2450%
|
|
2440 PRINT #1%,"OVERFLOW IN HEX CONVERSION" &
|
|
\ E%=E%+1% &
|
|
\ FNH$=" "
|
|
2450 FNEND
|
|
2460 DEF* FND(X$) ! HEX TO DECIMAL CONVERSION
|
|
2470 X=LEN(X$) &
|
|
\ X0=0% &
|
|
\ GOTO 2500% IF X>4%
|
|
2480 FOR X%=0% TO X-1% &
|
|
\ X1$=MID(X$,X-X%,1%) &
|
|
\ GOTO 2490% IF X1$=MID(H$,X1,1%) FOR X1=1% TO 16% &
|
|
\ PRINT #1%,"ILLEGAL CHARACTER IN HEX NUMBER :";X$ &
|
|
\ GOTO 2510%
|
|
2490 X0=X0+(X1-1%)*X(X%) &
|
|
\ NEXT X% &
|
|
\ FND=X0 &
|
|
\ GOTO 2520%
|
|
2500 PRINT #1%,"OVERFLOW IN DECIMAL CONVERSION :"
|
|
2510 E%=E%+1% &
|
|
\ FND=0%
|
|
2520 FNEND
|
|
32767 END
|