{"id":23429982,"url":"https://github.com/parkertomatoes/basbolt","last_synced_at":"2025-04-12T21:36:21.939Z","repository":{"id":46643714,"uuid":"317526909","full_name":"parkertomatoes/basbolt","owner":"parkertomatoes","description":"A QuickBASIC Compiler Explorer","archived":false,"fork":false,"pushed_at":"2021-11-20T08:17:05.000Z","size":1664,"stargazers_count":5,"open_issues_count":16,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-26T15:48:07.725Z","etag":null,"topics":["assembly","basic","compiler","qbasic","quickbasic"],"latest_commit_sha":null,"homepage":"https://parkertomatoes.github.io/basbolt","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/parkertomatoes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-12-01T11:59:01.000Z","updated_at":"2023-02-01T09:58:26.000Z","dependencies_parsed_at":"2022-08-01T00:18:05.744Z","dependency_job_id":null,"html_url":"https://github.com/parkertomatoes/basbolt","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parkertomatoes%2Fbasbolt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parkertomatoes%2Fbasbolt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parkertomatoes%2Fbasbolt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parkertomatoes%2Fbasbolt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/parkertomatoes","download_url":"https://codeload.github.com/parkertomatoes/basbolt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248637322,"owners_count":21137531,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assembly","basic","compiler","qbasic","quickbasic"],"created_at":"2024-12-23T08:13:57.818Z","updated_at":"2025-04-12T21:36:21.906Z","avatar_url":"https://github.com/parkertomatoes.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BasBolt\n\n## Overview\nBasBolt is an in-browser compiler explorer for QuickBASIC. It automatically\ncompiles code into 16-bit assembly using Microsoft BASIC Compiler as you type, \nand integrates the results into the editor.\n\nIt shows generated assembly, colored to identify source code regions\n![inline errors screenshot](doc/nibbles.png)\n\nIt also marks errors in the source code:\n![inline errors screenshot](doc/error.png)\n\n[Live Demo](https://parkertomatoes.github.io/basbolt/) - for a bonus, click a keyword and press F1!\n\n## How It Works\nThe editor keeps a [V86 emulator](https://copy.sh/v86) instance in the background, running a small server on FreeDOS to facilitate communication. The server written in QuickBASIC (of course). \n\nWhenever the code in the editor changes:\n 1. The editor transfers the source code to the server\n 2. The server saves the source code to a file\n 3. The server invokes BC.EXE (Microsoft BASIC Compiler) to compile\n 4. The server transfers the listing file output to the editor\n 5. The editor parses the listing file and annotates the source code\n\n ### Transferring Files\n\nV86 doesn't have an API to access FAT disks, but file transfer is made possible by reading and writing to the emulated system's RAM: \n![compilation flow](doc/compilation.png)\n\nSince 16-bit real mode DOS doesn't concern itself about any silly nonsense like virtual memory protection, The server can just allocate a buffer, do a little arithmetic with the segment and offset, and write the physical address to the console:\n```basic\nCONST buffersize\u0026 = 16384\nDIM SHARED buffer AS STRING * 16384\n\nsegment\u0026 = VARSEG(buffer)\nIF segment\u0026 \u003c 0 THEN segment\u0026 = 1 - segment\u0026\npointer\u0026 = VARPTR(buffer)\nIF pointer\u0026 \u003c 0 THEN pointer\u0026 = 1 - pointer\u0026\nbufferaddr\u0026 = segment\u0026 * 16 + pointer\u0026\n\nPRINT USING \"(buffer\u0026, size\u0026) \"; STR$(bufferaddr\u0026); STR$(buffersize\u0026);\n```\nWhich prints something like this, redirected to COM1:\n``` \n(buffer 123456, size: 16384)\n```\nThe compilation server code can be found in [another repostiory](https://github.com/parkertomatoes/basbolt-image)\n\nThe editor reads the pointer using the V86's serial API. V86 also has a convenient API to read and write blocks of memory in the emulated system:\n\n```javascript\nconst bytes = emulator.read_memory(address, size);\nemulator.write_memory(bytes, address);\n```\nSince the RAM is implemented as a `Uint8Array`, and `read_memory` is implemented with `UInt8Array.prototype.subarray`, we can effectively access shared memory. 16KB blocks are written at one time. A byte is sent over COM1 to signal that the data is ready to copied, and a message is sent back over COM1 to signal that the server is ready for more data. In formal CS literature, this transaction is called a podunk direct memory access (PDMA) transfer.\n\n### Compiling \n\nTo compile, the server invokes the `SHELL` command to run BC.EXE. Passing with the /A option generates a .lst file that includes each line of source, followed by the assembly for that line and any errors. \n```\nBC.EXE /A /O JOB.BAS JOB.OBJ JOB.LST\n```\n\njob.bas:\n```basic\nPRIN \"HELLO WORLD\"\n```\n\njob.lst:\n```txt\n                                                                      PAGE   1\n                                                                      12 Dec 20\n                                                                      16:34:29\nOffset  Data    Source Line           Microsoft (R) BASIC Compiler Version 7.10\n\n 0030   0006    PRIN \"HELLO WORLD\"\n                     ^\u0007 Equal sign missing\n 0030    **        I00002:   call    B$CENP\n 0035   0006    \n\n46074 Bytes Available\n45976 Bytes Free\n\n    0 Warning Error(s)\n    1 Severe  Error(s)\n```\n_yes, it's paginated and formatted to 80 characters for your dot matrix printer_\n\nErrors and assembly don't include any explicit line numbers and columns. But by counting lines of code, and spaces between the start of the line and the \"^\" for errors, the line and column of errors can be determined. The listing file is parsed using a combination of regular expressions and a simple state machine.\n\nThe assembly mappings in the listing files are not as fine-grained as the ones generated by modern compilers. It appears to only associate entire blocks of source code between branches and labels, with blocks of assembly. But it's still enough to give you a near rough idea of what source code becomes what assembly.\n\n## Building \n\n### 1. Add BIOS Images\nFor X86 emulation with V86, a BIOS image is required to function:\n * [SeaBIOS](https://www.seabios.org/downloads/) is used as the bios, and should be placed in `images/seabios.bin`\n * [Bochs VGABios](http://www.nongnu.org/vgabios/#DOWNLOAD) is used as the VGA bios, and should be placed in `images/vgabios.bin`\n\n### 2. Build the compilation server\nA hard disk image containing the compilation server must be built. It can be found here:\nhttps://github.com/parkertomatoes/basbolt-image\n\nRun the makefile in that repository to build `basbolt.img`, then copy it to `images/basbolt.img`.\n\n### 3. Building\n\nThe project is packaged with npm and webpack, and can be built using the following commands:\n```\nnpm install\nnpm run buildRelease\n```\nIf the bundling is successful, the contents of `/dist` can be deployed to any webserver. \n\n## Roadmap\nThis project is currently a fun tech demo that started as a joke, and was written as a way for me to practice writing a semi-complex project using React Hooks. \n\nBut it would be neat to make something like a tweakable sandbox for showcasing old Q(uick)?BASIC games and demos. Eventual features could include \n\n* Linking\n* Running\n* Multiple sources\n* Non-source files\n* Multiple compilers (QB 1-4, PDS 7.1, VBDOS 1.0, etc)\n* In-app help, etc\n\n## Contributing\nAre you of sound mind? And want to contribute? Welcome to that very narrow middle of that Venn diagram, friend. I'll happily review any issues or pull requests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparkertomatoes%2Fbasbolt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparkertomatoes%2Fbasbolt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparkertomatoes%2Fbasbolt/lists"}