{"id":24227748,"url":"https://github.com/git719/defender","last_synced_at":"2025-03-04T06:15:01.558Z","repository":{"id":144688372,"uuid":"488725037","full_name":"git719/defender","owner":"git719","description":"Old arcade coin-op game","archived":false,"fork":false,"pushed_at":"2022-05-04T19:52:22.000Z","size":407,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-14T10:29:38.201Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Makefile","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/git719.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-04T19:51:33.000Z","updated_at":"2024-11-29T01:07:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"e4529c36-e1e3-4a1e-8461-c8e4e7078a60","html_url":"https://github.com/git719/defender","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/git719%2Fdefender","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git719%2Fdefender/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git719%2Fdefender/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git719%2Fdefender/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/git719","download_url":"https://codeload.github.com/git719/defender/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241794137,"owners_count":20021193,"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":[],"created_at":"2025-01-14T10:20:28.202Z","updated_at":"2025-03-04T06:15:01.547Z","avatar_url":"https://github.com/git719.png","language":"Makefile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Defender (1981) by Eugene Jarvis and Sam Dicker\n\u003cimg src=\"https://user-images.githubusercontent.com/58846/125344603-67e64d80-e34f-11eb-90bf-79a6260db9f1.png\" height=250\u003e\u003cimg src=\"https://user-images.githubusercontent.com/58846/125094574-4aa14d00-e0cb-11eb-9cf9-6dec489585f4.gif\" height=250\u003e\n\nThis is the source code for the Williams arcade game Defender.\n\nThe source code can be assembled into the 11 rom files that would have been\nloaded onto the arcade cabinet's ROM board. Today, these rom files can be used\nto play the game in an emulator such as\n[MAME](https://www.mamedev.org/release.html).\n\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n* [Build Instructions](#build-instructions)\n  * [Build Requirements](#build-requirements)\n  * [Build the assembler toolchain](#build-the-assembler-toolchain)\n  * [Build Defender](#build-defender)\n* [Play Defender](#play-defender)\n* [Notes on the Source Code, ROM Files, and the Physical Circuit Boards](#notes-on-the-source-code-rom-files-and-the-physical-circuit-boards)\n  * [About the source code](#about-the-source-code)\n  * [ROM Part Table with Corresponding Assembled Object Files](#rom-part-table-with-corresponding-assembled-object-files)\n  * [Changes required for the source to assemble](#changes-required-for-the-source-to-assemble)\n\n\u003c!-- vim-markdown-toc --\u003e\n## Build Instructions\n\n### Build Requirements\n```sh\nsudo apt install build-essentials wine python3 flex\n```\n\n### Build the assembler toolchain\n\nWe use [`asm6809`](https://www.6809.org.uk/asm6809/) to assembler the source code for the main game and [`vasm`](http://www.compilers.de/vasm.html) to compile\nthe sound module. \n\nFirst you must run the following to set up the git submodules containing the assembler toolchain:\n\n```sh\ngit submodule init\ngit submodule update\n```\n\nNow you can build the toolchain, as follows:\n\n```sh\ncd asm6809\n./autogen.sh\n./configure\nmake \ncd ..\ncd vasm-mirror\nmake CPU=6800 SYNTAX=oldstyle\ncd ..\n```\n\n### Build Defender\n\nTo build the Red Label rom files (see below for more information on what these are), do:\n```sh\nmake redlabel\n```\nThese will get written to a directory called `redlabel`.\n\n## Play Defender\n\nOnce you've built defender you can now use the rom files in the `redlabel` directory to play defender on [MAME](https://www.mamedev.org/release.html). If you're on Ubuntu you can also install MAME with apt:\n```sh\nsudo apt install mame\n```\n\n## Notes on the Source Code, ROM Files, and the Physical Circuit Boards\n\n### About the source code\nThe game source code for Defender in [src](src) was originally retrieved from\nhttps://github.com/historicalsource/defender. It is the Motorola 6809 assembly language\nsource code for the 'Red Label' version of the game.\n\nThe source code for the [sound module](src/vsndrm1.src) was retrieved from https://github.com/historicalsource/williams-soundroms.\n\nThere were four versions of the game released:\nWhite Label, Blue Label, Green Label, and Red Label, in that order. Each\nrelease was a circuit board with the assembled code split across a number of\ndifferent ROM chips, also referred to as 'ICs'. This image of the Red Label ROM\nboard from [Scott Tunstall's\nsite](https://www.robotron-2084.co.uk/techwilliamshardwareid.html) gives you an\nidea of what such a board looks like:\n\n\u003cimg src=\"orig/D8572.jpg\" size=250\u003e \u003cimg src=\"orig/RedLabelROMBoardSchema.png\" size=250\u003e\n\nIf you compare this image to [the file listing for the Red Label\nroms](orig/defender-redlabel) you'll notice that the missing chip on the board\ncorresponds to a missing file `defend.5`:\n```sh\n[robert@mwenge-desktop defender-redlabel (master)]$ ls -al\ntotal 64\ndrwxrwxr-x 2 robert robert 4096 Jul 11 10:32 .\ndrwxrwxr-x 8 robert robert 4096 Jul 11 11:02 ..\n-rw-rw-r-- 1 robert robert 2048 Dec 24  1996 defend.1\n-rw-rw-r-- 1 robert robert 2048 Dec 24  1996 defend.10\n-rw-rw-r-- 1 robert robert 2048 Dec 24  1996 defend.11\n-rw-rw-r-- 1 robert robert 2048 Dec 24  1996 defend.12\n-rw-rw-r-- 1 robert robert 4096 Dec 24  1996 defend.2\n-rw-rw-r-- 1 robert robert 4096 Dec 24  1996 defend.3\n-rw-rw-r-- 1 robert robert 2048 Dec 24  1996 defend.4\n-rw-rw-r-- 1 robert robert 2048 Dec 24  1996 defend.6\n-rw-rw-r-- 1 robert robert 2048 Dec 24  1996 defend.7\n-rw-rw-r-- 1 robert robert 2048 Dec 24  1996 defend.8\n-rw-rw-r-- 1 robert robert 2048 Dec 24  1996 defend.9\n```\n\nSo each file `defend.[x]` corresponds to a matching chip on the board and\nbecause there is a missing chip in slot 5 we have no `defend.5` in the rom dump\nlisting.\n\nIn the [Defender product documentation](https://www.robotron-2084.co.uk/manuals/defender/defender_later_pcb_drawing_set.pdf) a \nchart lists the part numbers for each chip and confirms that IC5 (i.e. `defend.5`) is unused:\n\n\u003cimg src=\"orig/RedLabelROMChart.png\" size=\"300\"\u003e\n\nWhen we assemble the Defender source with `make redlabel` we create a bunch of\nobject files and then split them across the 11 files to match the 11 in the Red\nLabel ROM dump listing above.\n\nEugene Jarvis left a slightly cryptic note to how we assemble the source in [`info.src`](src/info.src):\n\n```\n TO ASSEMBLE THE DEFENDER MESS\n\nRASM PHR2,DEFA2,DEFB2,AMODE0;-X (ELSE CREF SYMBOL OVERFLOW)\nRASM PHR2,SAMEXPA7\nRASM PHR2,DEFA2,DEFB2\nTO GET THE DIAGS, CHAIN ALL.CF\nLOAD IT ALL AND THEN PRAY IT WORKS\n(NOTE: BEWARE OF ORDER OF LOADING\n       LOOK OUT FOR THE SELECTED BLOCK SHIT\n\nDR J. 1/21/81\n\n```\n\nSince the `RASM` assembler is no longer available to us we use [`asm6809`](asm6809) instead. Fortunately this\ndoes a good job of assembling the source faithfully and [only very minor modifications to the source files are\nrequired to produce binaries](#changes-required-for-the-source-to-assemble). We recreate the steps in Eugene's notes as follows:\n\n```\n\t# Build amode1 # The equivalent of: RASM PHR2,DEFA2,DEFB2,AMODE0;-X (ELSE CREF SYMBOL OVERFLOW)\n\t./asm6809/src/asm6809 -B src/phr6.src src/defa7.src src/defb6.src src/amode1.src\\\n\t \t\t-l bin/defa7-defb6-amode1.lst  -o bin/defa7-defb6-amode1.o\n```\nThis is the main game code with the attract mode module assembled in. `phr6.src` is a file containing definitions,\nwhile `defa7.src` and `defb6/src` contain the main game code; `amode1.src` contains the attract mode code.\n\nWe also have to build a version of this game code without the attract mode module:\n\n```\n\n\t# Build defa7 and defb6\n\t# The equivalent of: RASM PHR2,DEFA2,DEFB2\n\t./asm6809/src/asm6809 -B src/phr6.src src/defa7.src src/defb6.src\\\n \t\t\t-l bin/defa7-defb6.lst -o bin/defa7-defb6.o\n```\n\nThe final module the notes mention is `samexpa7` a bunch of explosion routines added by Sam Dicker:\n\n```\n\t# Build samexamp\n\t# The equivalent of: RASM PHR2,SAMEXPA7\n\t./asm6809/src/asm6809 -B src/phr6.src src/samexap7.src\\\n\t    -l bin/samexap7.lst -o bin/samexap7.o\n```\n\nEugene's notes are much less clear on how we go about assembling the reamining source files:\n\n```\nmess0.src\nblk71.src\nromf8.src\nromc0.src\nromc8.src\n```\n\nHowever the way he lists them in the notes turns out to provide a clue to the order in which they\nshoud be assembled:\n\n```\nPHR6.SRC\t  636 LINES\nDEFA7.SRC\t3,375 LINES\nDEFB6.SRC\t2,252 LINES\nAMODE1.SRC\t1,310 LINES\nBLK71.SRC\t  723 LINES\nSAMEXAP7.SRC\t  382 LINES\nMESS0.SRC\t  955 LINES\nROMF8.SRC\t  692 LINES\nROMC0.SRC\t  925 LINES\nROMC8.SRC\t  839 LINES\n```\n\nWe assemble the last four together in the order that they appear above:\n\n```\n\t# Build roms\n\t./asm6809/src/asm6809 -B src/mess0.src src/romf8.src src/romc0.src src/romc8.src\\\n\t \t\t-l bin/roms.lst -o bin/roms.o\n```\n\nAnd we assemble `blk71.src` by itself:\n\n```\n\t# Build blk71\n\t./asm6809/src/asm6809 -B src/blk71.src -l bin/blk71.lst -o bin/blk71.o\n```\n\n### ROM Part Table with Corresponding Assembled Object Files\nThis table shows how the contents of each ROM chip relates back to the assembled code.\n\nROM Chip| Part Number|File Name|Build Binary|Start Position in Build Binary|End Position in Build Binary\n| --- | --- | --- | --- | --- | --- |\nIC1|A5343-09636 |defend.1|bin/defa7-defb6-amode1.o|0xb000|0xb800\nIC2|A5343-09637 |defend.2|bin/defa7-defb6-amode1.o|0xc000|0xd000\nIC3|A5343-09638 |defend.3|bin/defa7-defb6-amode1.o|0xd000|0xdc60\nIC3|A5343-09638 |defend.3|bin/samexpa7.o|0x0000|0x02f8\nIC3|A5343-09638 |defend.3|bin/defa7-defb6-amode1.o|0xdf59|0x0230\nIC4|A5343-09639 |defend.4|bin/defa7-defb6-amode1.o|0xb800|0x0800\nIC5|Not Used||||\nIC6|A5343-09640 |defend.6|bin/blk71.o|0x0000|0x0772\nIC6|A5343-09640 |defend.6|bin/roms.o|0xa778|0x0088\nIC7|A5343-09641 |defend.7|bin/roms.o|0xa000|0x0800\nIC8|A5343-09642 |defend.8|bin/roms.o|0x0000|0x0800\nIC9|A5343-09642 |defend.9|bin/defa7-defb6-amode1.o|0x0000|0x0800\nIC10|A5343-09643 |defend.10|bin/roms.o|0xa800|0x0800\nIC11|A5343-09644 |defend.11|bin/roms.o|0x0800|0x0800\nIC11|A5343-09644 |defend.11|Unknown||0x0800\nIC12|A5343-09645 |defend.12|bin/defa7-defb6-amode1.o|0x0800|0x0800\nIC12|A5343-09645 |defend.12|bin/defa7-defb6-amode1.o|0xaee9|0x0117\n\nReplicating this arrangement of the binaries is achieved by [`ChainFilesToRom.py`](ChainFilesToRom.py) in the \nproject's [Makefile](Makefile). It's a simple python script that extracts the relevant segments from each of the\nbinaries built in the `bin` folder when you run `make redlabel`.\n\n### Changes required for the source to assemble\nThere were a few modifications to the source required along the way to get this to work.\n\n1. Replacing macro arguments to make them compatible `asm6809`,e.g.:\n```diff\n-NAPP    MACRO  \\0,\\1\n-        LDA    #\\0\n-        LDX    #\\1\n+NAPP    MACRO  \\1,\\2\n+        LDA    #\\1\n+        LDX    #\\2\n         JMP    SLEEPP\n         ENDM \n```\n\n2. Replacing the use of `$` in label names, e.g.:\n```diff\n-INIT$V  EQU    HOFV+2\n-HALLDV  EQU    INIT$V+2\n+INITSSV  EQU    HOFV+2\n+HALLDV  EQU    INITSSV+2\n```\n3. Replacing the use of '.' in label names, e.g.:\n```diff\n-        LDY    #.P1SCR          ;START WITH PLAYER 1\n+        LDY    #P1SCR           ;START WITH PLAYER 1\n```\n\n4.  Work around the fact that `RASM` seems to have allowed you to assemble code sections into overlapping\nmemory segments. For example both `amode1.src` and `defa7.src` want to assemble into position `$C000` in\nthe ROM, meaning that one will overwrite the other. This explains why the main game files get assembled\ntwice, once with attract mode (`amode1.src`) and once without: they wanted a binary with some segments\noverwritten with attract mode features and one without. We achieve this ourselves by modifying the source\nto assemble and place the attract mode code to position `$2000` in memory, and when we later split the\nobject files into the `defend.x` files pick the chunk of code we're interested in:\n```diff\n@@ -111,6 +111,8 @@ YSHIP   EQU    $5000\n AMTYPE  EQU    0\n \n         ORG    $C000\n+        PUT    $2000\n+\n         JMP    HALLOF           ;VECTORS\n         JMP    SCNR\n```\n5. In `amode1.src` I had to replace a few hard-coded constant values to match what was in the binary:\n```diff\ndiff --git a/src/amode1.src b/src/amode1.src\nindex 543cb7e..cdaeb1e 100755\n--- a/src/amode1.src\n+++ b/src/amode1.src\n@@ -145,19 +147,19 @@ HALL1   STA    PNUMB            ;PLAYER NUMBER\n HALL1A  JSR    P2SW\n HALL1B  LDB    #$85             ;LIGHT BLUE LETTERS\n         STB    PCRAM+1\n-        LDA    #$FE             ;TODAYS SOUND - PHANTOM\n+        LDA    #$3E             ;TODAYS SOUND - PHANTOM\n         LDX    #THSTAB          ;TODAYS TOP SCORE\n         JSR    CPXCY            ;COMPARE\n         BHS    HALL2            ;NOT THE BEST?\n-        LDA    #$FD             ;HIGH SCORE SOUND - TOCCATA\n+        LDA    #$3D             ;HIGH SCORE SOUND - TOCCATA\n HALL2   LDX    #$CC02           ;SOUND PIAS\n-        LDB    #$FF             ;CLEAR LINES\n+        LDB    #$3F             ;CLEAR LINES\n         JSR    STBXBV\n-        LDB    #$E4             ;SELECT ORGAN\n+        LDB    #$24             ;SELECT ORGAN\n         JSR    STBXBV\n-HALL3   DECB     DELAY\n+HALL3   DECB                    ;DELAY\n         BNE    HALL3\n-        LDB    #$FF             ;CLEAR LINES\n+        LDB    #$3F             ;CLEAR LINES\n         JSR    STBXBV\n         TFR    A,B\n         JSR    STBXBV           ;PLAY SOUND\n``` \n\n7. Update the bit-shift and bit-wise comparison notation to be compatible with syntax expected by `asm6809`, e.g.:\n```diff\n-        LDX    #WCURS!.$C35A    ;CONFUSION\n-        LDD    #WCURS!.$3CA5    ;MORE CONFUSION\n+        LDX    #WCURS\u0026$C35A    ;CONFUSION\n+        LDD    #WCURS\u0026$3CA5    ;MORE CONFUSION\n@@ -1206,7 +1208,7 @@ MT1     LDD    BGL              ;CALC SCANL\n         LDA    STATUS\n         BITA   #2               ;NO TERRAIN???\n         BNE    MTX              ;NONE\n-        LDA    #SCANER!\u003e8\n+        LDA    #SCANER\u003e\u003e8\n         LDY    #STETAB          ;ERASE TABLE\n```\n8. Comment out some directives not used by `asm6809`, e.g.:\n```diff\nindex d2d7212..86d4bf0 100755\n--- a/src/blk71.src\n+++ b/src/blk71.src\n@@ -1,6 +1,6 @@\n-        TTL    D E F E N D E R   1.0\n-        NMLIST\n-        NOGEN\n+*       TTL  D E F E N D E R   1.0\n+*       NMLIST\n+*       NOGEN\n```\n\n\n10. This one may be worth investingating further. The code references `P1LAS` when it needs to be `P1LAT` to match\nthe Red Label binaries. Would be interesting to know if this sheds any light on the version of the source code as it\nlooks very like a typo that was bug-fixed.\n```diff\n@@ -831,14 +831,14 @@ CSCX    RTS\n *DISPLAY LASERS\n *\n LDISP   PSHS   D,X,Y,U          ;PLAYER 1\n-        LDX    #P1LAS\n-        LDA    .P1LAS\n+        LDX    #P1LAT           ;Fixme was: #P1LAS\n+        LDA    P1LAS\n         BSR    LDSP\n         LDA    PLRCNT\n         DECA \n         BEQ    LDPX\n-        LDX    #P2LAS\n-        LDA    .P2LAS\n+        LDX    #P2LAT\n+        LDA    P2LAS\n         BSR    LDSP\n```\n\n11. I needed to modify the `KILP` and `KILO` macros to assembly properly with `asm6809`. Removing the addition of `$`\nto the argument in the macro itself and instead adding it before passing the argument:\n```diff\n-KILP    MACRO  \\0,\\1\n+KILP    MACRO  \\1,\\2\n         JSR    KILPOS\n-        FDB    $\\0\n         FDB    \\1\n+        FDB    \\2\n         ENDM \n-KILO    MACRO  \\0,\\1\n+KILO    MACRO  \\1,\\2\n         JSR    KILOS\n-        FDB    $\\0\n         FDB    \\1\n+        FDB    \\2\n         ENDM \nindex 33665f5..3f4c5ac 100755\n--- a/src/defb6.src\n+++ b/src/defb6.src\n@@ -73,13 +73,13 @@ UFONV4  ADDA   #10\n         CLRB \n         LDA    XTEMP+1\n         ADDD   PLAYV\n-        ASRA     DIVIDE           ;BY 2\n+        ASRA                    ; DIVIDE BY 2\n         RORB \n         STD    OYV,X\n UFONVX  RTS  \n *UFOKILL\n UFOKIL  DEC    UFOCNT\n-        KILP   0120,UFHSND\n+        KILP   $0120,UFHSND\n         RTS  \n *\n```\n\n12. Replace some single-quotes with double-quotes for compatibility with `asm6809`, e.g.:\n```diff\n@@ -780,21 +780,21 @@ A28     FCC    \"SPECIAL         ;FUNCTION/\"\n * DEFAULT HERE FOR NOW\n *\n DEFALT  FCB    $02,$12,$70      ;CRHSTD\n-        FCC    'DRJ'\n+        FCC    \"DRJ\"\n         FCB    $01,$83,$15      ;CRHST1\n-        FCC    'SAM'\n+        FCC    \"SAM\"\n         FCB    $01,$59,$20      ;THSTD2\n-        FCC    'LED'\n+        FCC    \"LED\"\n```\n\n13. `blk71.src` has to be assembled with 6309 extensions and `STX [,Y]` has to be changed to the `COMF' instruction\nin order to get it to match with the ROM binaries.\n\n```asm\n./src/blk71.src:191: TTER03  COMF       ;Was: STX    [,Y]             ;FAST OUTPUT\n```\n\n14. In a few cases I've had to replace the values of constants in the code to match the ROM binaries. These are:\n```asm\n./src/romc0.src:78:        FDB    $D9FF               ;Fixme was: $FFFF\n./src/defb6.src:2170:      FDB    $0000,$00FE,$C300 ; Fixme: $C300 was $6600\n./src/mess0.src:68:        FDB    $5BFF              ;Fixme was: $FFFF\n./src/mess0.src:654:       FDB    $84FF              ;Fixme was: $FFFF\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgit719%2Fdefender","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgit719%2Fdefender","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgit719%2Fdefender/lists"}