├── Makefile ├── OPCODES.A18 ├── OPZ80.A23 ├── README.md ├── dia.asm ├── mxass.c ├── mxass.txt └── x7.asm /Makefile: -------------------------------------------------------------------------------- 1 | all: mxass 2 | 3 | mxass: mxass.c 4 | cc -o mxass mxass.c 5 | 6 | zip: 7 | rm -f mxass.zip 8 | zip -9 mxass.zip mxass.c Makefile OPCODES.A18 OPZ80.A23 dia.asm x7.asm README.md mxass.txt 9 | 10 | clean: 11 | rm -f mxass mxass.zip 12 | -------------------------------------------------------------------------------- /OPCODES.A18: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist64/mxass/ea6232621d95c9a0b4a46d43f697ffab2eb0987f/OPCODES.A18 -------------------------------------------------------------------------------- /OPZ80.A23: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist64/mxass/ea6232621d95c9a0b4a46d43f697ffab2eb0987f/OPZ80.A23 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mxass 2 | 3 | *mxass* is a cross assembler that targets Commodore 64-like platforms. It runs on UNIX systems and supports 6502, 65816 and Z80. 4 | 5 | ## History 6 | 7 | *mxass* was started in 1995 in PowerBASIC/DOS, was ported to Turbo Pascal in 1997 and abandoned in 1998. The last DOS binary can still be found [here](http://www.weihenstephan.org/~michaste/mxass/). In 2008, I dug up the source again, and ported it to C on UNIX. Most of the code is in an abominable state, but I find it an interesting experiment to port this code forward. And maybe someone finds it useful... 8 | 9 | ## Notes 10 | 11 | * The history in the repository goes back to the 1997 Pascal version. 12 | * This is not a release version. It assembles the examples, but might fail horribly on everything else. 13 | * The manual is outdated. For example, *mxass* does not support the PC64 or 64NET cables any more. 14 | * There are two examples: dia.asm is a C64 diagnostics program (German user interface), and x7.asm is the core of the C64 diskmag "X-Dome". 15 | 16 | ## License 17 | 18 | Public Domain 19 | 20 | ## Author 21 | 22 | Michael Steil 23 | -------------------------------------------------------------------------------- /dia.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist64/mxass/ea6232621d95c9a0b4a46d43f697ffab2eb0987f/dia.asm -------------------------------------------------------------------------------- /mxass.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist64/mxass/ea6232621d95c9a0b4a46d43f697ffab2eb0987f/mxass.c -------------------------------------------------------------------------------- /mxass.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | MXASS 0.24 User's Manual 9 | 10 | MXASS (C) 1995-1997 Michael Steil, Eittingerstr. 11b, 85459 11 | Berglern 12 | 13 | 14 | 15 | Introduction .................................................1 16 | What is MXASS? .............................................1 17 | Why MXASS? .................................................2 18 | Quickstart ...................................................2 19 | Using the special features ...................................3 20 | Local labels ...............................................3 21 | Macros .....................................................4 22 | Including constants into your object code ..................5 23 | .by .......................................................5 24 | .wo .......................................................5 25 | .br .......................................................5 26 | .tx .......................................................5 27 | .ts .......................................................5 28 | Linking ....................................................6 29 | .include ..................................................6 30 | .load .....................................................6 31 | Other pseudo statements ....................................6 32 | .ba .......................................................6 33 | .la .......................................................6 34 | Using different CPU types ..................................6 35 | 6502 ......................................................6 36 | 6502ILL ...................................................6 37 | 65C02 .....................................................7 38 | 65816 or 65802 ............................................7 39 | Z80 .......................................................7 40 | Writing 65816 code with MXASS ..............................7 41 | Writing Z80 code with MXASS ................................8 42 | Command line syntax ..........................................9 43 | Transferring the object code to the C64 ....................9 44 | -64net ....................................................9 45 | -pc64 .....................................................9 46 | -transfer- ................................................9 47 | Starting the program immediately after transfer ...........10 48 | Saving the object code to your PC's hard disk .............10 49 | Saving the symbols to your PC's hard disk .................10 50 | Show mode .................................................10 51 | Index .......................................................11 52 | 53 | 54 | Introduction 55 | 56 | What is MXASS? 57 | MXASS is a command line Assembler for the MOS6502/WDC65816 and 58 | Z80 CPUs that runs on an MS-DOS platform. Its main purpose is 59 | to assemble programs for a C64 or a C128, but it can also be 60 | used for any other computer system running with one of the 61 | above mentioned CPUs. 62 | 63 | 64 | MXASS User's Manual 65 | 66 | 67 | Why MXASS? 68 | With MXASS you can edit your source codes on any MS-DOS/Windows 69 | editor more comfortably, assemble it more quickly and run it on 70 | a C64 with much more free memory. All the advantages are listed 71 | below: 72 | . Source code is written on a PC, using any ASCII-editor you 73 | like. 74 | . Assembly time is already on a 386 much faster than any assem- 75 | bler running on a C64 76 | . The assembler can handle: 77 | all the documented statements and addressing modes of the 78 | MOS6502 79 | all the undocumented ("illegal") MOS6502 statements 80 | all new 65C02 statements and addressing modes (e.g. "phx" 81 | command, zp-indirect addressing mode; this processor is found 82 | in CMD floppies and hard disks) 83 | all the new WDC65802/65816 statements and addressing modes 84 | (including 16-bit support!), to comfortably program your 85 | Flash8/SuperCPU! 86 | Z80 assembly language, so you can program your C128's second 87 | CPU directly! 88 | . Full support of macros (use them like built-in assembler 89 | statements!) 90 | . Full support of local labels (use a leading + or -) 91 | . Optional transfer of the object code (and additional data) to 92 | a C64 or C128 connected to the PC's parallel port via a 64NET 93 | or a PC64 cable. 94 | . Object code can also be saved to hard disk in one of these 95 | formats: N64 (for 64NET), P00 (for PC64), PRG (for several 96 | C64 programs) and OBJ (raw). 97 | . Symbols can be saved to a text file. 98 | 99 | 100 | 101 | Quickstart 102 | Chose your favorite ASCII-editor on your PC and start writing 103 | your program. It should look like this: 104 | 105 | .ba $1000 106 | .la strout=$ab1e 107 | 108 | lda #text 110 | jmp strout 111 | 112 | text .tx "Hello, world!" 113 | .by 0 114 | 115 | Save it as "HELLO.ASM". Now enter DOS mode (or open a(nother) 116 | DOS box in Windows/Win95) and call MXASS using the following 117 | command line: 118 | 119 | if you have got a C64 connected to your PC via the 64NET cable: 120 | 121 | MXASS HELLO.ASM -64NET -START 122 | 123 | As soon as the PC tells you to press any key, run the common 124 | 64NET wedge program by Paul Gardner-Stephen or MXASS' own 64NET 125 | StartUp program, the do so as the PC tells you. 126 | 127 | 2 128 | 129 | 130 | MXASS User's Manual 131 | 132 | 133 | The object code will now be transferred to your C64 and started 134 | immediately. When it wants to return to BASIC, it returns to 135 | the 64NET wedge program again, so that you need not start this 136 | program again to do another transfer. If you want to jump to 137 | BASIC, you have to replace your "RTS" by a "JMP $E386". 138 | 139 | if you have got a C64 connected to your PC via the PC64 cable: 140 | 141 | MXASS HELLO.ASM -PC64 -START 142 | 143 | Do the same as above, but use the PC64 StartUp program. 144 | 145 | if you have got no C64 connected to your PC, but the PC64 emu- 146 | lator on your PC: 147 | 148 | MXASS HELLO.ASM -P00 149 | 150 | Then run PC64 and LOAD & SYS the P00 file. 151 | 152 | if you have got another C64 emulator: 153 | 154 | MXASS HELLO.ASM -PRG 155 | 156 | The object code file ("HELLO.PRG") should then be able to be 157 | imported into your emulator. 158 | 159 | 160 | Using the special features 161 | 162 | Local labels 163 | Local labels start with a + or a - character. They can only be 164 | defined as labels in the code, not as constants defined by 165 | ".LA". 166 | 167 | Example: 168 | 169 | ldx #0 170 | lda #" " 171 | -LOOP sta $0400,x 172 | sta $0500,x 173 | sta $0600,x 174 | sta $0700,x 175 | inx 176 | bne -LOOP 177 | 178 | You may have as many "-LOOP" labels as you like, but this label 179 | can only be referred to from below its definition. So, a label 180 | starting with a + can only be referred to from above. If there 181 | are several local labels with the same name, the nearest will 182 | be taken by the assembler. 183 | 184 | Second example: 185 | 186 | inc $02 187 | bne + 188 | inc $03 189 | + lda ... 190 | 191 | 192 | 193 | 3 194 | 195 | 196 | MXASS User's Manual 197 | 198 | 199 | Here, the reference is above the definition, so you have to use 200 | a + to define a local label. You can here also see that you do 201 | not need a name for a local label, a simple + or - is enough. 202 | 203 | 204 | Macros 205 | Macros can be defined by the following sequence: 206 | 207 | .macro poke address,value 208 | lda #value 209 | sta address 210 | .endmacro 211 | 212 | (As every pseudo statement, you can abbreviate these two by us- 213 | ing only its first two letters: ".ma" and ".en".) 214 | 215 | You can refer to this macro simply be typing : 216 | 217 | poke 53280,0 218 | 219 | The following code will be generated: 220 | 221 | lda #0 222 | sta 53280 223 | 224 | Note that the symbols "address" and "value" are only defined 225 | within the macro code. 226 | If you need labels within a macro, you have to use local labels 227 | (see above), since a normal label can only be defined one. At- 228 | tention: Do not use simple labels as + or - within a macro, 229 | since the assembler could assume that you refer to this label 230 | rather than to one outside. Example: 231 | 232 | - jsr getkey 233 | jsr printkey 234 | clearscreen ; calls the macro 235 | 236 | lda clearscreenflag 237 | bne - ; clear the screen again 238 | 239 | We assume that the macro "clearscreen" is defined as follows: 240 | 241 | .ma clearscreen 242 | ldx #0 243 | lda #" " 244 | - sta $0400,x 245 | sta $0500,x 246 | sta $0600,x 247 | sta $0700,x 248 | inx 249 | bne - 250 | .en 251 | 252 | So "bne -" in the main routine would refer to the line "sta 253 | $0400,x" rather than to "jsr getkey". 254 | That's why you should give local labels within macros unique 255 | names. 256 | 257 | 258 | 259 | 4 260 | 261 | 262 | MXASS User's Manual 263 | 264 | 265 | Including constants into your object code 266 | 267 | .by 268 | You can store constant bytes in your object code with the ".by" 269 | pseudo statement. Simply add, separated by commas, as many 270 | byte values as you like: 271 | 272 | colors .by 0,11,12,15,1,12,11,0 273 | (Long form ".byte" is also allowed.) 274 | 275 | 276 | .wo 277 | The same is possible with words (double bytes): 278 | 279 | table .wo mount,read,write,unmount ; defining labels in 280 | your program 281 | 282 | 283 | .br 284 | If you need to reserve an amount of bytes or want to insert a 285 | block of constant bytes, you can use ".br" (bytes reserve). The 286 | parameters define how many times, and what value will be stored 287 | there: 288 | 289 | buffer .br 17*256, 0 ; reserves 17 blocks and stores zeroes 290 | in it 291 | 292 | 293 | .tx 294 | Text can be stored with ".tx": 295 | 296 | error .tx "An error occured while reading." 297 | .by 0 298 | 299 | Note that it depends on the ASCII/PETCII configuration whether 300 | the text will be stored in ASCII or Commodore PETASCII format. 301 | Use ".ASCII" to switch to ASCII mode and ".PETSCII" to switch 302 | to Commodore PETASCII mode. If you do not use one of these two 303 | pseudo statements, the assembler generates ASCII code. Note 304 | that any other reference to text constants will be converted if 305 | in PETSCII mode, such as lda #"A", for instance. 306 | 307 | 308 | .ts 309 | Since C64 and C128 have another format to store text, the 310 | screen code, this format can also be generated by the assem- 311 | bler: 312 | 313 | .ba $1000 314 | ldx #11 315 | - lda text,x 316 | sta $0400,x 317 | dex 318 | bpl - 319 | rts 320 | text .ts "Hello World!" 321 | 322 | 323 | 324 | 325 | 5 326 | 327 | 328 | MXASS User's Manual 329 | 330 | 331 | Linking 332 | 333 | .include 334 | With ".include" followed by the name of another source text 335 | file in quotes you tell MXASS to continue assembling in another 336 | file. After that, it will of course continue in the first 337 | source file. So you can split very huge source texts. 338 | 339 | .include "floppy.inc" 340 | 341 | .load 342 | ".load" tells MXASS to transfer an additional file to the C64 343 | after assembly is complete. This only works if you use the 344 | "transfer" switch in the command line (see below). With the 345 | help of load, you make sure that all of your data that is 346 | needed by your program is really in the C64's memory. Note that 347 | the first two bytes of the file symbolize the start address in 348 | memory after transfer (PRG format). This address cannot be 349 | changed by MXASS. If you want to change it, you have to use a 350 | hex editor. 351 | 352 | .load "sinus.dat" 353 | 354 | Other pseudo statements 355 | 356 | .ba 357 | .ba defines the base address. It can also be changed within the 358 | code, but only if the new address is above the old one. 359 | 360 | .ba $9F00 361 | 362 | .la 363 | Define a global label like this: 364 | 365 | .la screen=$0400 366 | .la firstlineused=screen+40 367 | 368 | 369 | Using different CPU types 370 | MXASS can generate code for five different CPU types. What kind 371 | of statements are allowed can be defined with the ".cpu" pseudo 372 | statement. Is has to be followed by the CPU type: 373 | 374 | 375 | 6502 376 | If you specify this CPU, only 6502 legal opcodes are allowed. 377 | Your program will run on any 65xx processor. 378 | 379 | 380 | 6502ILL 381 | Same as above, but the 6502's undocumented ("illegal") opcodes 382 | are allowed. Note that programs with illegal opcodes will nei- 383 | ther run on 65C02 (several non-Commodore disk drives) nor on 384 | 65816 systems (Flash8/SuperCPU), nor on the C64DX/C65 (65CE02). 385 | But there are no problems on standard C64 and C128 computers. 386 | 387 | 388 | 389 | 390 | 391 | 6 392 | 393 | 394 | MXASS User's Manual 395 | 396 | 397 | 65C02 398 | In this mode, illegal opcodes are forbidden, but you may use 399 | the 65C02's extended instruction set. 400 | 401 | 402 | 65816 or 65802 403 | Here you can use all 65816 statements, which include all legal 404 | 6502 and all 65C02 special statements. See "" for more informa- 405 | tion. 406 | 407 | 408 | Z80 409 | The Z80 has nothing in common with the 65xx series processors. 410 | But since the C128 has a built-in Z80, MXASS supports its full 411 | instruction set. 412 | 413 | 414 | Writing 65816 code with MXASS 415 | The additional 65816 features can be used as follows: 416 | 417 | The size of the accumulator and the index registers can be set 418 | with: 419 | 420 | .al 16 bit accumulator 421 | .as 8 bit accumulator 422 | .rl 16 bit index registers 423 | .rs 8 bit index registers 424 | 425 | Note that this does not set any of the CPU's 8/16 flags. It has 426 | only to be defined to let the assembler to know what operand 427 | size it has to store in the object code. Use the "rep" and 428 | "sep" instructions to tell your CPU. 429 | You may define the following macros to make it easier: 430 | 431 | .ma acculong 432 | rep #%00100000 433 | .al 434 | .en 435 | .ma accushort 436 | sep #%00100000 437 | .as 438 | .en 439 | .ma indexlong 440 | rep #%00010000 441 | .al 442 | .en 443 | .ma indexshort 444 | sep #%00010000 445 | .as 446 | .en 447 | .ma bothlong 448 | rep #%00110000 449 | .al 450 | .rl 451 | .en 452 | .ma bothshort 453 | sep #%00110000 454 | .as 455 | .rs 456 | 457 | 7 458 | 459 | 460 | MXASS User's Manual 461 | 462 | 463 | .en 464 | 465 | Simply type "bothlong" in your source code and both the accumu- 466 | lator and the index registers will be 16 bits long. 467 | 468 | 469 | Writing Z80 code with MXASS 470 | Remember that the existing StartUp programs for the C64 can 471 | only start 65xx programs. If you want to start Z80 programs 472 | with these StartUps you have to add additional code to your 473 | program that switches the computer to Z80 mode. Use the follow- 474 | ing piece of code to enable the Z80 from the C128 mode: 475 | 476 | ;************************************************************** 477 | ************ 478 | ; Piece of code for a C128 program that uses both the 8502 and 479 | the Z80. 480 | ; Any Z80 routine can be called by a 8502 routine by "call", it 481 | has to be 482 | ; terminated by a "ret". 483 | ;************************************************************** 484 | ************ 485 | 486 | .ba $3000; start in C128 mode with BANK 0: SYS DEC("3000") 487 | 488 | .ma call ROUTINE 489 | ldx #ROUTINE 491 | jsr Z80CALL 492 | .en 493 | 494 | ;*** main program 495 | ********************************************************* 496 | 497 | jsr Z80INIT ; needed once 498 | 499 | call Routine1 ; this is a Z80 routine! 500 | 501 | rts 502 | 503 | 504 | ;*** 8502/Z80 management subroutines 505 | ************************************** 506 | Z80INIT lda #$c3 507 | sta $ffee 508 | lda #Z80STRT 511 | sta $fff0 512 | lda #$58 513 | sta $ffdc 514 | lda #$60 515 | sta $ffdd 516 | rts 517 | Z80CALL stx Z80SFMD+1 518 | sty Z80SFMD+2 519 | jmp $ffd0 520 | 521 | .CPU Z80 522 | 523 | 8 524 | 525 | 526 | MXASS User's Manual 527 | 528 | 529 | Z80STRT ld sp,$8000 ; set stack 530 | Z80SFMD call $FFFF 531 | jp $ffe0 532 | 533 | 534 | ; ***** Z80 routines 535 | ****************************************************** 536 | Routine1: 537 | ld bc,$d020 ; decrements the border color and 538 | in a,(c) ; then terminates immediately 539 | dec a 540 | out (c),a 541 | ret 542 | 543 | If you work with the Commodore Z80 microprocessor cartridge, 544 | this is more difficult, since the 6510 and the Z80 addressing 545 | space are not the same. You have to move your Z80 code $1000 546 | bytes upwards before enabling the Z80. If you use the Z80 emu- 547 | lator from Rossmoeller's CP/M emulator shipped with the Flash 548 | 8, this is the same. Please read your manual for additional in- 549 | formation. 550 | 551 | 552 | Command line syntax 553 | You start MXASS like this: 554 | 555 | MXASS [-options] filename[.ASM] [-options] 556 | 557 | It is irrelevant whether you use capital letters typing the op- 558 | tions or not. 559 | 560 | Transferring the object code to the C64 561 | 562 | -64net 563 | The switch "-64net" tells MXASS to transfer the object code and 564 | all ".load" files to a C64 connected to LPT1 via the 64NET ca- 565 | ble. This cable has been developed by Paul Gardner-Stephen and 566 | used in his software 64NET. Its speed is below the speed of the 567 | PC64 cable, but I decided to implement it because really many 568 | people own this kind of cable. As soon as the PC tells you to 569 | press any key, you have to run the 64NET cable StartUp program 570 | on your C64 (if it is not already active) and then do so as the 571 | PC tells you. If you do not have the 64NET cable StartUp pro- 572 | gram, you can also use Paul Gardner-Stephen's 64NET wedge pro- 573 | gram. 574 | 575 | -pc64 576 | If you own a PC64 cable, you have to use the switch "-pc64" to 577 | tell MXASS to transfer the object code and all ".load" files to 578 | a C64 connected to LPT1 via the PC64 cable developed by Wolf- 579 | gang Lorenz, who wrote PC64 emulator. This cable makes about 10 580 | Kbytes per second on a C64, twice the speed on a C128 in fast 581 | mode and even faster on a C64 with Flash8 or SuperCPU. So it is 582 | the best choice if you think about which cable you are going to 583 | use. 584 | 585 | -transfer- 586 | "-transfer-" disables transfer and overrides any "-64net" or "- 587 | pc64" switch before. 588 | 589 | 9 590 | 591 | 592 | MXASS User's Manual 593 | 594 | 595 | Starting the program immediately after transfer 596 | If you add "-start" to your command line, the program will be 597 | run immediately after transfer at the program's address in mem- 598 | ory. To override this, use "-start-". 599 | 600 | 601 | Saving the object code to your PC's hard disk 602 | The object code can be written to your PC's hard disk in sev- 603 | eral file formats: 604 | 605 | OBJ 606 | With "-ocode" the object code will be written to disk as a raw 607 | file without modifications. 608 | 609 | PRG 610 | With "-prg" the object code will be written to disk in PRG for- 611 | mat. The first two bytes contain the program's start address in 612 | memory, the object code itself follows immediately (see ".load" 613 | pseudo opcode). This file format can be read by most Commodore 614 | emulators. 615 | 616 | P00 617 | With "-p00" the object code will be written to disk in PC64 P00 618 | format. This file format has a simple header and can directly 619 | be loaded within the PC64 emulator. 620 | 621 | N64 622 | With "-p00" the object code will be written to disk in 64NET 623 | P00 format. This file format has a simple header and can di- 624 | rectly be read by 64NET. 625 | 626 | 627 | Saving the symbols to your PC's hard disk 628 | If you add "-sym" to your command line, the symbols will be 629 | written to disk after assembly is complete. To override this, 630 | use "-sym-". 631 | 632 | 633 | Show mode 634 | If you add "-show" to your command line, every line being as- 635 | sembled will be shown on screen while assembly. To override 636 | this, use "-show-". 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 10 656 | 657 | 658 | MXASS User's Manual 659 | 660 | 661 | 662 | Index 663 | 664 | 665 | . F 666 | 667 | .al 6 668 | 669 | .ba 5 G 670 | .br 4 671 | .by 4 Flash8 2; 5; 8 .as 6 Gardner-Stephen, Paul 2; 8 672 | .include 5 673 | .la 5 H 674 | .load 5 675 | .rl 6 HELLO.ASM 2 676 | .rs 6 677 | .ts 4 I 678 | .tx 4 679 | .wo 4 illegal 1; 5 680 | introduction 1 681 | 6 682 | L 683 | -64net 8 684 | 64NET 2 linking 5 685 | 6502 5 local labels 3 686 | 6502ILL 5 Lorenz, Wolfgang 8 687 | 65802 6 LPT1 8 688 | 65816 1; 6 689 | 65C02 5 M 690 | 691 | 8 macros 2; 3; 6 692 | MOS 1 693 | 8/16 flags 6 MS-DOS 1 694 | 695 | A N 696 | 697 | abbreviation 3 N64 8 698 | ASCII 4 699 | O 700 | B 701 | OBJ 8 702 | BASIC 2 -ocode 8 703 | 704 | C P 705 | 706 | C128 7 P00 8 707 | cartridge 7 PC64 2; 8 708 | clearscreen 3 -pc64 8 709 | command line 2; 5; 7 PETASCII 4 710 | constants 4 PETCII 4 711 | CP/M 7 poke 3 712 | CPU types 5 PRG 8 713 | pseudo statements 5 714 | E 715 | R 716 | emulator 8 717 | rep 6 718 | Rossmoeller 7 719 | 720 | 721 | 11 722 | 723 | 724 | MXASS User's Manual 725 | 726 | 727 | S -transfer- 8 728 | 729 | save 8 U 730 | sep 6 731 | show mode 8 unique names 4 732 | start 8 733 | -start 8 W 734 | -start- 8 735 | StartUp 2; 8 WDC 1 736 | strout 2 737 | SuperCPU 2; 5; 8 Z 738 | symbols 8 739 | Z80 1; 6 740 | T 741 | 742 | transfer 8 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 12 -------------------------------------------------------------------------------- /x7.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist64/mxass/ea6232621d95c9a0b4a46d43f697ffab2eb0987f/x7.asm --------------------------------------------------------------------------------