beebasm
changeset 22:3f1b3ffd6beb v1.04
BeebASM v1.04 - first released Dec 02 2009 21:24:57
| author | Samwise <samwise@bagshot-row.org> |
|---|---|
| date | Sun May 02 12:29:28 2010 +0100 |
| parents | 5db9dbc9a87d |
| children | 1f49259b73aa |
| files | about.txt beebasm.exe src/asmexception.h src/assemble.cpp src/commands.cpp src/expression.cpp src/lineparser.cpp src/lineparser.h src/main.cpp src/objectcode.cpp src/objectcode.h src/sourcefile.cpp src/sourcefile.h |
| diffstat | 13 files changed, 377 insertions(+), 174 deletions(-) [+] |
line diff
1.1 --- a/about.txt Sun May 02 12:27:54 2010 +0100 1.2 +++ b/about.txt Sun May 02 12:29:28 2010 +0100 1.3 @@ -1,10 +1,10 @@ 1.4 ******************************************************************************* 1.5 * * 1.6 -* BeebAsm V1.02 * 1.7 +* BeebAsm V1.04 * 1.8 * * 1.9 * A portable 6502 assembler with BBC Micro style syntax * 1.10 * * 1.11 -* Copyright (C) Rich Talbot-Watkins 2007, 2008 * 1.12 +* Copyright (C) Rich Talbot-Watkins 2007, 2008, 2009 * 1.13 * <rich_tw@hotmail.com> * 1.14 * * 1.15 * This program is free software: you can redistribute it and/or modify * 1.16 @@ -270,6 +270,15 @@ 1.17 blocks. This is exactly equivalent to BBC BASIC's 'P%=<addr>'. 1.18 1.19 1.20 +CPU <n> 1.21 + 1.22 + Selects the target CPU, which determines the range of instructions that 1.23 + will be accepted. The default is 0, which provides the original 6502 1.24 + instruction set. The only current alternative is 1, which provides the 1.25 + 65C02 instruction set (including PLX, TRB etc, but not the Rockwell 1.26 + additions like BBR). 1.27 + 1.28 + 1.29 SKIP <bytes> 1.30 1.31 Moves the address pointer on by the specified number of bytes. Use this to 1.32 @@ -310,6 +319,11 @@ 1.33 Insert the specified 16-bit word(s) into the code. 1.34 1.35 1.36 +EQUD a [, b, c, ...] 1.37 + 1.38 + Insert the specified 32-bit word(s) into the code. 1.39 + 1.40 + 1.41 EQUS "string" [, "string", byte, ...] 1.42 1.43 Inserts the specified string into the code. Note that this can take a comma- 1.44 @@ -421,7 +435,7 @@ 1.45 STX product:STX product+1:RTS 1.46 1.47 1.48 -IF...ELSE...ENDIF 1.49 +IF...ELIF...ELSE...ENDIF 1.50 1.51 Use to assemble conditionally. Like anything else in BeebAsm, these 1.52 statements can be placed on one line, separated by colons, but even if they 1.53 @@ -442,6 +456,17 @@ 1.54 1.55 IF debugraster:LDA #3:STA &FE21:ENDIF 1.56 1.57 + IF rom 1.58 + ORG &8000 1.59 + GUARD &C000 1.60 + ELIF tube 1.61 + ORG &B800 1.62 + GUARD &F800 1.63 + ELSE 1.64 + ORG &3C00 1.65 + GUARD &7C00 1.66 + ENDIF 1.67 + 1.68 1.69 { ... } 1.70 1.71 @@ -583,6 +608,10 @@ 1.72 1.73 9. VERSION HISTORY 1.74 1.75 +02/12/2009 1.04 Additions by Kevin Bracey: 1.76 + Added 65C02 instruction set and CPU directive. 1.77 + Added ELIF, EQUD. 1.78 + SKIP now lists the current address. 1.79 27/07/2009 1.03 Bugfix: Corrected the unary < and > operators to 1.80 correspond to HI and LO as appropriate. 1.81 Added '$' as a valid hex literal prefix.
2.1 Binary file beebasm.exe has changed
3.1 --- a/src/asmexception.h Sun May 02 12:27:54 2010 +0100 3.2 +++ b/src/asmexception.h Sun May 02 12:29:28 2010 +0100 3.3 @@ -187,10 +187,9 @@ 3.4 DEFINE_SYNTAX_EXCEPTION( ImmNegative, "Constant cannot be negative." ); 3.5 DEFINE_SYNTAX_EXCEPTION( UnexpectedComma, "Unexpected comma enountered." ); 3.6 DEFINE_SYNTAX_EXCEPTION( NoImmediate, "Immediate mode not allowed for this instruction." ); 3.7 -DEFINE_SYNTAX_EXCEPTION( NoIndirect16, "16-bit indirect mode not allowed for this instruction." ); 3.8 +DEFINE_SYNTAX_EXCEPTION( NoIndirect, "Indirect mode not allowed for this instruction." ); 3.9 DEFINE_SYNTAX_EXCEPTION( 6502Bug, "JMP (addr) will not execute as intended due to the 6502 bug (addr = &xxFF)." ); 3.10 DEFINE_SYNTAX_EXCEPTION( BadIndirect, "Incorrectly formed indirect instruction." ); 3.11 -DEFINE_SYNTAX_EXCEPTION( NoIndirect, "Indirect mode not allowed for this instruction." ); 3.12 DEFINE_SYNTAX_EXCEPTION( NotZeroPage, "Address is not in zero-page." ); 3.13 DEFINE_SYNTAX_EXCEPTION( BranchOutOfRange, "Branch out of range." ); 3.14 DEFINE_SYNTAX_EXCEPTION( NoAbsolute, "Absolute addressing mode not allowed for this instruction." ); 3.15 @@ -211,6 +210,7 @@ 3.16 DEFINE_SYNTAX_EXCEPTION( MismatchedBraces, "Mismatched braces." ); 3.17 DEFINE_SYNTAX_EXCEPTION( CantInclude, "Cannot include a source file within a FOR loop or braced block." ); 3.18 DEFINE_SYNTAX_EXCEPTION( ElseWithoutIf, "ELSE without IF." ); 3.19 +DEFINE_SYNTAX_EXCEPTION( ElifWithoutIf, "ELIF without IF." ); 3.20 DEFINE_SYNTAX_EXCEPTION( EndifWithoutIf, "ENDIF without IF." ); 3.21 DEFINE_SYNTAX_EXCEPTION( IfWithoutEndif, "IF without ENDIF." ); 3.22 DEFINE_SYNTAX_EXCEPTION( TooManyIFs, "Too many nested IFs." );
4.1 --- a/src/assemble.cpp Sun May 02 12:27:54 2010 +0100 4.2 +++ b/src/assemble.cpp Sun May 02 12:29:28 2010 +0100 4.3 @@ -35,71 +35,82 @@ 4.4 4.5 4.6 4.7 -#define DATA( op, imp, acc, imm, zp, zpx, zpy, abs, absx, absy, indx, indy, ind16, rel ) \ 4.8 - { { imp, acc, imm, zp, zpx, zpy, abs, absx, absy, indx, indy, ind16, rel }, op } 4.9 +#define DATA( cpu, op, imp, acc, imm, zp, zpx, zpy, abs, absx, absy, ind, indx, indy, ind16, ind16x, rel ) \ 4.10 + { { imp, acc, imm, zp, zpx, zpy, abs, absx, absy, ind, indx, indy, ind16, ind16x, rel }, op, cpu } 4.11 4.12 #define X -1 4.13 4.14 -LineParser::OpcodeData LineParser::m_gaOpcodeTable[] = 4.15 +const LineParser::OpcodeData LineParser::m_gaOpcodeTable[] = 4.16 { 4.17 -// IMP ACC IMM ZP ZPX ZPY ABS ABSX ABSY INDX INDY IND16 REL 4.18 +// IMP ACC IMM ZP ZPX ZPY ABS ABSX ABSY IND INDX INDY IND16 IND16X REL 4.19 4.20 - DATA( "ADC", X, X, 0x69, 0x65, 0x75, X, 0x6D, 0x7D, 0x79, 0x61, 0x71, X, X ), 4.21 - DATA( "AND", X, X, 0x29, 0x25, 0x35, X, 0x2D, 0x3D, 0x39, 0x21, 0x31, X, X ), 4.22 - DATA( "ASL", X, 0x0A, X, 0x06, 0x16, X, 0x0E, 0x1E, X, X, X, X, X ), 4.23 - DATA( "BCC", X, X, X, X, X, X, X, X, X, X, X, X, 0x90 ), 4.24 - DATA( "BCS", X, X, X, X, X, X, X, X, X, X, X, X, 0xB0 ), 4.25 - DATA( "BEQ", X, X, X, X, X, X, X, X, X, X, X, X, 0xF0 ), 4.26 - DATA( "BIT", X, X, X, 0x24, X, X, 0x2C, X, X, X, X, X, X ), 4.27 - DATA( "BMI", X, X, X, X, X, X, X, X, X, X, X, X, 0x30 ), 4.28 - DATA( "BNE", X, X, X, X, X, X, X, X, X, X, X, X, 0xD0 ), 4.29 - DATA( "BPL", X, X, X, X, X, X, X, X, X, X, X, X, 0x10 ), 4.30 - DATA( "BRK", 0x00, X, X, X, X, X, X, X, X, X, X, X, X ), 4.31 - DATA( "BVC", X, X, X, X, X, X, X, X, X, X, X, X, 0x50 ), 4.32 - DATA( "BVS", X, X, X, X, X, X, X, X, X, X, X, X, 0x70 ), 4.33 - DATA( "CLC", 0x18, X, X, X, X, X, X, X, X, X, X, X, X ), 4.34 - DATA( "CLD", 0xD8, X, X, X, X, X, X, X, X, X, X, X, X ), 4.35 - DATA( "CLI", 0x58, X, X, X, X, X, X, X, X, X, X, X, X ), 4.36 - DATA( "CLV", 0xB8, X, X, X, X, X, X, X, X, X, X, X, X ), 4.37 - DATA( "CMP", X, X, 0xC9, 0xC5, 0xD5, X, 0xCD, 0xDD, 0xD9, 0xC1, 0xD1, X, X ), 4.38 - DATA( "CPX", X, X, 0xE0, 0xE4, X, X, 0xEC, X, X, X, X, X, X ), 4.39 - DATA( "CPY", X, X, 0xC0, 0xC4, X, X, 0xCC, X, X, X, X, X, X ), 4.40 - DATA( "DEC", X, X, X, 0xC6, 0xD6, X, 0xCE, 0xDE, X, X, X, X, X ), 4.41 - DATA( "DEX", 0xCA, X, X, X, X, X, X, X, X, X, X, X, X ), 4.42 - DATA( "DEY", 0x88, X, X, X, X, X, X, X, X, X, X, X, X ), 4.43 - DATA( "EOR", X, X, 0x49, 0x45, 0x55, X, 0x4D, 0x5D, 0x59, 0x41, 0x51, X, X ), 4.44 - DATA( "INC", X, X, X, 0xE6, 0xF6, X, 0xEE, 0xFE, X, X, X, X, X ), 4.45 - DATA( "INX", 0xE8, X, X, X, X, X, X, X, X, X, X, X, X ), 4.46 - DATA( "INY", 0xC8, X, X, X, X, X, X, X, X, X, X, X, X ), 4.47 - DATA( "JMP", X, X, X, X, X, X, 0x4C, X, X, X, X, 0x6C, X ), 4.48 - DATA( "JSR", X, X, X, X, X, X, 0x20, X, X, X, X, X, X ), 4.49 - DATA( "LDA", X, X, 0xA9, 0xA5, 0xB5, X, 0xAD, 0xBD, 0xB9, 0xA1, 0xB1, X, X ), 4.50 - DATA( "LDX", X, X, 0xA2, 0xA6, X, 0xB6, 0xAE, X, 0xBE, X, X, X, X ), 4.51 - DATA( "LDY", X, X, 0xA0, 0xA4, 0xB4, X, 0xAC, 0xBC, X, X, X, X, X ), 4.52 - DATA( "LSR", X, 0x4A, X, 0x46, 0x56, X, 0x4E, 0x5E, X, X, X, X, X ), 4.53 - DATA( "NOP", 0xEA, X, X, X, X, X, X, X, X, X, X, X, X ), 4.54 - DATA( "ORA", X, X, 0x09, 0x05, 0x15, X, 0x0D, 0x1D, 0x19, 0x01, 0x11, X, X ), 4.55 - DATA( "PHA", 0x48, X, X, X, X, X, X, X, X, X, X, X, X ), 4.56 - DATA( "PHP", 0x08, X, X, X, X, X, X, X, X, X, X, X, X ), 4.57 - DATA( "PLA", 0x68, X, X, X, X, X, X, X, X, X, X, X, X ), 4.58 - DATA( "PLP", 0x28, X, X, X, X, X, X, X, X, X, X, X, X ), 4.59 - DATA( "ROL", X, 0x2A, X, 0x26, 0x36, X, 0x2E, 0x3E, X, X, X, X, X ), 4.60 - DATA( "ROR", X, 0x6A, X, 0x66, 0x76, X, 0x6E, 0x7E, X, X, X, X, X ), 4.61 - DATA( "RTI", 0x40, X, X, X, X, X, X, X, X, X, X, X, X ), 4.62 - DATA( "RTS", 0x60, X, X, X, X, X, X, X, X, X, X, X, X ), 4.63 - DATA( "SBC", X, X, 0xE9, 0xE5, 0xF5, X, 0xED, 0xFD, 0xF9, 0xE1, 0xF1, X, X ), 4.64 - DATA( "SEC", 0x38, X, X, X, X, X, X, X, X, X, X, X, X ), 4.65 - DATA( "SED", 0xF8, X, X, X, X, X, X, X, X, X, X, X, X ), 4.66 - DATA( "SEI", 0x78, X, X, X, X, X, X, X, X, X, X, X, X ), 4.67 - DATA( "STA", X, X, X, 0x85, 0x95, X, 0x8D, 0x9D, 0x99, 0x81, 0x91, X, X ), 4.68 - DATA( "STX", X, X, X, 0x86, X, 0x96, 0x8E, X, X, X, X, X, X ), 4.69 - DATA( "STY", X, X, X, 0x84, 0x94, X, 0x8C, X, X, X, X, X, X ), 4.70 - DATA( "TAX", 0xAA, X, X, X, X, X, X, X, X, X, X, X, X ), 4.71 - DATA( "TAY", 0xA8, X, X, X, X, X, X, X, X, X, X, X, X ), 4.72 - DATA( "TSX", 0xBA, X, X, X, X, X, X, X, X, X, X, X, X ), 4.73 - DATA( "TXA", 0x8A, X, X, X, X, X, X, X, X, X, X, X, X ), 4.74 - DATA( "TXS", 0x9A, X, X, X, X, X, X, X, X, X, X, X, X ), 4.75 - DATA( "TYA", 0x98, X, X, X, X, X, X, X, X, X, X, X, X ) 4.76 + DATA( 0, "ADC", X, X, 0x69, 0x65, 0x75, X, 0x6D, 0x7D, 0x79, 0x172, 0x61, 0x71, X, X, X ), 4.77 + DATA( 0, "AND", X, X, 0x29, 0x25, 0x35, X, 0x2D, 0x3D, 0x39, 0x132, 0x21, 0x31, X, X, X ), 4.78 + DATA( 0, "ASL", X, 0x0A, X, 0x06, 0x16, X, 0x0E, 0x1E, X, X, X, X, X, X, X ), 4.79 + DATA( 0, "BCC", X, X, X, X, X, X, X, X, X, X, X, X, X, X, 0x90 ), 4.80 + DATA( 0, "BCS", X, X, X, X, X, X, X, X, X, X, X, X, X, X, 0xB0 ), 4.81 + DATA( 0, "BEQ", X, X, X, X, X, X, X, X, X, X, X, X, X, X, 0xF0 ), 4.82 + DATA( 0, "BIT", X, X, 0x189, 0x24, 0x134, X, 0x2C, 0x13C, X, X, X, X, X, X, X ), 4.83 + DATA( 0, "BMI", X, X, X, X, X, X, X, X, X, X, X, X, X, X, 0x30 ), 4.84 + DATA( 0, "BNE", X, X, X, X, X, X, X, X, X, X, X, X, X, X, 0xD0 ), 4.85 + DATA( 0, "BPL", X, X, X, X, X, X, X, X, X, X, X, X, X, X, 0x10 ), 4.86 + DATA( 1, "BRA", X, X, X, X, X, X, X, X, X, X, X, X, X, X, 0x180 ), 4.87 + DATA( 0, "BRK", 0x00, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.88 + DATA( 0, "BVC", X, X, X, X, X, X, X, X, X, X, X, X, X, X, 0x50 ), 4.89 + DATA( 0, "BVS", X, X, X, X, X, X, X, X, X, X, X, X, X, X, 0x70 ), 4.90 + DATA( 0, "CLC", 0x18, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.91 + DATA( 0, "CLD", 0xD8, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.92 + DATA( 0, "CLI", 0x58, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.93 + DATA( 1, "CLR", X, X, X, 0x164, 0x174, X, 0x19C, 0x19E, X, X, X, X, X, X, X ), 4.94 + DATA( 0, "CLV", 0xB8, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.95 + DATA( 0, "CMP", X, X, 0xC9, 0xC5, 0xD5, X, 0xCD, 0xDD, 0xD9, 0x1D2, 0xC1, 0xD1, X, X, X ), 4.96 + DATA( 0, "CPX", X, X, 0xE0, 0xE4, X, X, 0xEC, X, X, X, X, X, X, X, X ), 4.97 + DATA( 0, "CPY", X, X, 0xC0, 0xC4, X, X, 0xCC, X, X, X, X, X, X, X, X ), 4.98 + DATA( 1, "DEA", 0x13A, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.99 + DATA( 0, "DEC", X, 0x13A, X, 0xC6, 0xD6, X, 0xCE, 0xDE, X, X, X, X, X, X, X ), 4.100 + DATA( 0, "DEX", 0xCA, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.101 + DATA( 0, "DEY", 0x88, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.102 + DATA( 0, "EOR", X, X, 0x49, 0x45, 0x55, X, 0x4D, 0x5D, 0x59, 0x152, 0x41, 0x51, X, X, X ), 4.103 + DATA( 1, "INA", 0x11A, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.104 + DATA( 0, "INC", X, 0x11A, X, 0xE6, 0xF6, X, 0xEE, 0xFE, X, X, X, X, X, X, X ), 4.105 + DATA( 0, "INX", 0xE8, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.106 + DATA( 0, "INY", 0xC8, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.107 + DATA( 0, "JMP", X, X, X, X, X, X, 0x4C, X, X, X, X, X, 0x6C, 0x17C, X ), 4.108 + DATA( 0, "JSR", X, X, X, X, X, X, 0x20, X, X, X, X, X, X, X, X ), 4.109 + DATA( 0, "LDA", X, X, 0xA9, 0xA5, 0xB5, X, 0xAD, 0xBD, 0xB9, 0x1B2, 0xA1, 0xB1, X, X, X ), 4.110 + DATA( 0, "LDX", X, X, 0xA2, 0xA6, X, 0xB6, 0xAE, X, 0xBE, X, X, X, X, X, X ), 4.111 + DATA( 0, "LDY", X, X, 0xA0, 0xA4, 0xB4, X, 0xAC, 0xBC, X, X, X, X, X, X, X ), 4.112 + DATA( 0, "LSR", X, 0x4A, X, 0x46, 0x56, X, 0x4E, 0x5E, X, X, X, X, X, X, X ), 4.113 + DATA( 0, "NOP", 0xEA, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.114 + DATA( 0, "ORA", X, X, 0x09, 0x05, 0x15, X, 0x0D, 0x1D, 0x19, 0x112, 0x01, 0x11, X, X, X ), 4.115 + DATA( 0, "PHA", 0x48, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.116 + DATA( 0, "PHP", 0x08, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.117 + DATA( 1, "PHX", 0x1DA, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.118 + DATA( 1, "PHY", 0x15A, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.119 + DATA( 0, "PLA", 0x68, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.120 + DATA( 0, "PLP", 0x28, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.121 + DATA( 1, "PLX", 0x1FA, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.122 + DATA( 1, "PLY", 0x17A, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.123 + DATA( 0, "ROL", X, 0x2A, X, 0x26, 0x36, X, 0x2E, 0x3E, X, X, X, X, X, X, X ), 4.124 + DATA( 0, "ROR", X, 0x6A, X, 0x66, 0x76, X, 0x6E, 0x7E, X, X, X, X, X, X, X ), 4.125 + DATA( 0, "RTI", 0x40, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.126 + DATA( 0, "RTS", 0x60, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.127 + DATA( 0, "SBC", X, X, 0xE9, 0xE5, 0xF5, X, 0xED, 0xFD, 0xF9, 0x1F2, 0xE1, 0xF1, X, X, X ), 4.128 + DATA( 0, "SEC", 0x38, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.129 + DATA( 0, "SED", 0xF8, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.130 + DATA( 0, "SEI", 0x78, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.131 + DATA( 0, "STA", X, X, X, 0x85, 0x95, X, 0x8D, 0x9D, 0x99, 0x192, 0x81, 0x91, X, X, X ), 4.132 + DATA( 0, "STX", X, X, X, 0x86, X, 0x96, 0x8E, X, X, X, X, X, X, X, X ), 4.133 + DATA( 0, "STY", X, X, X, 0x84, 0x94, X, 0x8C, X, X, X, X, X, X, X, X ), 4.134 + DATA( 1, "STZ", X, X, X, 0x164, 0x174, X, 0x19C, 0x19E, X, X, X, X, X, X, X ), 4.135 + DATA( 0, "TAX", 0xAA, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.136 + DATA( 0, "TAY", 0xA8, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.137 + DATA( 1, "TRB", X, X, X, 0x114, X, X, 0x11C, X, X, X, X, X, X, X, X ), 4.138 + DATA( 1, "TSB", X, X, X, 0x104, X, X, 0x10C, X, X, X, X, X, X, X, X ), 4.139 + DATA( 0, "TSX", 0xBA, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.140 + DATA( 0, "TXA", 0x8A, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.141 + DATA( 0, "TXS", 0x9A, X, X, X, X, X, X, X, X, X, X, X, X, X, X ), 4.142 + DATA( 0, "TYA", 0x98, X, X, X, X, X, X, X, X, X, X, X, X, X, X ) 4.143 }; 4.144 4.145 4.146 @@ -122,9 +133,14 @@ 4.147 { 4.148 for ( int i = 0; i < static_cast<int>( sizeof m_gaOpcodeTable / sizeof( OpcodeData ) ); i++ ) 4.149 { 4.150 + int cpu = m_gaOpcodeTable[ i ].m_cpu; 4.151 const char* token = m_gaOpcodeTable[ i ].m_pName; 4.152 size_t len = strlen( token ); 4.153 4.154 + // ignore instructions not for current cpu 4.155 + if ( cpu > ObjectCode::Instance().GetCPU() ) 4.156 + continue; 4.157 + 4.158 // create lower-case version of token 4.159 4.160 char tokenLC[ 16 ]; 4.161 @@ -156,7 +172,8 @@ 4.162 /*************************************************************************************************/ 4.163 bool LineParser::HasAddressingMode( int instructionIndex, ADDRESSING_MODE mode ) 4.164 { 4.165 - return ( m_gaOpcodeTable[ instructionIndex ].m_aOpcodes[ mode ] != -1 ); 4.166 + int i = m_gaOpcodeTable[ instructionIndex ].m_aOpcodes[ mode ]; 4.167 + return ( i != -1 && (i & 0xFF00) <= (ObjectCode::Instance().GetCPU() << 8) ); 4.168 } 4.169 4.170 4.171 @@ -171,7 +188,7 @@ 4.172 int i = m_gaOpcodeTable[ instructionIndex ].m_aOpcodes[ mode ]; 4.173 4.174 assert( i != -1 ); 4.175 - return static_cast< unsigned int >( i ); 4.176 + return static_cast< unsigned int >( i & 0xFF ); 4.177 } 4.178 4.179 4.180 @@ -236,7 +253,7 @@ 4.181 { 4.182 cout << "#"; 4.183 } 4.184 - else if ( mode == INDX || mode == INDY ) 4.185 + else if ( mode == IND || mode == INDX || mode == INDY ) 4.186 { 4.187 cout << "("; 4.188 } 4.189 @@ -258,6 +275,10 @@ 4.190 { 4.191 cout << ",Y"; 4.192 } 4.193 + else if ( mode == IND ) 4.194 + { 4.195 + cout << ")"; 4.196 + } 4.197 else if ( mode == INDX ) 4.198 { 4.199 cout << ",X)"; 4.200 @@ -303,7 +324,7 @@ 4.201 cout << setw(2) << ( ( value >> 8 ) & 0xFF ) << " "; 4.202 cout << m_gaOpcodeTable[ instructionIndex ].m_pName << " "; 4.203 4.204 - if ( mode == IND16 ) 4.205 + if ( mode == IND16 || mode == IND16X ) 4.206 { 4.207 cout << "("; 4.208 } 4.209 @@ -322,6 +343,10 @@ 4.210 { 4.211 cout << ")"; 4.212 } 4.213 + else if ( mode == IND16X ) 4.214 + { 4.215 + cout << ",X)"; 4.216 + } 4.217 4.218 cout << endl << nouppercase << dec << setfill( ' ' ); 4.219 } 4.220 @@ -471,34 +496,53 @@ 4.221 } 4.222 } 4.223 4.224 - // the only valid character to find here is ',' for (ind,X) and ')' for (ind),Y and (ind16) 4.225 - 4.226 - // check (ind16) and (ind),Y 4.227 + // the only valid character to find here is ',' for (ind,X) or (ind16,X) and ')' for (ind),Y or (ind16) or (ind) 4.228 + // we know that ind and ind16 forms are exclusive 4.229 + // check (ind), (ind16) and (ind),Y 4.230 4.231 if ( m_line[ m_column ] == ')' ) 4.232 { 4.233 m_column++; 4.234 4.235 - // check (ind16) 4.236 + // check (ind) and (ind16) 4.237 4.238 if ( !AdvanceAndCheckEndOfStatement() ) 4.239 { 4.240 - // nothing else here - must be ind16... see if this is allowed! 4.241 + // nothing else here - must be ind or ind16... see if this is allowed! 4.242 4.243 - if ( !HasAddressingMode( instruction, IND16 ) ) 4.244 + if ( HasAddressingMode( instruction, IND16 ) ) 4.245 { 4.246 - throw AsmException_SyntaxError_NoIndirect16( m_line, oldColumn ); 4.247 + // It is definitely ind16 mode - check for the 6502 bug 4.248 + 4.249 + if ( ( value & 0xFF ) == 0xFF ) 4.250 + { 4.251 + // victim of the 6502 bug! throw an error 4.252 + throw AsmException_SyntaxError_6502Bug( m_line, oldColumn + 1 ); 4.253 + } 4.254 + 4.255 + Assemble3( instruction, IND16, value ); 4.256 + return; 4.257 } 4.258 4.259 - // It is definitely ind16 mode - check for the 6502 bug 4.260 - 4.261 - if ( ( value & 0xFF ) == 0xFF ) 4.262 + if ( !HasAddressingMode( instruction, IND ) ) 4.263 { 4.264 - // victim of the 6502 bug! throw an error 4.265 - throw AsmException_SyntaxError_6502Bug( m_line, oldColumn + 1 ); 4.266 + throw AsmException_SyntaxError_NoIndirect( m_line, oldColumn ); 4.267 } 4.268 4.269 - Assemble3( instruction, IND16, value ); 4.270 + // assemble (ind) instruction 4.271 + 4.272 + if ( value > 0xFF ) 4.273 + { 4.274 + // it's not ZP and it must be 4.275 + throw AsmException_SyntaxError_NotZeroPage( m_line, oldColumn + 1 ); 4.276 + } 4.277 + 4.278 + if ( value < 0 ) 4.279 + { 4.280 + throw AsmException_SyntaxError_BadAddress( m_line, oldColumn + 1 ); 4.281 + } 4.282 + 4.283 + Assemble2( instruction, IND, value ); 4.284 return; 4.285 } 4.286 4.287 @@ -559,7 +603,7 @@ 4.288 throw AsmException_SyntaxError_BadIndirect( m_line, m_column ); 4.289 } 4.290 4.291 - // check (ind,X) 4.292 + // check (ind,X) or (ind16,X) 4.293 4.294 if ( m_line[ m_column ] == ',' ) 4.295 { 4.296 @@ -599,6 +643,14 @@ 4.297 throw AsmException_SyntaxError_BadIndirect( m_line, m_column ); 4.298 } 4.299 4.300 + if ( HasAddressingMode( instruction, IND16X ) ) 4.301 + { 4.302 + // It is definitely ind16,x mode 4.303 + 4.304 + Assemble3( instruction, IND16X, value ); 4.305 + return; 4.306 + } 4.307 + 4.308 // It is definitely (ind,X) - check we can use it 4.309 4.310 if ( !HasAddressingMode( instruction, INDX ) ) 4.311 @@ -624,7 +676,7 @@ 4.312 return; 4.313 } 4.314 4.315 - // If we got here, we identified neither (ind16), (ind,X) nor (ind),Y 4.316 + // If we got here, we identified none of (ind), (ind16), (ind,X), (ind16,X) or (ind),Y 4.317 // Therefore we throw a syntax error 4.318 4.319 throw AsmException_SyntaxError_BadIndirect( m_line, m_column );
5.1 --- a/src/commands.cpp Sun May 02 12:27:54 2010 +0100 5.2 +++ b/src/commands.cpp Sun May 02 12:29:28 2010 +0100 5.3 @@ -37,34 +37,36 @@ 5.4 5.5 using namespace std; 5.6 5.7 - 5.8 -LineParser::Token LineParser::m_gaTokenTable[] = 5.9 +const LineParser::Token LineParser::m_gaTokenTable[] = 5.10 { 5.11 - { ".", &LineParser::HandleDefineLabel }, 5.12 - { "\\", &LineParser::HandleDefineComment }, 5.13 - { ";", &LineParser::HandleDefineComment }, 5.14 - { ":", &LineParser::HandleStatementSeparator }, 5.15 - { "PRINT", &LineParser::HandlePrint }, 5.16 - { "ORG", &LineParser::HandleOrg }, 5.17 - { "INCLUDE", &LineParser::HandleInclude }, 5.18 - { "EQUB", &LineParser::HandleEqub }, 5.19 - { "EQUS", &LineParser::HandleEqub }, 5.20 - { "EQUW", &LineParser::HandleEquw }, 5.21 - { "SAVE", &LineParser::HandleSave }, 5.22 - { "FOR", &LineParser::HandleFor }, 5.23 - { "NEXT", &LineParser::HandleNext }, 5.24 - { "IF", &LineParser::HandleIf }, 5.25 - { "ELSE", &LineParser::HandleElse }, 5.26 - { "ENDIF", &LineParser::HandleEndif }, 5.27 - { "ALIGN", &LineParser::HandleAlign }, 5.28 - { "SKIPTO", &LineParser::HandleSkipTo }, 5.29 - { "SKIP", &LineParser::HandleSkip }, 5.30 - { "GUARD", &LineParser::HandleGuard }, 5.31 - { "CLEAR", &LineParser::HandleClear }, 5.32 - { "INCBIN", &LineParser::HandleIncBin }, 5.33 - { "{", &LineParser::HandleOpenBrace }, 5.34 - { "}", &LineParser::HandleCloseBrace }, 5.35 - { "MAPCHAR", &LineParser::HandleMapChar } 5.36 + { ".", &LineParser::HandleDefineLabel, 0 }, // Why is gcc forcing me to 5.37 + { "\\", &LineParser::HandleDefineComment, 0 }, // put all these 0s in? 5.38 + { ";", &LineParser::HandleDefineComment, 0 }, 5.39 + { ":", &LineParser::HandleStatementSeparator, 0 }, 5.40 + { "PRINT", &LineParser::HandlePrint, 0 }, 5.41 + { "CPU", &LineParser::HandleCpu, 0 }, 5.42 + { "ORG", &LineParser::HandleOrg, 0 }, 5.43 + { "INCLUDE", &LineParser::HandleInclude, 0 }, 5.44 + { "EQUB", &LineParser::HandleEqub, 0 }, 5.45 + { "EQUD", &LineParser::HandleEqud, 0 }, 5.46 + { "EQUS", &LineParser::HandleEqub, 0 }, 5.47 + { "EQUW", &LineParser::HandleEquw, 0 }, 5.48 + { "SAVE", &LineParser::HandleSave, 0 }, 5.49 + { "FOR", &LineParser::HandleFor, 0 }, 5.50 + { "NEXT", &LineParser::HandleNext, 0 }, 5.51 + { "IF", &LineParser::HandleIf, &SourceFile::AddIfLevel }, 5.52 + { "ELIF", &LineParser::HandleIf, &SourceFile::StartElif }, 5.53 + { "ELSE", &LineParser::HandleDirective, &SourceFile::StartElse }, 5.54 + { "ENDIF", &LineParser::HandleDirective, &SourceFile::RemoveIfLevel }, 5.55 + { "ALIGN", &LineParser::HandleAlign, 0 }, 5.56 + { "SKIPTO", &LineParser::HandleSkipTo, 0 }, 5.57 + { "SKIP", &LineParser::HandleSkip, 0 }, 5.58 + { "GUARD", &LineParser::HandleGuard, 0 }, 5.59 + { "CLEAR", &LineParser::HandleClear, 0 }, 5.60 + { "INCBIN", &LineParser::HandleIncBin, 0 }, 5.61 + { "{", &LineParser::HandleOpenBrace, 0 }, 5.62 + { "}", &LineParser::HandleCloseBrace, 0 }, 5.63 + { "MAPCHAR", &LineParser::HandleMapChar, 0 } 5.64 }; 5.65 5.66 5.67 @@ -199,6 +201,23 @@ 5.68 5.69 /*************************************************************************************************/ 5.70 /** 5.71 + LineParser::HandleDirective() 5.72 +*/ 5.73 +/*************************************************************************************************/ 5.74 +void LineParser::HandleDirective() 5.75 +{ 5.76 + // directive that doesn't need extra handling; just check rest of line is empty 5.77 + if ( AdvanceAndCheckEndOfStatement() ) 5.78 + { 5.79 + // found nothing 5.80 + throw AsmException_SyntaxError_InvalidCharacter( m_line, m_column ); 5.81 + } 5.82 +} 5.83 + 5.84 + 5.85 + 5.86 +/*************************************************************************************************/ 5.87 +/** 5.88 LineParser::HandleOrg() 5.89 */ 5.90 /*************************************************************************************************/ 5.91 @@ -224,6 +243,30 @@ 5.92 5.93 /*************************************************************************************************/ 5.94 /** 5.95 + LineParser::HandleCpu() 5.96 +*/ 5.97 +/*************************************************************************************************/ 5.98 +void LineParser::HandleCpu() 5.99 +{ 5.100 + int newCpu = EvaluateExpressionAsInt(); 5.101 + if ( newCpu < 0 || newCpu > 1 ) 5.102 + { 5.103 + throw AsmException_SyntaxError_OutOfRange( m_line, m_column ); 5.104 + } 5.105 + 5.106 + ObjectCode::Instance().SetCPU( newCpu ); 5.107 + 5.108 + if ( m_line[ m_column ] == ',' ) 5.109 + { 5.110 + // Unexpected comma (remembering that an expression can validly end with a comma) 5.111 + throw AsmException_SyntaxError_UnexpectedComma( m_line, m_column ); 5.112 + } 5.113 +} 5.114 + 5.115 + 5.116 + 5.117 +/*************************************************************************************************/ 5.118 +/** 5.119 LineParser::HandleGuard() 5.120 */ 5.121 /*************************************************************************************************/ 5.122 @@ -415,6 +458,12 @@ 5.123 throw AsmException_SyntaxError_ImmNegative( m_line, oldColumn ); 5.124 } 5.125 5.126 + if ( GlobalData::Instance().ShouldOutputAsm() ) 5.127 + { 5.128 + cout << uppercase << hex << setfill( '0' ) << " "; 5.129 + cout << setw(4) << ObjectCode::Instance().GetPC() << endl; 5.130 + } 5.131 + 5.132 for ( int i = 0; i < val; i++ ) 5.133 { 5.134 try 5.135 @@ -796,6 +845,80 @@ 5.136 5.137 /*************************************************************************************************/ 5.138 /** 5.139 + LineParser::HandleEqud() 5.140 +*/ 5.141 +/*************************************************************************************************/ 5.142 +void LineParser::HandleEqud() 5.143 +{ 5.144 + do 5.145 + { 5.146 + int value; 5.147 + 5.148 + try 5.149 + { 5.150 + value = EvaluateExpressionAsInt(); 5.151 + } 5.152 + catch ( AsmException_SyntaxError_SymbolNotDefined& e ) 5.153 + { 5.154 + if ( GlobalData::Instance().IsFirstPass() ) 5.155 + { 5.156 + value = 0; 5.157 + } 5.158 + else 5.159 + { 5.160 + throw; 5.161 + } 5.162 + } 5.163 + 5.164 + if ( GlobalData::Instance().ShouldOutputAsm() ) 5.165 + { 5.166 + cout << uppercase << hex << setfill( '0' ) << " "; 5.167 + cout << setw(4) << ObjectCode::Instance().GetPC() << " "; 5.168 + cout << setw(2) << ( value & 0xFF ) << " "; 5.169 + cout << setw(2) << ( ( value & 0xFF00 ) >> 8 ) << " "; 5.170 + cout << setw(2) << ( ( value & 0xFF0000 ) >> 16 ) << " "; 5.171 + cout << setw(2) << ( ( value & 0xFF000000 ) >> 24 ); 5.172 + cout << endl << nouppercase << dec << setfill( ' ' ); 5.173 + } 5.174 + 5.175 + try 5.176 + { 5.177 + ObjectCode::Instance().PutByte( value & 0xFF ); 5.178 + ObjectCode::Instance().PutByte( ( value & 0xFF00 ) >> 8 ); 5.179 + ObjectCode::Instance().PutByte( ( value & 0xFF0000 ) >> 16 ); 5.180 + ObjectCode::Instance().PutByte( ( value & 0xFF000000 ) >> 24 ); 5.181 + } 5.182 + catch ( AsmException_AssembleError& e ) 5.183 + { 5.184 + e.SetString( m_line ); 5.185 + e.SetColumn( m_column ); 5.186 + throw; 5.187 + } 5.188 + 5.189 + if ( !AdvanceAndCheckEndOfStatement() ) 5.190 + { 5.191 + break; 5.192 + } 5.193 + 5.194 + if ( m_line[ m_column ] != ',' ) 5.195 + { 5.196 + throw AsmException_SyntaxError_InvalidCharacter( m_line, m_column ); 5.197 + } 5.198 + 5.199 + m_column++; 5.200 + 5.201 + if ( !AdvanceAndCheckEndOfStatement() ) 5.202 + { 5.203 + throw AsmException_SyntaxError_EmptyExpression( m_line, m_column ); 5.204 + } 5.205 + 5.206 + } while ( true ); 5.207 +} 5.208 + 5.209 + 5.210 + 5.211 +/*************************************************************************************************/ 5.212 +/** 5.213 LineParser::HandleSave() 5.214 */ 5.215 /*************************************************************************************************/ 5.216 @@ -1129,6 +1252,7 @@ 5.217 /*************************************************************************************************/ 5.218 void LineParser::HandleIf() 5.219 { 5.220 + // Handles both IF and ELIF 5.221 int condition = EvaluateExpressionAsInt(); 5.222 m_sourceFile->SetCurrentIfCondition( condition ); 5.223 5.224 @@ -1143,38 +1267,6 @@ 5.225 5.226 /*************************************************************************************************/ 5.227 /** 5.228 - LineParser::HandleElse() 5.229 -*/ 5.230 -/*************************************************************************************************/ 5.231 -void LineParser::HandleElse() 5.232 -{ 5.233 - if ( AdvanceAndCheckEndOfStatement() ) 5.234 - { 5.235 - // found nothing 5.236 - throw AsmException_SyntaxError_InvalidCharacter( m_line, m_column ); 5.237 - } 5.238 -} 5.239 - 5.240 - 5.241 - 5.242 -/*************************************************************************************************/ 5.243 -/** 5.244 - LineParser::HandleEndif() 5.245 -*/ 5.246 -/*************************************************************************************************/ 5.247 -void LineParser::HandleEndif() 5.248 -{ 5.249 - if ( AdvanceAndCheckEndOfStatement() ) 5.250 - { 5.251 - // found nothing 5.252 - throw AsmException_SyntaxError_InvalidCharacter( m_line, m_column ); 5.253 - } 5.254 -} 5.255 - 5.256 - 5.257 - 5.258 -/*************************************************************************************************/ 5.259 -/** 5.260 LineParser::HandlePrint() 5.261 5.262 Handle PRINT token.
6.1 --- a/src/expression.cpp Sun May 02 12:27:54 2010 +0100 6.2 +++ b/src/expression.cpp Sun May 02 12:29:28 2010 +0100 6.3 @@ -39,7 +39,7 @@ 6.4 6.5 6.6 6.7 -LineParser::Operator LineParser::m_gaBinaryOperatorTable[] = 6.8 +const LineParser::Operator LineParser::m_gaBinaryOperatorTable[] = 6.9 { 6.10 { ")", -1, NULL }, // special case 6.11 { "]", -1, NULL }, // special case 6.12 @@ -69,7 +69,7 @@ 6.13 6.14 6.15 6.16 -LineParser::Operator LineParser::m_gaUnaryOperatorTable[] = 6.17 +const LineParser::Operator LineParser::m_gaUnaryOperatorTable[] = 6.18 { 6.19 { "(", -1, NULL }, // special case 6.20 { "[", -1, NULL }, // special case 6.21 @@ -142,7 +142,7 @@ 6.22 { 6.23 // get a number 6.24 6.25 - int hexValue; 6.26 + unsigned int hexValue; 6.27 6.28 istringstream str( m_line ); 6.29 str.seekg( m_column ); 6.30 @@ -321,7 +321,7 @@ 6.31 { 6.32 // If unary operator *was* found... 6.33 6.34 - Operator& thisOp = m_gaUnaryOperatorTable[ matchedToken ]; 6.35 + const Operator& thisOp = m_gaUnaryOperatorTable[ matchedToken ]; 6.36 6.37 if ( thisOp.handler != NULL ) 6.38 { 6.39 @@ -381,7 +381,7 @@ 6.40 6.41 // we found binary operator 6.42 6.43 - Operator& thisOp = m_gaBinaryOperatorTable[ matchedToken ]; 6.44 + const Operator& thisOp = m_gaBinaryOperatorTable[ matchedToken ]; 6.45 6.46 if ( thisOp.handler != NULL ) 6.47 {
7.1 --- a/src/lineparser.cpp Sun May 02 12:27:54 2010 +0100 7.2 +++ b/src/lineparser.cpp Sun May 02 12:29:28 2010 +0100 7.3 @@ -291,19 +291,9 @@ 7.4 { 7.5 assert( i >= 0 ); 7.6 7.7 - // Do special case handling for IF/ELSE/ENDIF 7.8 - 7.9 - if ( m_gaTokenTable[ i ].m_handler == &LineParser::HandleIf ) 7.10 + if ( m_gaTokenTable[ i ].m_directiveHandler ) 7.11 { 7.12 - m_sourceFile->AddIfLevel( m_line, m_column ); 7.13 - } 7.14 - else if ( m_gaTokenTable[ i ].m_handler == &LineParser::HandleElse ) 7.15 - { 7.16 - m_sourceFile->ToggleCurrentIfCondition( m_line, m_column ); 7.17 - } 7.18 - else if ( m_gaTokenTable[ i ].m_handler == &LineParser::HandleEndif ) 7.19 - { 7.20 - m_sourceFile->RemoveIfLevel( m_line, m_column ); 7.21 + ( m_sourceFile->*m_gaTokenTable[ i ].m_directiveHandler )( m_line, m_column ); 7.22 } 7.23 7.24 if ( m_sourceFile->IsIfConditionTrue() )
8.1 --- a/src/lineparser.h Sun May 02 12:27:54 2010 +0100 8.2 +++ b/src/lineparser.h Sun May 02 12:29:28 2010 +0100 8.3 @@ -46,11 +46,13 @@ 8.4 private: 8.5 8.6 typedef void ( LineParser::*TokenHandler )(); 8.7 + typedef void ( SourceFile::*DirectiveHandler )( std::string line, int column ); 8.8 8.9 struct Token 8.10 { 8.11 - const char* m_pName; 8.12 - TokenHandler m_handler; 8.13 + const char* m_pName; 8.14 + TokenHandler m_handler; 8.15 + DirectiveHandler m_directiveHandler; 8.16 }; 8.17 8.18 enum ADDRESSING_MODE 8.19 @@ -64,9 +66,11 @@ 8.20 ABS, 8.21 ABSX, 8.22 ABSY, 8.23 + IND, 8.24 INDX, 8.25 INDY, 8.26 IND16, 8.27 + IND16X, 8.28 REL, 8.29 8.30 NUM_ADDRESSING_MODES 8.31 @@ -76,6 +80,7 @@ 8.32 { 8.33 short m_aOpcodes[NUM_ADDRESSING_MODES]; 8.34 const char* m_pName; 8.35 + int m_cpu; 8.36 }; 8.37 8.38 8.39 @@ -122,20 +127,21 @@ 8.40 void HandleDefineLabel(); 8.41 void HandleDefineComment(); 8.42 void HandleStatementSeparator(); 8.43 + void HandleDirective(); 8.44 void HandlePrint(); 8.45 + void HandleCpu(); 8.46 void HandleOrg(); 8.47 void HandleInclude(); 8.48 void HandleIncBin(); 8.49 void HandleEqub(); 8.50 void HandleEquw(); 8.51 + void HandleEqud(); 8.52 void HandleSave(); 8.53 void HandleFor(); 8.54 void HandleNext(); 8.55 void HandleOpenBrace(); 8.56 void HandleCloseBrace(); 8.57 void HandleIf(); 8.58 - void HandleElse(); 8.59 - void HandleEndif(); 8.60 void HandleAlign(); 8.61 void HandleSkip(); 8.62 void HandleSkipTo(); 8.63 @@ -195,10 +201,10 @@ 8.64 std::string m_line; 8.65 size_t m_column; 8.66 8.67 - static Token m_gaTokenTable[]; 8.68 - static OpcodeData m_gaOpcodeTable[]; 8.69 - static Operator m_gaUnaryOperatorTable[]; 8.70 - static Operator m_gaBinaryOperatorTable[]; 8.71 + static const Token m_gaTokenTable[]; 8.72 + static const OpcodeData m_gaOpcodeTable[]; 8.73 + static const Operator m_gaUnaryOperatorTable[]; 8.74 + static const Operator m_gaBinaryOperatorTable[]; 8.75 8.76 #define MAX_VALUES 128 8.77 #define MAX_OPERATORS 32
9.1 --- a/src/main.cpp Sun May 02 12:27:54 2010 +0100 9.2 +++ b/src/main.cpp Sun May 02 12:29:28 2010 +0100 9.3 @@ -39,7 +39,7 @@ 9.4 using namespace std; 9.5 9.6 9.7 -#define VERSION "1.03" 9.8 +#define VERSION "1.04" 9.9 9.10 9.11 /*************************************************************************************************/
10.1 --- a/src/objectcode.cpp Sun May 02 12:27:54 2010 +0100 10.2 +++ b/src/objectcode.cpp Sun May 02 12:29:28 2010 +0100 10.3 @@ -77,7 +77,8 @@ 10.4 */ 10.5 /*************************************************************************************************/ 10.6 ObjectCode::ObjectCode() 10.7 - : m_PC( 0 ) 10.8 + : m_PC( 0 ), 10.9 + m_CPU( 0 ) 10.10 { 10.11 memset( m_aMemory, 0, sizeof m_aMemory ); 10.12 memset( m_aFlags, 0, sizeof m_aFlags );
11.1 --- a/src/objectcode.h Sun May 02 12:27:54 2010 +0100 11.2 +++ b/src/objectcode.h Sun May 02 12:29:28 2010 +0100 11.3 @@ -38,6 +38,9 @@ 11.4 inline void SetPC( int i ) { m_PC = i; } 11.5 inline int GetPC() const { return m_PC; } 11.6 11.7 + inline void SetCPU( int i ) { m_CPU = i; } 11.8 + inline int GetCPU() const { return m_CPU; } 11.9 + 11.10 inline const unsigned char* GetAddr( int i ) const { return m_aMemory + i; } 11.11 11.12 void PutByte( unsigned int byte ); 11.13 @@ -70,6 +73,7 @@ 11.14 unsigned char m_aMemory[ 0x10000 ]; 11.15 unsigned char m_aFlags[ 0x10000 ]; 11.16 int m_PC; 11.17 + int m_CPU; 11.18 11.19 unsigned char m_aMapChar[ 96 ]; 11.20
12.1 --- a/src/sourcefile.cpp Sun May 02 12:27:54 2010 +0100 12.2 +++ b/src/sourcefile.cpp Sun May 02 12:29:28 2010 +0100 12.3 @@ -387,6 +387,8 @@ 12.4 } 12.5 12.6 m_ifStack[ m_ifStackPtr ].m_condition = true; 12.7 + m_ifStack[ m_ifStackPtr ].m_passed = false; 12.8 + m_ifStack[ m_ifStackPtr ].m_hadElse = false; 12.9 m_ifStack[ m_ifStackPtr ].m_line = line; 12.10 m_ifStack[ m_ifStackPtr ].m_column = column; 12.11 m_ifStack[ m_ifStackPtr ].m_lineNumber = m_lineNumber; 12.12 @@ -404,23 +406,46 @@ 12.13 { 12.14 assert( m_ifStackPtr > 0 ); 12.15 m_ifStack[ m_ifStackPtr - 1 ].m_condition = b; 12.16 + if ( b ) 12.17 + { 12.18 + m_ifStack[ m_ifStackPtr - 1 ].m_passed = true; 12.19 + } 12.20 } 12.21 12.22 12.23 12.24 /*************************************************************************************************/ 12.25 /** 12.26 - SourceFile::ToggleCurrentIfCondition() 12.27 + SourceFile::StartElse() 12.28 */ 12.29 /*************************************************************************************************/ 12.30 -void SourceFile::ToggleCurrentIfCondition( string line, int column ) 12.31 +void SourceFile::StartElse( string line, int column ) 12.32 { 12.33 - if ( m_ifStackPtr == 0 ) 12.34 + if ( m_ifStack[ m_ifStackPtr - 1 ].m_hadElse ) 12.35 { 12.36 throw AsmException_SyntaxError_ElseWithoutIf( line, column ); 12.37 } 12.38 12.39 - m_ifStack[ m_ifStackPtr - 1 ].m_condition = !m_ifStack[ m_ifStackPtr - 1 ].m_condition; 12.40 + m_ifStack[ m_ifStackPtr - 1 ].m_hadElse = true; 12.41 + 12.42 + m_ifStack[ m_ifStackPtr - 1 ].m_condition = !m_ifStack[ m_ifStackPtr - 1 ].m_passed; 12.43 +} 12.44 + 12.45 + 12.46 + 12.47 +/*************************************************************************************************/ 12.48 +/** 12.49 + SourceFile::StartElif() 12.50 +*/ 12.51 +/*************************************************************************************************/ 12.52 +void SourceFile::StartElif( string line, int column ) 12.53 +{ 12.54 + if ( m_ifStack[ m_ifStackPtr - 1 ].m_hadElse ) 12.55 + { 12.56 + throw AsmException_SyntaxError_ElifWithoutIf( line, column ); 12.57 + } 12.58 + 12.59 + m_ifStack[ m_ifStackPtr - 1 ].m_condition = !m_ifStack[ m_ifStackPtr - 1 ].m_passed; 12.60 } 12.61 12.62
13.1 --- a/src/sourcefile.h Sun May 02 12:27:54 2010 +0100 13.2 +++ b/src/sourcefile.h Sun May 02 12:29:28 2010 +0100 13.3 @@ -75,6 +75,8 @@ 13.4 struct If 13.5 { 13.6 bool m_condition; 13.7 + bool m_hadElse; 13.8 + bool m_passed; 13.9 std::string m_line; 13.10 int m_column; 13.11 int m_lineNumber; 13.12 @@ -105,6 +107,8 @@ 13.13 bool IsIfConditionTrue() const; 13.14 void AddIfLevel( std::string line, int column ); 13.15 void SetCurrentIfCondition( bool b ); 13.16 + void StartElse( std::string line, int column ); 13.17 + void StartElif( std::string line, int column ); 13.18 void ToggleCurrentIfCondition( std::string line, int column ); 13.19 void RemoveIfLevel( std::string line, int column ); 13.20
