-*[ MAGIC ASM v1.1 ]*- ---------------- Magic-ASM is an assembler for the HuC6280, the main CPU of the PC Engine console. This processor is based on the well known 6502 processor, if you are familiar with it, you will pass easily to the HuC6820, otherwise a good book on the 6502 will give you all the bases. The assembler seems to be bug free, :) but... if you find something abnormal or if you have a nice idea for improving the program, feel free to contact me, my e-mail address is at the bottom of this file. History ------- v0.1 : 12/Jun/97 - modified an old 6502 assembler. - added support for most of the HuC6280 instructions. v0.2 : 18/Jun/97 - added the .INCLUDE directive. - added a trap for divisions by zero. v0.3 : 26/Jun/97 - corrected a bug with undefined symbols. - rewritten all the symbol routines and added local symbols. - enhanced a bit the format of the listing file. v0.4 : 02/Jul/97 - added all the missing instructions : BBRi, BBSi TST, TII, TDD, TIN, TIA and TAI. - changed some error messages. - added two functions : HIGH, LOW. v1.0 : 06/Jul/97 - rewritten the expression parser. - added support for PCX file. - added new functions PAGE and BANK. [thanks Dave!] - corrected lots of minor bugs. v1.1 : 15/Jul/97 [first release] - added macro support. - modified the ORG directive and removed the PAGE directive. - corrected a few bugs (PCX and MACRO code). - added a small demo. Usage ----- Usage is very simple, the assembler accept only one argument on the command line : the name of an asm file (the .ASM extension can be omitted). The assembler will create a complete listing file (.LST) if the LIST directive is used in the asm file, and a ROM file (.PCE) directly usuable by an emulator like VPCE or MagicEngine. The limit for the ROM file is 1MB. Instructions set ---------------- +------+----------+-----------------------------+ | | NVTBDIZC | Description | +------+----------+-----------------------------+ | ADC | XX0---XX | Add with Carry | | AND | X-0---X- | Logical AND | | ASL | X-0---XX | Arithmetic Shift left | | BBRi | --0----- | Branch if Bit Reset | | BBSi | --0----- | Branch if Bit Set | | BCC | --0----- | Branch if Carry Clear | | BCS | --0----- | Branch if Carry Set | | BEQ | --0----- | Branch if Equal | | BIT | XX0---X- | Bit Test | | BMI | --0----- | Branch if Minus | | BNE | --0----- | Branch if Not Equal | | BPL | --0----- | Branch if Plus | | BRA | --0----- | Branch Always | | BRK | --0----- | Break | | BSR | --0----- | Branch Sub Routine | | BVC | --0----- | Branch if Overflow Clear | | BVS | --0----- | Branch if Overflow Set | | CLA | --0----- | Clear A | | CLC | --0----0 | Clear Carry flag | | CLD | --0-0--- | Clear Decimal flag | | CLI | --0--0-- | Clear Interrupt disable | | CLV | -00----- | Clear Overflow flag | | CLX | --0----- | Clear X | | CLY | --0----- | Clear Y | | CMP | X-0---XX | Compare A with source | | CPX | X-0---XX | Compare X with source | | CPY | X-0---XX | Compare Y with source | | CSH | --0----- | Clock Select High | | CSL | --0----- | Clock Select Low | | DEC | X-0---X- | Decrement | | DEX | X-0---X- | Decrement X | | DEY | X-0---X- | Decrement Y | | EOR | X-0---X- | Logical Exclusive OR | | INC | X-0---X- | Increment | | INX | X-0---X- | Increment X | | INY | X-0---X- | Increment Y | | JMP | --0----- | Jump | | JSR | --0----- | Jump to Sub Routine | | LDA | X-0---X- | Load A | | LDX | X-0---X- | Load X | | LDY | X-0---X- | Load Y | | LSR | 0-0---XX | Logical Shift Right | | NOP | --0----- | No Operation | | OR | X-0---X- | Logical inclusive OR | | PHA | --0----- | Push A | | PHP | --0----- | Push P | | PHX | --0----- | Push X | | PHY | --0----- | Push Y | | PLA | X-0---X- | Pull A | | PLP | XXXXXXXX | Pull P | | PLX | X-0---X- | Pull X | | PLY | X-0---X- | Pull Y | | RMBi | --0----- | Reser Memory Bit | | ROL | X-0---XX | Rotate Left | | ROR | X-0---XX | Rotate Right | | RTI | XXXXXXXX | Return from Interrupt | | RTS | --0----- | Return from Sub Routine | | SAX | --0----- | Swap A and X | | SAY | --0----- | Swap A and Y | | SBC | XX0---XX | Substract with Carry | | SEC | --0----1 | Set Carry flag | | SED | --0-1--- | Set Decimal flag | | SEI | --0--1-- | Set Interrupt disable | | SET | --1----- | Set T flag | | SMBi | --0----- | Set Memory Bit | | ST0 | --0----- | Store HuC6270[0] | | ST1 | --0----- | Store HuC6270[2] | | ST2 | --0----- | Store HuC6270[3] | | STA | --0----- | Store A | | STX | --0----- | Store X | | STY | --0----- | Store Y | | STZ | --0----- | Store Zero | | SXY | --0----- | Swap X and Y | | TAI | --0----- | Transfert block | | TAMi | --0----- | Transfert A to MPRi | | TAX | X-0---X- | Transfert A to X | | TAY | X-0---X- | Transfert A to Y | | TDD | --0----- | Transfert block | | TIA | --0----- | Transfert block | | TII | --0----- | Transfert block | | TIN | --0----- | Transfert block | | TMAi | --0----- | Transfert MPRi to A | | TRB | XX0---X- | Test and Reset Bit | | TSB | XX0---X- | Test and Set Bit | | TST | XX0---X- | Test memory | | TSX | X-0---X- | Transfert S to X | | TXA | X-0---X- | Transfert X to A | | TXS | --0----- | Transfert X to S | | TYA | X-0---X- | Transfert Y to A | +------+----------+-----------------------------+ Operand syntax -------------- A accumulator #i immediate #i,>. In an expression four predefined functions can be used too : HIGH(), return the high byte of a number. LOW(), return the low byte. BANK(), return the bank index of a symbol. If no symbol, or more than one, are given, the function return an error. PAGE(), return the page index of a symbol. See BANK for errors. Macros ------ Up to nine parameters, \1 to \9, can be used in a macro call. There's also a special parameter \@ that returns a different number for each macro, it's used to make local symbols inside the macro : dummy macro lda \1 bpl .x\@ eor #$FF inc A sta \1 .x\@: endm Directives ---------- LIST, tell the assembler that you want a complete listing file. You can later stop temporarily the output with the NOLIST directive and restart it with LIST. NOLIST, stop the listing output. MLIST, include the macros in the listing file. NOMLIST, stop expanding macros in the listing file. EQU, assign a value to a symbol. The character '=' has the same function too. BANK, select a ROM bank (0-127) and reset the location counter to the latest known position in this bank. ORG, fix the location of the program counter. The thirteen lower bits of the address inform the assembler about the offset in the ROM bank and the third upper bits represent the page index. DB, data byte(s). DW, data word(s). MACRO, start a macro definition. ENDM, end a macro definition. INCBIN, include a binary file at the current location. If the file is bigger than a ROM bank, as many successive banks as necessary will be filled and the bank and the location counter will be updated. INCLUDE, include a source file at the current location. Up to 7 levels are possible. INCCHR, extract a part of a PCX file and convert it to the graphic format used by background characters. Three syntaxes are possible : INCCHR "pic.pcx" without additional parameters, the command convert the whole PCX file. INCCHR "pic.pcx",32,4 tell the assembler to convert only 4 rows of 32 characters (a character size is 8x8). INCCHR "pic.pcx",48,16,32,4 same as above but start extracting characters from coordinate 48,16 (in pixels). INCSPR, same as INCCHR but for sprites, excepted that the size of a sprite character is 16x16. INCPAL, extract the palette of a PCX file. If no extra parameters are given all the 256 colors are loaded and converted. The first parameter indicates from what sub-palette to start (a sub-palette is a block of 16 colors). The second parameter is the number of sub-palette to extract, if omitted one is used instead. HuC6280 banks mechanism ----------------------- To access more than the usual 64KB, the HuC6280 uses a MMU that splits the address space in 8 pages of 8KB. For each page there's a 8bit register (MPRi) that contains the bank index for this page. There's two special instructions that access the MPRi registers : TAMi, transfer the content of the accumulator (A) to the MPRi register. TMAi, transfert the MPRi register to the accumulator. Banks map : $00-$7F ROM $F7 battery backup RAM $F8 RAM $FF I/O page There's a sort of standard for pages mapping. You are not obliged to respect it, but it's recommended if you want to share examples, libraries, etc... page 0 -> bank $FF page 1 -> bank $F8 page 2 -> | page 3 -> | user page 4 -> | definable page 5 -> | page 6 -> | page 7 -> bank $00 NOTE : After a RESET all the pages are mapped to bank $00. PC Engine hardware registers map -------------------------------- Details of the I/O page : $0000-$0003 HuC6270, Video Display Controller (VDC) $0400-$0407 AuC6260, Video Colour Encoder (VCE) $0800-$080F Programmable Sound Generator (PSG) $0C00-$0C01 Timer $1000 External port (gamepad) $1402 Interrupt disable register $1403 Interrupt request register NOTE : I know, this summary is very simple. :) For a detailled description of the PC Engine hardware check the homepage of VPCE's author : Jens Ch. Restemeier, you won't be disappointed! Jens has put all his knowledge on the PC Engine in a nice documentation. [Nice job Jens!] Follow the 'projects' link. HuC6280 IRQ vectors ------------------- $FFF6 IRQ2 (BRK) $FFF8 IRQ1 $FFFA TIMER $FFFC NMI $FFFE RESET Thanks to --------- - Jens Ch. Restemeier, for making this excellent documentation on the PC Engine hardware. - J. H. Van Ornum, for his old 6502 assembler (11/May/84). I used his sources as a base for the assembler. - DJ Delorie, for DJGPP. If you search for a fast, good and *free* C compiler, go to : - Charles Sandmann, for CWSDPMI. A pretty good DPMI server, needed by DJGPP. and to you if you like this program! ;) ------------ David Michel