commit eb9ae0480b840f316f65a14c778441d4f7886942 from: Sven M. Hallberg date: Thu Jun 11 18:36:07 2026 UTC BASASM.28 - local labels commit - 9767aa1c8b0eaa8b6fea2fb3487f6edbe2d440f2 commit + eb9ae0480b840f316f65a14c778441d4f7886942 blob - 3c163430545f1b9dd0e3c52f1d1c29f19de89495 blob + ee27252780c0e3fe07d444bbc7354984b05de6f2 Binary files BASASM,PRG and BASASM,PRG differ blob - 1fd795b36202ef6c7052d17c7c739d133569e6e6 blob + b10442f369b9c48599e62915b17e6e6be782aa8b --- BASASM.lst +++ BASASM.lst @@ -1,5 +1,5 @@ 0 REM BASASM - A SIMPLE ASSEMBLER MADE -1 REM V.27 IN BASIC. PESCO 2026 +1 REM V.28 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 @@ -20,11 +20,11 @@ 23 DIM LN%(MN%) :REM OPERAND LENGTHS 24 DIM MI%(26) :REM ALPH. MNEM. INDEX 25 SY% = 0 :REM SYMBOL COUNT -26 SM% = 255 :REM SYMBOL MAX +26 SM% = 150 :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% = 99 :REM PATCH MAX +31 PM% = 63 :REM PATCH MAX 32 DIM PA(PM%) :REM PATCH POSITION 33 DIM PA%(PM%) :REM PATCH LENGTH 34 DIM PA$(PM%) :REM PATCH EXPRESSION @@ -40,30 +40,38 @@ 118 IF B = A THEN 120 119 A = A + 1: MI%(A) = I: GOTO 118 120 I = I + 1: GOTO 110 -125 PRINT: IF I = MN% + 1 THEN 200 +125 PRINT: IF I = MN% + 1 THEN 201 127 PRINT "INVALID OPCODE DATA": END 128 REM 129 REM SUB: PARSE NUMBER, DEC OR HEX 130 A = VAL(A$) -132 IF LEFT$(A$,1) <> "$" THEN RETURN -138 A$ = MID$(A$,2) -139 IF A$ = "" THEN RETURN -140 A = A * 16 + ASC(A$) - 48 -145 IF ASC(A$) > 64 THEN A = A - 7 -146 GOTO 138 +131 IF LEFT$(A$,1) <> "$" THEN RETURN +132 A$ = MID$(A$,2) +133 IF A$ = "" THEN RETURN +134 A = A * 16 + ASC(A$) - 48 +135 IF ASC(A$) > 64 THEN A = A - 7 +136 GOTO 132 +138 REM +139 REM SUB: PARSE ARGUMENT, SYM OR NUM +140 EX = 0: B$ = A$ +141 HI = (RIGHT$(A$,1) = "↑") +142 PL = (RIGHT$(A$,1) = "+") +143 IF NOT (HI OR PL) THEN 156 +144 EX = 1 +145 A$ = LEFT$(A$, LEN(A$) - 1) +146 GOTO 156 148 REM -149 REM SUB: PARSE ARGUMENT, SYM OR NUM -150 EX = 0: B$ = A$ -151 HI = (RIGHT$(A$,1) = "↑") -152 PL = (RIGHT$(A$,1) = "+") -153 IF NOT (HI OR PL) THEN 156 -154 EX = 1 -155 A$ = LEFT$(A$, LEN(A$) - 1) +149 REM SUB: PARSE ARG, PRINT [EXPR] +150 GOSUB 140 +151 IF EX THEN PRINT "["; A$; "] "; +152 RETURN +154 REM +155 REM PARSE ARG (CONT) 156 IF ASC(A$) > 64 THEN 160 :REM "A" -157 IF EX THEN PRINT "["; B$; "] "; +157 IF ASC(A$) = 39 THEN 160 :REM "'" 158 GOSUB 130: A$ = B$: GOTO 165 159 REM -160 PRINT "["; B$; "] "; +160 EX = 1 161 GOSUB 170: A$ = B$ 162 IF SY(A) = XX THEN A% = 1: RETURN 163 A = SY(A) :REM GET SYM. VALUE @@ -73,14 +81,10 @@ 167 A% = 0: RETURN :REM SUCCESS 168 REM 169 REM SUB: LOOK UP SYMBOL -170 A = 0 -171 IF A = SY% THEN 174 :REM NOT FND -172 IF SY$(A) = A$ THEN RETURN -173 A = A + 1: GOTO 171 -174 IF SY% < SM% + 1 THEN 176 -175 PRINT "TOO MANY SYMBOLS": END -176 SY% = SY% + 1: UN = UN + 1 -177 SY$(A) = A$: SY(A)=XX: RETURN +170 T = SY%: FOR A = 0 TO SY% - 1 +171 IF SY$(A) = A$ THEN RETURN +172 IF SY$(A) = "" THEN T = A +173 NEXT: A = T: GOTO 340 :REM ALLOC 178 REM 179 REM SUB: DEFINE SYMBOL 180 GOSUB 170 @@ -109,13 +113,18 @@ 219 A$ = M$: GOSUB 130 :REM NUM 220 C = A: L% = 0: GOTO 270 223 A$ = MID$(M$,2): V = P: GOSUB 180 -225 PRINT P; TAB(12); M$ :REM SYMDEF -227 GOTO 210 +224 PRINT P; TAB(12); M$ :REM SYMDEF +225 IF ASC(A$) = 39 THEN 229:REM LOCAL +226 REM ON TOP-LEVEL LABEL ('ABC)... +227 GOSUB 370 :REM PATCH FWD REFS +228 GOSUB 330 :REM CLEAR LOCAL SYMS +229 GOTO 210 230 READ A$: GOSUB 130 :REM NUM -> A 231 A$ = LEFT$(M$, LEN(M$) - 1) 232 V = A: GOSUB 180 :REM SYMDEF -233 PRINT P; TAB(12); A$; " = "; V -234 GOTO 210 +233 PRINT P; TAB(12); A$; " ="; +234 PRINT LEFT$(" ", -(V < 0)); V +235 GOTO 210 239 REM SEARCH FOR MNEMONIC 240 A = ASC(M$) - 64 242 FOR I = MI%(A) TO MN% @@ -142,17 +151,33 @@ 298 REM 299 REM - AFTER END OF INPUT - 300 IF P > PQ THEN PQ = P -305 PRINT "PATCH FWD REFS..." -306 GOSUB 370 :REM PATCH FWD REFS -310 IF UN = 0 THEN 340 -320 PRINT "UNDEFINED SYMBOLS:" -325 FOR I = 0 TO SY% -330 IF SY(I) = XX THEN PRINT SY$(I),; -335 NEXT: PRINT -340 PRINT "ASSEMBLY FINISHED." -341 PRINT "P =";PP; TAB(12); "Q =";PQ; -342 PRINT TAB(24); "Q-P ="; PQ-PP -350 END +305 GOSUB 370 :REM PATCH FWD REFS +310 IF UN = 0 THEN 320 +311 PRINT "UNDEFINED SYMBOLS:" +312 FOR I = 0 TO SY% +313 IF SY(I) = XX THEN PRINT SY$(I),; +314 NEXT: PRINT +320 PRINT "ASSEMBLY FINISHED." +321 PRINT "P =";PP; TAB(12); "Q =";PQ; +322 PRINT TAB(24); "Q-P ="; PQ-PP +323 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 +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 +343 IF A > SY% THEN STOP :REM BUG +344 IF A = SY% THEN SY% = SY% + 1 +345 SY$(A) = A$: SY(A) = XX: RETURN 358 REM 359 REM SUB: VALIDATE & PREPARE OPERAND 360 IF M$ <> "R" THEN 364 @@ -166,25 +191,31 @@ 368 END 369 REM SUB: PATCH FWD SYMBOL REFS 370 IF PA% = 0 THEN RETURN -371 FOR I = 0 TO PA% - 1 -372 P = PA(I): L% = PA%(I) -373 A$ = PA$(I): M$ = PM$(I) -375 PRINT P + 1; TAB(13); -376 GOSUB 150: IF A% THEN PRINT: NEXT -377 GOSUB 190: PRINT -378 PA(I) = -1: NEXT +371 Q=P: FOR I = 0 TO PA% - 1 +372 IF PA(I) = -1 THEN 379 +373 P = PA(I): L% = PA%(I) +374 A$ = PA$(I): M$ = PM$(I) +375 GOSUB 140: IF A% THEN 379 +376 PRINT P, "← "; +377 IF EX THEN PRINT "["; A$; "] "; +378 GOSUB 190: PRINT: PA(I) = -1 +379 NEXT: P=Q 380 FOR I = PA% - 1 TO 0 STEP -1 382 IF PA(I) <> -1 THEN RETURN 383 PA% = I :REM REMOVE 384 NEXT: RETURN 388 REM 389 REM SUB: RECORD SYM REF TO PATCH -390 IF PA% <= PM% THEN 394 -391 PRINT: PRINT "TOO MANY FWD REFS" -392 END -394 PA(PA%) = P: PA%(PA%) = L% -395 PA$(PA%) = A$: PM$(PA%) = M$ -396 PA% = PA% + 1: RETURN +390 IF PA% <= PM% THEN 396 +391 FOR I = 0 TO PA% - 1 +392 IF PA(I) = -1 THEN 397 +393 NEXT: PRINT +394 PRINT "TOO MANY FORWARD REFERENCES" +395 END +396 I = PA%: PA% = PA% + 1 +397 PA(I) = P: PA%(I) = L% +398 PA$(I) = A$: PM$(I) = M$ +399 RETURN 400 REM 401 REM - ASSEMBLER DIRECTIVES - 408 REM @@ -246,9 +277,10 @@ 578 REM 579 REM .DZ - OUTPUT N ZERO BYTES 580 READ A$: GOSUB 150: N=A -582 IF A <= 0 THEN PRINT N: GOTO 499 +582 IF A <= 0 THEN 587 584 POKE P,0: P=P+1 586 A=A-1: GOTO 582 +587 PRINT MID$(STR$(N), 2): GOTO 499 588 REM 589 REM .LIM - LIMIT OUTPUT POSITION 590 READ A$: GOSUB 150 blob - 8f98de9ad02c66ea51cf0765bd27c3618bef8130 blob + 96c0cb7b2209776b8434ad441157144b1643000e --- README +++ README @@ -28,6 +28,7 @@ - Mnemonic instructions, aware of operand sizes. - Decimal and hexadecimal notation. - Symbolic labels, absolute and relative addressing. + - Locally-scoped labels. - User-defined symbolic constants. - Single-pass operation with forward references. - Range checks for operands. blob - 8bbb53978627510982e193f24d132249234dd567 blob + 39f8222c30892f2ae04238a302488e682f5676e6 Binary files TEST.B,PRG and TEST.B,PRG differ blob - 2c85b0f88c4fec4ffc526385580b0b27550b00bd blob + 9f1a65b1af0d350367ef7d3ecd0a10be461b998c --- TEST.B.lst +++ TEST.B.lst @@ -4,12 +4,15 @@ 1003 DATA .DB, HALLO↑ 1004 DATA .DB, 1 2 3 1005 DATA PHA -1010 DATA BMIR, L1, RTI -1014 DATA 'L1 -1015 DATA BITZ, -123 -1016 DATA BEQR, L1 +1006 DATA STA, 2048: REM OK, FULL RNG +1007 REM STAZ, 2048: REM ERR, >255 +1010 DATA BMIR, 'L1, RTI +1014 DATA ''L1 +1015 DATA BITZ, 123 +1016 DATA BEQR, 'L1 1017 DATA JSR, L2 1018 DATA 'L2 +1019 REM BCCR, 'L1: REM UNDEF HERE 1020 DATA ORA(X, $23 1023 DATA HALLO=, -555 1024 DATA .DB, -1 $16, .DW, HALLO $4242 @@ -19,7 +22,9 @@ 1030 DATA .LIM, 49210 1040 DATA AND#, 255 1041 DATA ORA, $C80A+ +1042 DATA ADC#, -1025 1050 DATA JMP, START+ +1099 DATA .LIM, $C100: REM 49408 2000 DATA .=,49200, BEQR, FAR+ 2001 DATA .=,49328, 'FAR 9999 DATA .END