commit - 002402cf274f1206271c31736820b465395d6a4f
commit + a6de81a3ff0bdf38809febe118c08a89b353c0c2
blob - ee27252780c0e3fe07d444bbc7354984b05de6f2
blob + 2823c1254c4e837ac40866dff999492de81e7abc
Binary files BASASM,PRG and BASASM,PRG differ
blob - b10442f369b9c48599e62915b17e6e6be782aa8b
blob + fb6ebcefc3acff2cf2336dbaa55d21589edbcef2
--- BASASM.lst
+++ BASASM.lst
0 REM BASASM - A SIMPLE ASSEMBLER MADE
-1 REM V.28 IN BASIC. PESCO 2026
+1 REM V.29 IN BASIC. PESCO 2026
2 REM 10 VARIABLES 700 *SAVE ML PRG
3 REM 100 LOAD OPCODES 720 *PRINT SEQ F
4 REM 130 SUBROUTINES 740 *MEMSTAT
5 REM 200 MAIN LOOP 750 *DISK CMD
6 REM 300 FORWARD REFS 760 *SCRATCH F..
7 REM 400 .DIRECTIVES 770 *SCR/SAVE
-8 REM 800 *HEXDUMP 777 *SCR/SAV/RUN
-9 REM 900 OPCODE TBL 1000 ASSEMBLY PGM
+8 REM 777 *SCR/SAV/RUN
+9 REM 1000 ASM DATA 800 *HEXDUMP MEM
10 O = 49152 :REM STARTING POSITION
11 P = O :REM CURRENT POSITION
12 PP = P :REM MIN. POSITION
23 DIM LN%(MN%) :REM OPERAND LENGTHS
24 DIM MI%(26) :REM ALPH. MNEM. INDEX
25 SY% = 0 :REM SYMBOL COUNT
-26 SM% = 150 :REM SYMBOL MAX
+26 SM% = 99 :REM SYMBOL MAX
27 DIM SY$(SM%) :REM SYMBOL NAMES
28 DIM SY(SM%) :REM SYMBOL VALUES
30 PA% = 0 :REM PATCH COUNT
-31 PM% = 63 :REM PATCH MAX
+31 PM% = 49 :REM PATCH MAX
32 DIM PA(PM%) :REM PATCH POSITION
33 DIM PA%(PM%) :REM PATCH LENGTH
34 DIM PA$(PM%) :REM PATCH EXPRESSION
35 DIM PM$(PM%) :REM PATCH (ADDR) MODE
-99 REM
-100 REM - READ OPCODE TABLE FROM DATA -
-105 PRINT "LOAD OPCODES...";
-107 I = 0: A = 0
-110 READ O%: IF O% = -1 THEN 125
-112 OP%(I) = O%
-115 READ MN$(I), X%: LN%(I) = X% - 1
+98 REM
+99 REM - READ OPCODE TABLE FROM FILE -
+100 IF XX = 0 THEN 10 :REM AFTER CLR
+101 IF MN$(MN%) <> "" THEN 201
+102 PRINT "LOAD OPCODES...";
+103 D = PEEK(186): REM CURRENT DEVICE
+104 OPEN 1,D,5, "OPCODES,SEQ,R"
+105 IF ST = 0 THEN 110
+106 PRINT: CLOSE 1
+109 C$ = "": GOSUB 753: GOTO 999
+110 I = 0: A = 0
+111 INPUT# 1, O%, MN$(I), X%
+112 IF MN$(I) = "" THEN 122
+114 OP%(I) = O%
+115 LN%(I) = X% - 1
117 B = ASC(MN$(I)) - 64
118 IF B = A THEN 120
119 A = A + 1: MI%(A) = I: GOTO 118
-120 I = I + 1: GOTO 110
+120 I = I + 1
+121 IF ST = 0 THEN GOTO 111
+122 CLOSE 1
+123 IF ST <> 64 THEN 109
125 PRINT: IF I = MN% + 1 THEN 201
-127 PRINT "INVALID OPCODE DATA": END
+127 PRINT "INVALID OPCODE DATA":GOTO999
128 REM
129 REM SUB: PARSE NUMBER, DEC OR HEX
130 A = VAL(A$)
197 PRINT MID$(STR$(R), 2); " ";
198 NEXT: RETURN
199 REM
-200 REM - ASSEMBLE REST OF DATA -
-201 P=O: UN=0: SY%=0: PA%=0
+200 REM - ASSEMBLE DATA -
+201 P=O: PP=P: PQ=P: UN=0: SY%=0: PA%=0
+204 RESTORE
205 PRINT "ASSEMBLE..."
210 READ M$
211 IF ASC(M$) = 46 THEN 410 :REM "."
242 FOR I = MI%(A) TO MN%
245 IF MN$(I) = M$ THEN 260
250 NEXT
-255 PRINT P; " UNKNOWN", M$: END
+255 PRINT P; " UNKNOWN", M$: GOTO 999
260 C = OP%(I): L% = LN%(I)
265 REM OUTPUT CODE
270 PRINT P; C; TAB(13); M$; TAB(19);
320 PRINT "ASSEMBLY FINISHED."
321 PRINT "P =";PP; TAB(12); "Q =";PQ;
322 PRINT TAB(24); "Q-P ="; PQ-PP
-323 END
+323 GOTO 999 :REM END
328 REM
329 REM SUB: CLEAR LOCAL SYMBOLS
330 FOR I = 0 TO SY% - 1
331 IF LEFT$(SY$(I), 1) <> "'" THEN 336
332 IF SY(I) <> XX THEN 335
333 PRINT "UNRESOLVED LOCAL LABEL: ";
-334 PRINT SY$(I): END
+334 PRINT SY$(I): GOTO 999
335 SY$(I) = ""
336 NEXT: RETURN
338 REM
339 REM SUB: ALLOCATE SYMBOL (IDX A)
340 UN = UN + 1
341 IF A <= SM% THEN 343
-342 PRINT "TOO MANY SYMBOLS": END
+342 PRINT "TOO MANY SYMBOLS": GOTO 999
343 IF A > SY% THEN STOP :REM BUG
344 IF A = SY% THEN SY% = SY% + 1
345 SY$(A) = A$: SY(A) = XX: RETURN
365 IF A < 0 OR A > 255 THEN 367
366 RETURN
367 PRINT:PRINT "OPERAND OUT OF RANGE"
-368 END
+368 GOTO 999
369 REM SUB: PATCH FWD SYMBOL REFS
370 IF PA% = 0 THEN RETURN
371 Q=P: FOR I = 0 TO PA% - 1
392 IF PA(I) = -1 THEN 397
393 NEXT: PRINT
394 PRINT "TOO MANY FORWARD REFERENCES"
-395 END
+395 GOTO 999
396 I = PA%: PA% = PA% + 1
397 PA(I) = P: PA%(I) = L%
398 PA$(I) = A$: PM$(I) = M$
590 READ A$: GOSUB 150
591 PRINT MID$(STR$(A), 2)
592 IF P <= A THEN 499: REM POS VALID
-593 PRINT "LIMIT VIOLATED": END
+593 PRINT "LIMIT VIOLATED": GOTO 999
697 REM
698 REM *RUN 700* WRITE MEM TO PRG FILE
699 REM
706 OPEN 1,D,2, F$ + ",PRG,W"
707 H = INT(L / 256): L = L - H*256
708 PRINT# 1, CHR$(L); CHR$(H);
-709 IF P >= Q THEN CLOSE 1: END
+709 IF P >= Q THEN CLOSE 1: GOTO 999
710 PRINT# 1, CHR$(PEEK(P));
711 P=P+1: GOTO 709
717 REM
719 REM
720 GOSUB 780: REM GET D/F
728 OPEN 1,D,2,F$ + ",SEQ,)"
-729 IF ST THEN CLOSE 1: END
+729 IF ST THEN CLOSE 1: GOTO 999
732 GET# 1, A$: PRINT A$;: GOTO 729
737 REM
738 REM *RUN 740* PRINT MEM STATS/PTRS
744 PRINT 51,"FRETOP",PEEK(51)+PEEK(52)*256
745 PRINT 53,"FRESPC",PEEK(53)+PEEK(54)*256
746 PRINT 55,"MEMSIZ",PEEK(55)+PEEK(56)*256
-747 END
+747 GOTO 999
748 REM *RUN 750* ISSUE DISK COMMAND
749 REM
-750 GOSUB 785: REM GET DRIVE
-751 INPUT "CMD"; C$: GOSUB 753: END
+750 C$="":GOSUB 785: REM GET DRIVE
+751 INPUT "CMD"; C$: GOSUB 753: GOTO999
752 REM
753 OPEN 15,D,15, C$
754 INPUT# 15, X,A$,Y,Z: CLOSE 15
757 REM
758 REM *RUN 760* SCRATCH FILE(S)
759 REM
-760 GOSUB 761: END
+760 GOSUB 761: GOTO 999
761 GOSUB 780: REM GET D/F
762 C$ = "S:" + F$
763 GOSUB 753: REM SEND CMD
767 REM *RUN 770* SCRATCH & SAVE
768 REM *RUN 777* SCRATCH/SAVE/RUN
769 REM
-770 GOSUB 772: END
+770 GOSUB 772: GOTO 999
771 REM
-772 GOSUB 761: SAVE F$,D
-773 IF ST THEN C$= "": GOSUB 753: END
+772 GOSUB 761: SAVE F$,D: PRINT
+773 IF ST THEN C$="":GOSUB 753: GOTO999
774 RETURN
776 REM
-777 GOSUB 772: RUN
+777 GOSUB 772: GOTO 100
778 REM
779 REM SUB: PROMPT FOR DRIVE & FILE
-780 GOSUB 785: INPUT "FILE"; F$
-781 IF F$ = "" THEN PRINT "ABORT": END
+780 GOSUB 785: F$="": INPUT "FILE"; F$
+781 IF F$="" THEN PRINT"ABORT": GOTO999
782 RETURN
783 REM
784 REM SUB: PROMPT FOR DRIVE
-785 FA = PEEK(186) :REM CURRENT DEVICE
+785 FA = PEEK(186): A$ = ""
786 PRINT "DRIVE [";FA;"]";: INPUT A$
787 D=FA: IF A$ <> "" THEN D=VAL(A$)
-788 IF D=0 THEN END
+788 IF D=0 THEN PRINT "ABORT": GOTO 999
789 RETURN
797 REM
798 REM *RUN 800* HEXDUMP MEMORY
799 REM
800 INPUT "START"; A$: GOSUB 130: P=A
801 INPUT "STOP "; A$: GOSUB 830: Q=A
-804 IF P >= Q THEN PRINT: END
+804 IF P >= Q THEN PRINT: GOTO 999
805 X=P: IF X > 32767 THEN X=X-65536
806 IF X AND 7 THEN 809
807 PRINT " "; S$: S$ = ""
830 IF LEFT$(A$,1) <> "+" THEN 130
831 A = A + VAL(MID$(A$,2))
832 RETURN
+997 REM
+998 REM
+999 END: GOTO 100 :REM CONT RESTARTS
blob - 949dc785749272c251b1ef60f5a9ee87e996cc45
blob + e9e5dbae92b5779e52b8f00e8bfd1bcedc538907
--- Makefile
+++ Makefile
PRGS = BASASM HDFILE HEXDUMP SAVEMEM PRINTNAT.B LINECNT.B MANUAL OPCODES \
- LINEUTIL.B TEST.B TV MKALLTOK DISKCOPY
+ LINEUTIL.B TEST.B TV MKALLTOK DISKCOPY MKOPCODES
.PHONY: all
all: und64 listprg ${PRGS:=.lst}
blob - /dev/null
blob + 8bf32919e540f6b3457da287f13ae024a93258cb (mode 644)
Binary files /dev/null and MKOPCODES,PRG differ
blob - /dev/null
blob + fce57368b06514da1784ca88294593c83220ca63 (mode 644)
--- /dev/null
+++ MKOPCODES.lst
+100 PRINT "WRITE OPCODE TABLE"
+105 GOSUB 110: GOTO 155
+106 REM
+110 INPUT "FILE"; F$
+120 IF F$ = "" THEN PRINT "ABORT": END
+130 D = PEEK(186)
+140 PRINT "DEVICE ["; D; "]";
+145 INPUT D$
+150 IF D$ <> "" THEN D = VAL(D$)
+151 RETURN
+152 REM
+155 OPEN 1,D,15, "S:" + F$: CLOSE 1
+160 OPEN 1,D,5, F$ + ",SEQ,W"
+170 IF ST = 0 THEN 200
+180 CLOSE 1
+181 OPEN 1,D,15
+182 INPUT# 1, A,B$,X,Y
+184 PRINT A; B$, X; Y
+185 CLOSE 1
+186 END
+200 READ OP: IF OP = -1 THEN 300
+210 READ MN$, LN
+220 OP$ = MID$(STR$(OP),2)
+225 LN$ = MID$(STR$(LN),2)
+230 PRINT OP$; "," MN$ ","; LN$
+240 PRINT# 1, OP$; "," MN$ ","; LN$
+250 N = N + 1
+260 GOTO 200
+300 CLOSE 1
+310 PRINT "WROTE"; N; "OPCODES."
+320 END
+499 REM
+500 PRINT "LIST OPCODE TABLE"
+510 GOSUB 110
+520 OPEN 1,D,5, F$ + ",SEQ,R"
+530 IF ST THEN 180
+540 INPUT# 1, OP, MN$, LN
+550 PRINT OP, MN$, LN
+555 N = N + 1
+560 IF ST = 64 THEN 580
+565 IF ST THEN 180
+570 GOTO 540
+580 CLOSE 1
+585 PRINT "READ"; N; "OPCODES."
+590 END
blob - 96c0cb7b2209776b8434ad441157144b1643000e
blob + ddd6c6830a640bbb46770dc49789e8f178e507fd
--- README
+++ README
to save programs.
The assembler consists of the base program, BASASM, and the table
- of machine OPCODES in a separate file. These must be combined with
- the user program in the form of DATA statements before RUNning.
- This can be accomplished with the supplied LINEUTILs. An executable
- MANUAL provides more instructions.
+ of machine OPCODES in a separate file. It must be combined with the
+ user program in the form of DATA statements before RUNning. This can
+ be accomplished with the supplied LINEUTILs. An executable MANUAL
+ provides more instructions.
Beside its immediate purpose, LINEUTIL serves as a moderate-size
example program, comprising a set of base subroutines and multiple
MKALLTOK write a PRG file that contains every possible BASIC
token (used for listprg)
DISKCOPY duplicate a disk block by block (incredibly slow)
+ MKOPCODES generate OPCODES file
Notes on encoding: Several (printable) characters in the Commodore
character set differ from ASCII - arrows, for instance, in place of