6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Wed May 08, 2024 3:08 pm

All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
PostPosted: Sun Jul 10, 2022 1:35 am 
Offline
User avatar

Joined: Mon May 12, 2014 6:18 pm
Posts: 365
TL;DR - Interactive 6502 assembler/simulator with syntax highlighting in your browser. Assembles and simulates as you type, kind of like godbolt/Compiler Explorer. Link here

A few months ago, while working on a 6502 emulation project, I kept having to look up little details like which addressing modes certain instructions support and whether they modify certain flags, so I made a Python program for Linux called i65 to easily look them all up (GitHub link). i65 adc, for example, shows all the adc op codes, addressing modes, size, cycles count, and flags they affect (screenshot below). i65 zp shows the same info for all the instructions with zero page addressing. If the program is started without any arguments, it waits for input and shows all instructions that match what you type until it's narrowed down far enough to show the full information. The Kowalski simulator has this, and I wanted to have something similar on Linux.

After that program was done, I decided to use it as a base for a combined assembler and simulator that also works in a Linux terminal. The Kowalski simulator is usually open in my taskbar for when I need to try out little snippets, though I have a few gripes about using it. I always forget to put a .ORG directive and have to reassemble (my fault, not the simulator's). The register window only shows info for the last executed instruction, although it would be useful to see it for all of them if the program is short. It would also be nice to be able to put instructions in the first column and have indented labels not in the first column. Another thing is that the parser chokes on a few simple things like LDA (5)+2. The guys maintaining Kowalski have added some improvements and missing instructions which I appreciate.

The assembler I came up with (GitHUb link) reassembles and simulates as much of the source as it can while you type, so you don't have to go through the whole cycle of assembling, fixing errors, re-assembling, and simulating (screenshot below). It somewhat resembles Compiler Explorer in that regard. There is no user input or output, and it doesn't produce binaries, so it won't replace Kowalski, but for testing snippets for my emulation projects, I think it works a lot better. The assembler has syntax highlighting including marking unknown symbols in yellow and syntax errors in red. The simulator keeps track of uninitialized memory and marks anything loaded or calculated from it with "?".

The address mode recognition and syntax checker for the assembler were especially interesting to work on. Rather than try to write out a state machine with a huge number of if statements, I mapped everything out in a spreadsheet. Once that was done, it was simple to have the spreadsheet format the data into a structure that can be directly pasted into the Python script. The Python code to advance the state machine is then very compact and basically just does a look up into the data structure. For example, starting with an instruction like LDA ((3)+2,X), the state machine would take it's current state ("none" since nothing has been evaluated yet) and look up the next state based on the first input symbol which is "(". In the screenshot below, column A holds the current state (A2 for "none") and row 1 holds the input state (D1 for "("). The look up specifies the next state as D2 which is "(". A look up yielding "E" means the combination is invalid, as in E2 where starting an argument with "," is always invalid. On the next iteration, "(" is the input state (A5). One special rule is that any parentheses after the top level are treated as part of an expression since they don't specify addressing mode. Any part of an expression including numbers and operators is coded as "*" in the column, so the next state is given by looking up A5 and B1 which yields "(*" from B5. Proceeding like this, the states are:
Code:
LDA ((3)+2,X)
1.  (          A2,D1  = D2:  "none" + "(" = "("
2.   (         A5,B1  = B5:  "("    + "*" = "(*"
3.    3        A8,B1  = B8:  "(*"   + "*" = "(*"
4.     )       A8,B1  = B8:  "(*"   + "*" = "(*"
5.      +      A8,B1  = B8:  "(*"   + "*" = "(*"
6.       2     A8,B1  = B8:  "(*"   + "*" = "(*"
7.        ,    A8,E1  = A12: "(*"   + "," = "(*,"
8.         X   A12,G1 = G12: "(*,"  + "X" = "(*,X"
9.          )  A14,F1 = F14: "(*,X" + ")" = "(*,X)"
The result after all symbols are parsed is "(*,X)" which can be matched to the addressing mode for generating the machine code. This method lets me handle tricky cases like LDA (3)+2 or LDA (3)+(2). A similar state machine handles syntax checking so I know anything passed to the addressing mode state machine is correct. This method also lets me tell the difference between * as multiplication and * as current address (ie JMP *), as well as - as subtraction and - as a minus sign.

After the program was finished, I used Brython to port it to the browser. You can try it on my website here without downloading anything. It may take 10 seconds or so to load since Brython translates the program from Python to JavaScript every time the page loads. (The first attempt at porting used Transcrypt which would have loaded much faster but produced horribly broken JavaScript).


Attachments:
ia6502-screenshot.PNG
ia6502-screenshot.PNG [ 65.08 KiB | Viewed 474 times ]
ia6502-state machine.PNG
ia6502-state machine.PNG [ 26.01 KiB | Viewed 474 times ]
i65-screenshot.PNG
i65-screenshot.PNG [ 24.8 KiB | Viewed 474 times ]
Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 10, 2022 5:12 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
An interesting offering - thanks! Nice to see a model of uninitialised memory.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: