{"id":16619311,"url":"https://github.com/tomwhite/zx81-not-only-30-programs","last_synced_at":"2025-07-17T02:39:29.568Z","repository":{"id":65246999,"uuid":"588980338","full_name":"tomwhite/zx81-not-only-30-programs","owner":"tomwhite","description":"Run the programs from \"Not Only 30 Programs for the Sinclair ZX81\" in your browser","archived":false,"fork":false,"pushed_at":"2023-01-25T17:21:40.000Z","size":36333,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-17T20:47:45.011Z","etag":null,"topics":["game","retro-computing","zx81"],"latest_commit_sha":null,"homepage":"https://tomwhite.github.io/zx81-not-only-30-programs/web/index.html","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomwhite.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2023-01-14T17:15:50.000Z","updated_at":"2024-02-10T00:21:43.000Z","dependencies_parsed_at":"2023-02-14T09:47:04.403Z","dependency_job_id":null,"html_url":"https://github.com/tomwhite/zx81-not-only-30-programs","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/tomwhite%2Fzx81-not-only-30-programs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomwhite%2Fzx81-not-only-30-programs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomwhite%2Fzx81-not-only-30-programs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomwhite%2Fzx81-not-only-30-programs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomwhite","download_url":"https://codeload.github.com/tomwhite/zx81-not-only-30-programs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242980782,"owners_count":20216285,"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":["game","retro-computing","zx81"],"created_at":"2024-10-12T02:24:56.228Z","updated_at":"2025-03-11T05:46:51.615Z","avatar_url":"https://github.com/tomwhite.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Not Only 30 Programs for the Sinclair ZX81\n\nRun the programs from this classic book [in your browser](https://tomwhite.github.io/zx81-not-only-30-programs/web/index.html), or load them onto a real ZX81.\n\n![Not Only 30 Programs for the Sinclair ZX81 front cover](web/NotOnly30ProgramsForTheSinclairZX81.Front.Small.jpg)\n\n## How this site was built\n\nI transcribed the ZX81 programs from a PDF copy of [Not Only 30 Programs for the Sinclair ZX81](https://archive.org/download/30-programs-for-the-zx-81-1-kacme/30_programs_for_the_ZX81_1K%28acme%29.pdf). (There is a [text version](http://amigan.1emu.net/aw/not30.txt) available too.)\n\nThe programs are saved in text format with a `.bas` file extension. Graphics characters and inverse video characters are represented using the conventions described in [ZXText2P](http://freestuff.grok.co.uk/zxtext2p/index.html). The sequence `\\::`, for example, represents a black square.\n\nThe `zxtext2p` command was used to convert these text files to ZX81 P files suitable for use in an emulator, or a real ZX81. For example:\n\n```bash\nexport PATH=$PATH:~/projects-workspace/zxtext2p\nzxtext2p -d -o web/images/craps.p src/craps.bas\nxxd -p web/images/craps.p | tr -d '\\n' \u003e web/images/craps.p.hex\n```\n\nNote that the `-d` option is needed to collapse the display file in the P file so that it can fit on a 1K ZX81. This option is not available on the standard version of ZXText2P, so I created a version that adds it (see https://github.com/tomwhite/zxtext2p).\n\nOr just run the following to convert all files:\n\n```bash\nmake\n```\n\nThe web pages use the excellent [JtyOne Online ZX81 Emulator](https://www.zx81stuff.org.uk/zx81/jtyone.html) to run the programs.\n\nTo create the zip of P files:\n\n```bash\nln -s web/images 30-programs\nzip --include \"*.p\" -r 30-programs 30-programs\nmv 30-programs.zip web\nrm 30-programs\n```\n\n## Notes on the programs\n\n### Noughts and crosses\n\nAs the book says \"its logic is fairly well hidden and the use of variables in the listing makes it difficult to know what is happening\".\nThis is as a result of getting it to work in under 1K of memory.\n\nIt turns out that it doesn't work on a ZX81 with 16K because of the way it uses the display file. The 1K ZX81 has a \"collapsed\" (or compressed) representation, where blank characters are skipped - so a blank screen is just a series of newlines. (This is mentioned in Chapter 27 of the ZX81 manual.) With a 16K memory extension this optimisation is not needed, and all characters on the screen can be stored, even blank ones.\n\nIf we look at the program's display routine, from line 400, we see that line 420 finds the address of the display file by `PEEK`ing the `D_FILE` system variable at address 16396 and 16397.\n\nLine 440 then looks at all positions in the display file memory (it is looping over `I`) and if any are the number being searched for (`R`, which can be between 1 and 8) then that memory address is set (by a `POKE` command) to `O` (52) or `X` (61).\n\nThe trouble is that the loop at line 430 is only looping to `Z*B + B`, which since `Z=4` and `B=8` is only 40 characters, which suffices for the collapsed display of the 1K ZX81, but on a 16K machine it won't check enough of the display file before exiting the loop. This means that not all of the board is searched, and the game doesn't work properly.\n\nI made an alteration to make it work when the display file is not collapsed (see `src/noughts_and_crosses_16k.bas`), but it is a lot slower since it has to scan a lot more memory.\n\n### Pinch\n\nThe program never terminates (by quick inspection). Not sure if the logic is correct in all cases.\n\n### Battleships\n\nThe program doesn't check if the battleships overlap, so there can be less than 8 `X` positions, so it doesn't terminate properly since the number of hits never reaches 8. However, it also doesn't check if you have already found an `X` so you can just repeat a previous position and it counts as a new hit!\n\n### Craps\n\nEscaping quotes in quotes needs `\\\"` for `zxtext2p`, rather than `\"\"` as on the ZX81 keyboard (shift Q).\n\n### Blackjack\n\nThis one uses two programs: the first to load variables (after which it can be deleted to free up space), and the second to do the work.\n\nThis means that `zxtext2p` isn't sufficient to produce a single P file for the final result. So to get around this I used `zxtext2p` to convert the second program to a P file, which I then loaded in an emulator (zxsp). I then defined the variables by entering them without line numbers, then saved a new P file containing the program and the variables.\n\nHowever, zxsp can't save a 1K P file with a collapsed display file (I'm not aware of any emulator that can do this on a Mac). So I wrote a script to collapse the display file:\n\n```\npython scripts/collapse_dfile.py web/images/blackjack_tmp.p web/images/blackjack.p\nprintf '\\x40' | dd of=web/images/blackjack.p bs=1 seek=50 count=1 conv=notrunc # fix CDFLAG\nxxd -p web/images/blackjack.p | tr -d '\\n' \u003e web/images/blackjack.p.hex\nrm web/images/blackjack_tmp.p\n```\n\n### Caves and Pitfalls\n\nLike Blackjack, this program is entered in two parts in order to save space.\n\nThis time I used [JSZeddy](https://weggetjes.nl/jszeddy/jszeddy.html), an online ZX81 emulator, since it allows you to load multiple listings without resetting the memory, which is crucial. It allows you to export the P file as a hex string, so I converted it to a binary file as follows:\n\n```\nxxd -p -r web/images/caves_and_pitfalls.p.hex web/images/caves_and_pitfalls_tmp.p\n```\n\nThen did the 1K conversion:\n\n```\npython scripts/collapse_dfile.py web/images/caves_and_pitfalls_tmp.p web/images/caves_and_pitfalls.p\nxxd -p web/images/caves_and_pitfalls.p | tr -d '\\n' \u003e web/images/caves_and_pitfalls.p.hex\nrm web/images/caves_and_pitfalls_tmp.p\n```\n\n### Doctor ZX81\n\nParts of this program are written in machine code, and there's an elaborate procedure to enter the code that's described in the book.\n\nI used JSZeddy again to produce a hex file, which I then processed as follows:\n\n```\nxxd -p -r web/images/doctor_zx81.p.hex web/images/doctor_zx81_tmp.p\npython scripts/collapse_dfile.py web/images/doctor_zx81_tmp.p web/images/doctor_zx81.p\nxxd -p web/images/doctor_zx81.p | tr -d '\\n' \u003e web/images/doctor_zx81.p.hex\nrm web/images/doctor_zx81_tmp.p\n```\n\n### Draughts\n\nThis program is the most ambitious in the book; even entering the code is a challenge. Rather than type the machine code one byte at a time, as suggested in the book, I cut and pasted the code and created the REM line in a syntax that JSZeddy understands (see `src/draughts_program1.txt`).\n\n```\nxxd -p -r web/images/draughts.p.hex web/images/draughts_tmp.p\npython scripts/collapse_dfile.py web/images/draughts_tmp.p web/images/draughts.p\nxxd -p web/images/draughts.p | tr -d '\\n' \u003e web/images/draughts.p.hex\nrm web/images/draughts_tmp.p\n```\n\nUnfortunately, this did not work! I couldn't get the program running on a real 1K machine.\n\n## Copyright and License\n\nThe programs are copyright (c) 1981 by Beam Software.\n\nThe emulator is subject to the GPL license, version 2. See https://www.zx81stuff.org.uk/zx81/jtyone.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomwhite%2Fzx81-not-only-30-programs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomwhite%2Fzx81-not-only-30-programs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomwhite%2Fzx81-not-only-30-programs/lists"}