{"id":22295861,"url":"https://github.com/meithecatte/ember","last_synced_at":"2025-07-29T01:32:19.463Z","repository":{"id":54375192,"uuid":"193344181","full_name":"meithecatte/ember","owner":"meithecatte","description":"an Apple II-style monitor that fits in your MBR.","archived":false,"fork":false,"pushed_at":"2021-03-04T14:14:44.000Z","size":24,"stargazers_count":9,"open_issues_count":1,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-05T05:51:12.645Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Assembly","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/meithecatte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-23T12:15:59.000Z","updated_at":"2024-01-16T16:26:10.000Z","dependencies_parsed_at":"2022-08-13T13:50:15.198Z","dependency_job_id":null,"html_url":"https://github.com/meithecatte/ember","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/meithecatte/ember","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meithecatte%2Fember","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meithecatte%2Fember/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meithecatte%2Fember/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meithecatte%2Fember/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meithecatte","download_url":"https://codeload.github.com/meithecatte/ember/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meithecatte%2Fember/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267616577,"owners_count":24116154,"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","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-12-03T17:43:23.336Z","updated_at":"2025-07-29T01:32:19.160Z","avatar_url":"https://github.com/meithecatte.png","language":"Assembly","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ember\n\nAn Apple II-style monitor that fits in your MBR.\n\n# Usage\n\nThe ember monitor will prompt you with `\u003e` once ready.\n\n## Reading memory\n\nEnter a 4-hexdigit lowercase address to view a hexdump of 16 bytes at that address:\n\n```\n\u003e7c00\n7c00: ea 0d 7c 00 00 47 7d 69 7d 12 7d 0b 7d fa 31 c9\n\u003e\n```\n\nIt's also possible to specify a range with `.`:\n\n```\n\u003e7c00.7c40\n7c00: ea 0d 7c 00 00 47 7d 69 7d 12 7d 0b 7d fa 31 c9\n7c10: 8e d9 8e c1 8e d1 bc 00 7c 88 16 37 7d fb fc bf\n7c20: 80 00 be 05 7c b1 08 a5 31 c0 ab e2 fa 31 db b0\n7c30: 3e cd 21 cd 20 be 00 06 e8 8b 00 72 05 93 89 df\n\u003e\n```\n\nThe count is rounded up to the nearest 16 bytes:\n\n```\n\u003e7c08.7c40\n7c08: 7d 12 7d 0b 7d fa 31 c9 8e d9 8e c1 8e d1 bc 00\n7c18: 7c 88 16 37 7d fb fc bf 80 00 be 05 7c b1 08 a5\n7c28: 31 c0 ab e2 fa 31 db b0 3e cd 21 cd 20 be 00 06\n7c38: e8 8b 00 72 05 93 89 df eb 03 be 00 06 ac 08 c0\n\u003e\n```\n\n## Writing memory\n\nAfter the address, type a `:` and the bytes you want to poke:\n\n```\n\u003e7e00:dead beef\n\u003e7e00\n7e00: de ad be ef 00 00 00 00 00 00 00 00 00 00 00 00\n\u003e\n```\n\n## Inferred locations\n\nEmber keeps track of the last read and write location and substitutes them\nwhen you omit the address at the start of the line.\n\n- The \"read location\" points after the last byte of the last read and is the default for\n  read operations:\n\n  ```\n  \u003e7c00\n  7c00: ea 0d 7c 00 00 47 7d 69 7d 12 7d 0b 7d fa 31 c9\n  \u003e\n  7c10: 8e d9 8e c1 8e d1 bc 00 7c 88 16 37 7d fb fc bf\n  \u003e\n  7c20: 80 00 be 05 7c b1 08 a5 31 c0 ab e2 fa 31 db b0\n  \u003e.7c60\n  7c30: 3e cd 21 cd 20 be 00 06 e8 8b 00 72 05 93 89 df\n  7c40: eb 03 be 00 06 ac 08 c0 75 05 b9 01 00 eb 16 3c\n  7c50: 2e 75 39 e8 70 00 72 5f 29 d8 83 c0 0f c1 e8 04\n  \u003e\n  ```\n\n- The \"write location\" points after the last byte of the last write and is the default for\n  write operations:\n\n  ```\n  \u003e7e00:cafe\n  \u003e:babe\n  \u003e7e00\n  7e00: ca fe ba be 00 00 00 00 00 00 00 00 00 00 00 00\n  \u003e\n  ```\n\n- Specifying an explicit address moves both locations to that address:\n\n  ```\n  \u003e7c00\n  7c00: ea 0d 7c 00 00 47 7d 69 7d 12 7d 0b 7d fa 31 c9\n  \u003e7e00:12 34 56 78\n  \u003e\n  7e00: 12 34 56 78 00 00 00 00 00 00 00 00 00 00 00 00\n  \u003e7e80\n  7e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n  \u003e:abcd\n  \u003e7e80\n  7e80: ab cd 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n  \u003e\n  ```\n\n- Writes move the read location to the beginning of the write:\n\n  ```\n  \u003e7e80\n  7e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n  \u003e:abcd\n  \u003e\n  7e80: ab cd 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n  \u003e\n  ```\n\n## Running code\n\nThe `g` command will call the specified address. When no address is provided, the write location\nis used.\n\n```\n\u003e7e00:4869210d00\n\u003e:be007e\n\u003e:ac 08c0 7404 cd21 ebf7 c3\n\u003e7e05g\nHi!\n\u003e\n```\n\n# Routines provided to runnning programs\n\nSome routines used in ember are exposed as interrupts. Apart from explicit outputs, no registers\nare modified.\n\n```asm\n; Interrupt 0x20\n; Read a line of text and store it in the global `linebuffer` (0x600). The result is\n; null-terminated. No overflow checking is performed.\n\n; Interrupt 0x21\n; Put a character on the screen. Expands \\r into \\r\\n because the latter is required\n; by the BIOS for a proper newline. \\r is used to signify newlines because that's what\n; the keyboard gives us.\n; Input:\n;  AL = ASCII character\n\n; Interrupt 0x22\n; Read sector on the boot disk\n; Input:\n;  eax = LBA\n;  es:di = operation buffer\n; Stops execution on error\n\n; Interrupt 0x23\n; Write sector on the boot disk\n; Input:\n;  eax = LBA\n;  es:di = operation buffer\n```\n\n# Limitations\n\n- uppercase letters are not recognized in commands\n- only the first 64K of memory is accessible\n- the error handling creates confusing messages when less than\n  four hexdigits of address are provided\n- backspacing over the edge of the screen desyncs what's visible from the internal buffer\n\n# TODO\n\n- `r` and `w` commands for accessing the boot disk.\n- Restart the main loop after a disk error.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeithecatte%2Fember","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeithecatte%2Fember","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeithecatte%2Fember/lists"}