-; opcodes.inc\r
-; ca65 6502 - opcode definitions, mainly for self modifying code\r
-;\r
-; Christian Krüger, latest change: 18-Sep-2010\r
-;\r
-; This software is provided 'as-is', without any expressed or implied \r
-; warranty. In no event will the authors be held liable for any damages \r
-; arising from the use of this software. \r
-; \r
-; Permission is granted to anyone to use this software for any purpose, \r
-; including commercial applications, and to alter it and redistribute it \r
-; freely, subject to the following restrictions: \r
-; \r
-; 1. The origin of this software must not be misrepresented; you must not \r
-; claim that you wrote the original software. If you use this software \r
-; in a product, an acknowledgment in the product documentation would be \r
-; appreciated but is not required. \r
-; 2. Altered source versions must be plainly marked as such, and must not \r
-; be misrepresented as being the original software. \r
-; 3. This notice may not be removed or altered from any source \r
-; distribution. \r
-; \r
-\r
-; Opcode-Table\r
-; ------------\r
-; Post fix explanation:\r
-; imm = #$00\r
-; zp = $00\r
-; zpx = $00,X\r
-; zpy = $00,Y\r
-; izp = ($00)\r
-; izx = ($00,X)\r
-; izy = ($00),Y\r
-; abs = $0000\r
-; abx = $0000,X\r
-; aby = $0000,Y\r
-; ind = ($0000)\r
-; iax = ($0000,X)\r
-; rel = $0000 (PC-relative) (supressed here)\r
-\r
-.macpack cpu\r
-\r
-OPC_BRK = $00\r
-OPC_ORA_izx = $01\r
-OPC_ORA_zp = $05\r
-OPC_ASL_zp = $06\r
-OPC_PHP = $08\r
-OPC_ORA_imm = $09\r
-OPC_ASL = $0A\r
-OPC_ORA_abs = $0D\r
-OPC_ASL_abs = $0E\r
-\r
-OPC_BPL = $10\r
-OPC_ORA_izy = $11\r
-OPC_ORA_zpx = $15\r
-OPC_ASL_zpx = $16\r
-OPC_CLC = $18\r
-OPC_ORA_aby = $19\r
-OPC_ORA_abx = $1D\r
-OPC_ASL_abx = $1E\r
-\r
-OPC_JSR_abs = $20\r
-OPC_AND_izx = $21\r
-OPC_BIT_zp = $24\r
-OPC_AND_zp = $25\r
-OPC_ROL_zp = $26\r
-OPC_PLP = $28\r
-OPC_AND_imm = $29\r
-OPC_ROL = $2A\r
-OPC_BIT_abs = $2C\r
-OPC_AND_abs = $2D\r
-OPC_ROL_abs = $2E\r
-\r
-OPC_BMI = $30\r
-OPC_AND_izy = $31\r
-OPC_AND_zpx = $35\r
-OPC_ROL_zpx = $36\r
-OPC_SEC = $38\r
-OPC_AND_aby = $39\r
-OPC_AND_abx = $3D\r
-OPC_ROL_abx = $3E\r
-\r
-\r
-OPC_RTI = $40\r
-OPC_EOR_izx = $41\r
-OPC_EOR_zp = $45\r
-OPC_LSR_zp = $46\r
-OPC_PHA = $48\r
-OPC_EOR_imm = $49\r
-OPC_LSR = $4A\r
-OPC_JMP_abs = $4C\r
-OPC_EOR_abs = $4D\r
-OPC_LSR_abs = $4E\r
-\r
-OPC_BVC = $50\r
-OPC_EOR_izy = $51\r
-OPC_EOR_zpx = $55\r
-OPC_LSR_zpx = $56\r
-OPC_CLI = $58\r
-OPC_EOR_aby = $59\r
-OPC_EOR_abx = $5D\r
-OPC_LSR_abx = $5E\r
-\r
-OPC_RTS = $60\r
-OPC_ADC_izx = $61\r
-OPC_ADC_zp = $65\r
-OPC_ROR_zp = $66\r
-OPC_PLA = $68\r
-OPC_ADC_imm = $69\r
-OPC_ROR = $6A\r
-OPC_JMP_ind = $6C\r
-OPC_ADC_abs = $6D\r
-OPC_ROR_abs = $6E\r
-\r
-OPC_BVS = $70\r
-OPC_ADC_izy = $71\r
-OPC_ADC_zpx = $75\r
-OPC_ROR_zpx = $76\r
-OPC_SEI = $78\r
-OPC_ADC_aby = $79\r
-OPC_ADC_abx = $7D\r
-OPC_ROR_abx = $7E\r
-\r
-OPC_STA_izx = $81\r
-OPC_STY_zp = $84\r
-OPC_STA_zp = $85\r
-OPC_STX_zp = $86\r
-OPC_DEY = $88\r
-OPC_TXA = $8A\r
-OPC_STY_abs = $8C\r
-OPC_STA_abs = $8D\r
-OPC_STX_abs = $8E\r
-\r
-OPC_BCC = $90\r
-OPC_STA_izy = $91\r
-OPC_STY_zpx = $94\r
-OPC_STA_zpx = $95\r
-OPC_STX_zpy = $96\r
-OPC_TYA = $98\r
-OPC_STA_aby = $99\r
-OPC_TXS = $9A\r
-OPC_STA_abx = $9D\r
-\r
-OPC_LDY_imm = $A0\r
-OPC_LDA_izx = $A1\r
-OPC_LDX_imm = $A2\r
-OPC_LDY_zp = $A4\r
-OPC_LDA_zp = $A5\r
-OPC_LDX_zp = $A6\r
-OPC_TAY = $A8\r
-OPC_LDA_imm = $A9\r
-OPC_TAX = $AA\r
-OPC_LDY_abs = $AC\r
-OPC_LDA_abs = $AD\r
-OPC_LDX_abs = $AE\r
-\r
-OPC_BCS = $B0\r
-OPC_LDA_izy = $B1\r
-OPC_LDY_zpx = $B4\r
-OPC_LDA_zpx = $B5\r
-OPC_LDX_zpy = $B6\r
-OPC_CLV = $B8\r
-OPC_LDA_aby = $B9\r
-OPC_TSX = $BA\r
-OPC_LDY_abx = $BC\r
-OPC_LDA_abx = $BD\r
-OPC_LDX_aby = $BE\r
-\r
-OPC_CPY_imm = $C0\r
-OPC_CMP_izx = $C1\r
-OPC_CPY_zp = $C4\r
-OPC_CMP_zp = $C5\r
-OPC_DEC_zp = $C6\r
-OPC_INY = $C8\r
-OPC_CMP_imm = $C9\r
-OPC_DEX = $CA\r
-OPC_CPY_abs = $CC\r
-OPC_CMP_abs = $CD\r
-OPC_DEC_abs = $CE\r
-\r
-OPC_BNE = $D0\r
-OPC_CMP_izy = $D1\r
-OPC_CMP_zpx = $D5\r
-OPC_DEC_zpx = $D6\r
-OPC_CLD = $D8\r
-OPC_CMP_aby = $D9\r
-OPC_CMP_abx = $DD\r
-OPC_DEC_abx = $DE\r
-\r
-OPC_CPX_imm = $E0\r
-OPC_SBC_izx = $E1\r
-OPC_CPX_zp = $E4\r
-OPC_SBC_zp = $E5\r
-OPC_INC_zp = $E6\r
-OPC_INX = $E8\r
-OPC_SBC_imm = $E9\r
-OPC_NOP = $EA\r
-OPC_CPX_abs = $EC\r
-OPC_SBC_abs = $ED\r
-OPC_INC_abs = $EE\r
-\r
-\r
-OPC_BEQ = $F0\r
-OPC_SBC_izy = $F1\r
-OPC_SBC_zpx = $F5\r
-OPC_INC_zpx = $F6\r
-OPC_SED = $F8\r
-OPC_SBC_aby = $F9\r
-OPC_SBC_abx = $FD\r
-OPC_INC_abx = $FE\r
-\r
-\r
-.if (.cpu .bitand ::CPU_ISET_65SC02)\r
-\r
-; OPC_NOP = $02 ; doublet\r
-; OPC_NOP = $03 ; doublet\r
-OPC_TSB_zp = $04\r
-; OPC_NOP = $0B ; doublet\r
-OPC_TSB_abs = $0C\r
-\r
-OPC_ORA_izp = $12\r
-; OPC_NOP = $13 ; doublet\r
-OPC_TRB_zp = $14\r
-OPC_INC = $1A\r
-; OPC_NOP = $1B ; doublet\r
-OPC_TRB_abs = $1C\r
-\r
-; OPC_NOP = $22 ; doublet\r
-; OPC_NOP = $23 ; doublet\r
-; OPC_NOP = $2B ; doublet\r
-\r
-OPC_AND_izp = $32\r
-; OPC_NOP = $33 ; doublet\r
-OPC_BIT_zpx = $34\r
-OPC_DEC = $3A\r
-; OPC_NOP = $3B ; doublet\r
-OPC_BIT_abx = $3C\r
-\r
-; OPC_NOP = $42 ; doublet\r
-; OPC_NOP = $43 ; doublet\r
-; OPC_NOP = $44 ; doublet\r
-; OPC_NOP = $4B ; doublet\r
-\r
-OPC_EOR_izp = $52 \r
-; OPC_NOP = $53 ; doublet\r
-; OPC_NOP = $54 ; doublet\r
-; OPC_NOP = $5A ; doublet\r
-; OPC_NOP = $5B ; doublet\r
-OPC_EOR_abx = $5C\r
-\r
-; OPC_NOP = $62 ; doublet\r
-; OPC_NOP = $63 ; doublet\r
-OPC_STZ_zp = $64\r
-; OPC_NOP = $6B ; doublet\r
-\r
-OPC_ADC_izp = $72\r
-; OPC_NOP = $73 ; doublet\r
-OPC_STZ_zpx = $74\r
-OPC_PLY = $7A\r
-; OPC_NOP = $7B ; doublet\r
-OPC_JMP_iax = $7C\r
-\r
-OPC_BRA = $80\r
-; OPC_NOP = $82 ; doublet\r
-; OPC_NOP = $83 ; doublet\r
-OPC_BIT_imm = $89\r
-; OPC_NOP = $8B ; doublet\r
-\r
-OPC_STA_izp = $92\r
-; OPC_NOP = $93 ; doublet\r
-; OPC_NOP = $9B ; doublet\r
-OPC_STZ_abs = $9C\r
-OPC_STZ_abx = $9E\r
-\r
-; OPC_NOP = $A3 ; doublet\r
-; OPC_NOP = $AB ; doublet\r
-\r
-OPC_LDA_izp = $B2\r
-; OPC_NOP = $B3 ; doublet\r
-; OPC_NOP = $BB ; doublet\r
-\r
-; OPC_NOP = $C2 ; doublet\r
-; OPC_NOP = $C3 ; doublet\r
-; OPC_NOP = $CB ; doublet\r
-\r
-OPC_CMP_izp = $D2\r
-; OPC_NOP = $D3 ; doublet\r
-; OPC_NOP = $D4 ; doublet\r
-OPC_PHX = $DA\r
-; OPC_NOP = $DB ; doublet\r
-; OPC_NOP = $DC ; doublet\r
-\r
-; OPC_NOP = $E2 ; doublet\r
-; OPC_NOP = $E3 ; doublet\r
-; OPC_NOP = $EB ; doublet\r
-\r
-OPC_SBC_izp = $F2\r
-; OPC_NOP = $F3 ; doublet\r
-; OPC_NOP = $F4 ; doublet\r
-OPC_PLX = $FA\r
-; OPC_NOP = $FB ; doublet\r
-; OPC_NOP = $FC ; doublet\r
-\r
-\r
-.if (.cpu .bitand ::CPU_ISET_65C02)\r
-\r
-; bit instructions for 65C02\r
-\r
-OPC_RMB0 = $07\r
-OPC_RMB1 = $17\r
-OPC_RMB2 = $27\r
-OPC_RMB3 = $37\r
-OPC_RMB4 = $47\r
-OPC_RMB5 = $57\r
-OPC_RMB6 = $67\r
-OPC_RMB7 = $77\r
-\r
-OPC_SMB0 = $87\r
-OPC_SMB1 = $97\r
-OPC_SMB2 = $A7\r
-OPC_SMB3 = $B7\r
-OPC_SMB4 = $C7\r
-OPC_SMB5 = $D7\r
-OPC_SMB6 = $E7\r
-OPC_SMB7 = $F7\r
-\r
-OPC_BBR0 = $0F\r
-OPC_BBR1 = $1F\r
-OPC_BBR2 = $2F\r
-OPC_BBR3 = $3F\r
-OPC_BBR4 = $4F\r
-OPC_BBR5 = $5F\r
-OPC_BBR6 = $6F\r
-OPC_BBR7 = $7F\r
-\r
-OPC_BBS0 = $8F\r
-OPC_BBS1 = $9F\r
-OPC_BBS2 = $AF\r
-OPC_BBS3 = $BF\r
-OPC_BBS4 = $CF\r
-OPC_BBS5 = $DF\r
-OPC_BBS6 = $EF\r
-OPC_BBS7 = $FF\r
-\r
-.else\r
-\r
-; no bit instructions for 65SC02\r
-\r
-; OPC_NOP = $07 ; doublet\r
-; OPC_NOP = $17 ; doublet\r
-; OPC_NOP = $27 ; doublet\r
-; OPC_NOP = $37 ; doublet\r
-; OPC_NOP = $47 ; doublet\r
-; OPC_NOP = $57 ; doublet\r
-; OPC_NOP = $67 ; doublet\r
-; OPC_NOP = $77 ; doublet\r
-; OPC_NOP = $87 ; doublet\r
-; OPC_NOP = $97 ; doublet\r
-; OPC_NOP = $A7 ; doublet\r
-; OPC_NOP = $B7 ; doublet\r
-; OPC_NOP = $C7 ; doublet\r
-; OPC_NOP = $D7 ; doublet\r
-; OPC_NOP = $E7 ; doublet\r
-; OPC_NOP = $F7 ; doublet\r
-; OPC_NOP = $0F ; doublet\r
-; OPC_NOP = $1F ; doublet\r
-; OPC_NOP = $2F ; doublet\r
-; OPC_NOP = $3F ; doublet\r
-; OPC_NOP = $4F ; doublet\r
-; OPC_NOP = $5F ; doublet\r
-; OPC_NOP = $6F ; doublet\r
-; OPC_NOP = $7F ; doublet\r
-; OPC_NOP = $8F ; doublet\r
-; OPC_NOP = $9F ; doublet\r
-; OPC_NOP = $AF ; doublet\r
-; OPC_NOP = $BF ; doublet\r
-; OPC_NOP = $CF ; doublet\r
-; OPC_NOP = $DF ; doublet\r
-; OPC_NOP = $EF ; doublet\r
-; OPC_NOP = $FF ; doublet\r
-\r
-.endif\r
-\r
-.elseif (.cpu .bitand ::CPU_ISET_6502X)\r
-\r
-; stable, undocumented opcodes\r
-\r
-; OPC_KIL = $02 ; unstable\r
-OPC_SLO_izx = $03\r
-OPC_NOP_zp = $04\r
-OPC_SLO_zp = $07\r
-OPC_ANC_imm = $0B\r
-OPC_NOP_abs = $0C\r
-OPC_SLO_abs = $0F\r
-\r
-; OPC_KIL = $12 ; unstable\r
-OPC_SLO_izy = $13\r
-OPC_NOP_zpx = $14\r
-OPC_SLO_zpx = $17\r
-;OPC_NOP = $1A\r
-OPC_SLO_aby = $1B\r
-OPC_NOP_abx = $1C\r
-OPC_SLO_abx = $1F\r
-\r
-; OPC_KIL = $22 ; unstable\r
-OPC_RLA_izx = $23\r
-OPC_RLA_zp = $27\r
-OPC_ANC_imm = $2B\r
-OPC_RLA_abs = $2F\r
-\r
-; OPC_KIL = $32 ; unstable\r
-OPC_RLA_izy = $33\r
-OPC_NOP_zpx = $34\r
-OPC_RLA_zpx = $37\r
-; OPC_NOP = $3A ; doublet\r
-OPC_RLA_aby = $3B\r
-OPC_NOP_abx = $3C\r
-OPC_RLA_abx = $3F\r
-\r
-; OPC_KIL = $42 ; unstable\r
-OPC_SRE_izx = $43\r
-OPC_NOP_zp = $44\r
-OPC_SRE_zp = $47\r
-OPC_ALR_imm = $4B\r
-OPC_SRE_abs = $4F\r
-\r
-; OPC_KIL = $52 ; unstable\r
-OPC_SRE_izy = $53\r
-OPC_NOP_zpx = $54\r
-OPC_SRE_zpx = $57\r
-; OPC_NOP = $5A ; doublet\r
-OPC_SRE_aby = $5B\r
-OPC_NOP_abx = $5C\r
-OPC_SRE_abx = $5F\r
-\r
-; OPC_KIL = $62\r
-OPC_RRA_izx = $63\r
-OPC_NOP_zp = $64\r
-OPC_RRA_zp = $67\r
-OPC_ARR_imm = $6B\r
-OPC_RRA_abs = $6F\r
-\r
-; OPC_KIL = $72\r
-OPC_RRA_izy = $73\r
-OPC_NOP_zpx = $74\r
-OPC_RRA_zpx = $77\r
-; OPC_NOP = $7A ; doublet\r
-OPC_RRA_aby = $7B\r
-OPC_NOP_abx = $7C\r
-OPC_RRA_abx = $7F\r
-\r
-OPC_NOP_imm = $80\r
-; OPC_NOP_imm = $82 ; doublet\r
-OPC_SAX_izx = $83\r
-OPC_SAX_zp = $87\r
-; OPC_NOP_imm = $89 ; doublet\r
-; OPC_XAA = $8B ; unstable\r
-OPC_SAX_abs = $8F\r
-\r
-; OPC_KIL = $92 ; unstable\r
-; OPC_AHX_izy = $93 ; unstable\r
-OPC_SAX_zpy = $97\r
-; OPC_TAS_aby = $9B ; unstable\r
-; OPC_SHY_abx = $9C ; unstable\r
-; OPC_SHX_aby = $9E ; unstable\r
-; OPC_AHX_aby = $9F ; unstable\r
-\r
-OPC_LAX_izx = $A3\r
-OPC_LAX_zp = $A7\r
-; OPC_LAX_imm = $AB ; unstable\r
-OPC_LAX_abs = $AF\r
-\r
-; OPC_KIL = $B2 ; unstable\r
-OPC_LAX_izy = $B3\r
-OPC_LAX_zpy = $B7\r
-OPC_LAS_aby = $BB\r
-OPC_LAX_aby = $BF\r
-\r
-; OPC_NOP_imm = $C2 ; doublet\r
-OPC_DCP_izx = $C3\r
-OPC_DCP_zp = $C7\r
-OPC_AXS_imm = $CB\r
-OPC_DCP_abs = $CF\r
-\r
-; OPC_KIL = $D2 ; unstable\r
-OPC_DCP_izy = $D3\r
-OPC_NOP_zpx = $D4\r
-OPC_DCP_zpx = $D7\r
-OPC_NOP_DA = $DA\r
-OPC_DCP_aby = $DB\r
-OPC_NOP_abx = $DC\r
-OPC_DCP_abx = $DF\r
-\r
-; OPC_NOP_imm = $E2 ; doublet\r
-OPC_ISC_izx = $E3\r
-OPC_ISC_zp = $E7\r
-; OPC_SBC_imm = $EB ; doublet\r
-OPC_ISC_abs = $EF\r
-\r
-; OPC_KIL = $F2 ; unstable\r
-OPC_ISC_izy = $F3\r
-OPC_NOP_zpx = $F4\r
-OPC_ISC_zpx = $F7\r
-OPC_NOP_FA = $FA\r
-OPC_ISC_aby = $FB\r
-OPC_NOP_abx = $FC\r
-OPC_ISC_abx = $FF\r
-\r
-.endif\r
+; opcodes.inc
+; ca65 6502 - opcode definitions, mainly for self modifying code
+;
+; Christian Krüger, latest change: 18-Sep-2010
+;
+; This software is provided 'as-is', without any expressed or implied
+; warranty. In no event will the authors be held liable for any damages
+; arising from the use of this software.
+;
+; Permission is granted to anyone to use this software for any purpose,
+; including commercial applications, and to alter it and redistribute it
+; freely, subject to the following restrictions:
+;
+; 1. The origin of this software must not be misrepresented; you must not
+; claim that you wrote the original software. If you use this software
+; in a product, an acknowledgment in the product documentation would be
+; appreciated but is not required.
+; 2. Altered source versions must be plainly marked as such, and must not
+; be misrepresented as being the original software.
+; 3. This notice may not be removed or altered from any source
+; distribution.
+;
+
+; Opcode-Table
+; ------------
+; Post fix explanation:
+; imm = #$00
+; zp = $00
+; zpx = $00,X
+; zpy = $00,Y
+; izp = ($00)
+; izx = ($00,X)
+; izy = ($00),Y
+; abs = $0000
+; abx = $0000,X
+; aby = $0000,Y
+; ind = ($0000)
+; iax = ($0000,X)
+; rel = $0000 (PC-relative) (supressed here)
+
+.macpack cpu
+
+OPC_BRK = $00
+OPC_ORA_izx = $01
+OPC_ORA_zp = $05
+OPC_ASL_zp = $06
+OPC_PHP = $08
+OPC_ORA_imm = $09
+OPC_ASL = $0A
+OPC_ORA_abs = $0D
+OPC_ASL_abs = $0E
+
+OPC_BPL = $10
+OPC_ORA_izy = $11
+OPC_ORA_zpx = $15
+OPC_ASL_zpx = $16
+OPC_CLC = $18
+OPC_ORA_aby = $19
+OPC_ORA_abx = $1D
+OPC_ASL_abx = $1E
+
+OPC_JSR_abs = $20
+OPC_AND_izx = $21
+OPC_BIT_zp = $24
+OPC_AND_zp = $25
+OPC_ROL_zp = $26
+OPC_PLP = $28
+OPC_AND_imm = $29
+OPC_ROL = $2A
+OPC_BIT_abs = $2C
+OPC_AND_abs = $2D
+OPC_ROL_abs = $2E
+
+OPC_BMI = $30
+OPC_AND_izy = $31
+OPC_AND_zpx = $35
+OPC_ROL_zpx = $36
+OPC_SEC = $38
+OPC_AND_aby = $39
+OPC_AND_abx = $3D
+OPC_ROL_abx = $3E
+
+
+OPC_RTI = $40
+OPC_EOR_izx = $41
+OPC_EOR_zp = $45
+OPC_LSR_zp = $46
+OPC_PHA = $48
+OPC_EOR_imm = $49
+OPC_LSR = $4A
+OPC_JMP_abs = $4C
+OPC_EOR_abs = $4D
+OPC_LSR_abs = $4E
+
+OPC_BVC = $50
+OPC_EOR_izy = $51
+OPC_EOR_zpx = $55
+OPC_LSR_zpx = $56
+OPC_CLI = $58
+OPC_EOR_aby = $59
+OPC_EOR_abx = $5D
+OPC_LSR_abx = $5E
+
+OPC_RTS = $60
+OPC_ADC_izx = $61
+OPC_ADC_zp = $65
+OPC_ROR_zp = $66
+OPC_PLA = $68
+OPC_ADC_imm = $69
+OPC_ROR = $6A
+OPC_JMP_ind = $6C
+OPC_ADC_abs = $6D
+OPC_ROR_abs = $6E
+
+OPC_BVS = $70
+OPC_ADC_izy = $71
+OPC_ADC_zpx = $75
+OPC_ROR_zpx = $76
+OPC_SEI = $78
+OPC_ADC_aby = $79
+OPC_ADC_abx = $7D
+OPC_ROR_abx = $7E
+
+OPC_STA_izx = $81
+OPC_STY_zp = $84
+OPC_STA_zp = $85
+OPC_STX_zp = $86
+OPC_DEY = $88
+OPC_TXA = $8A
+OPC_STY_abs = $8C
+OPC_STA_abs = $8D
+OPC_STX_abs = $8E
+
+OPC_BCC = $90
+OPC_STA_izy = $91
+OPC_STY_zpx = $94
+OPC_STA_zpx = $95
+OPC_STX_zpy = $96
+OPC_TYA = $98
+OPC_STA_aby = $99
+OPC_TXS = $9A
+OPC_STA_abx = $9D
+
+OPC_LDY_imm = $A0
+OPC_LDA_izx = $A1
+OPC_LDX_imm = $A2
+OPC_LDY_zp = $A4
+OPC_LDA_zp = $A5
+OPC_LDX_zp = $A6
+OPC_TAY = $A8
+OPC_LDA_imm = $A9
+OPC_TAX = $AA
+OPC_LDY_abs = $AC
+OPC_LDA_abs = $AD
+OPC_LDX_abs = $AE
+
+OPC_BCS = $B0
+OPC_LDA_izy = $B1
+OPC_LDY_zpx = $B4
+OPC_LDA_zpx = $B5
+OPC_LDX_zpy = $B6
+OPC_CLV = $B8
+OPC_LDA_aby = $B9
+OPC_TSX = $BA
+OPC_LDY_abx = $BC
+OPC_LDA_abx = $BD
+OPC_LDX_aby = $BE
+
+OPC_CPY_imm = $C0
+OPC_CMP_izx = $C1
+OPC_CPY_zp = $C4
+OPC_CMP_zp = $C5
+OPC_DEC_zp = $C6
+OPC_INY = $C8
+OPC_CMP_imm = $C9
+OPC_DEX = $CA
+OPC_CPY_abs = $CC
+OPC_CMP_abs = $CD
+OPC_DEC_abs = $CE
+
+OPC_BNE = $D0
+OPC_CMP_izy = $D1
+OPC_CMP_zpx = $D5
+OPC_DEC_zpx = $D6
+OPC_CLD = $D8
+OPC_CMP_aby = $D9
+OPC_CMP_abx = $DD
+OPC_DEC_abx = $DE
+
+OPC_CPX_imm = $E0
+OPC_SBC_izx = $E1
+OPC_CPX_zp = $E4
+OPC_SBC_zp = $E5
+OPC_INC_zp = $E6
+OPC_INX = $E8
+OPC_SBC_imm = $E9
+OPC_NOP = $EA
+OPC_CPX_abs = $EC
+OPC_SBC_abs = $ED
+OPC_INC_abs = $EE
+
+
+OPC_BEQ = $F0
+OPC_SBC_izy = $F1
+OPC_SBC_zpx = $F5
+OPC_INC_zpx = $F6
+OPC_SED = $F8
+OPC_SBC_aby = $F9
+OPC_SBC_abx = $FD
+OPC_INC_abx = $FE
+
+
+.if (.cpu .bitand ::CPU_ISET_65SC02)
+
+; OPC_NOP = $02 ; doublet
+; OPC_NOP = $03 ; doublet
+OPC_TSB_zp = $04
+; OPC_NOP = $0B ; doublet
+OPC_TSB_abs = $0C
+
+OPC_ORA_izp = $12
+; OPC_NOP = $13 ; doublet
+OPC_TRB_zp = $14
+OPC_INC = $1A
+; OPC_NOP = $1B ; doublet
+OPC_TRB_abs = $1C
+
+; OPC_NOP = $22 ; doublet
+; OPC_NOP = $23 ; doublet
+; OPC_NOP = $2B ; doublet
+
+OPC_AND_izp = $32
+; OPC_NOP = $33 ; doublet
+OPC_BIT_zpx = $34
+OPC_DEC = $3A
+; OPC_NOP = $3B ; doublet
+OPC_BIT_abx = $3C
+
+; OPC_NOP = $42 ; doublet
+; OPC_NOP = $43 ; doublet
+; OPC_NOP = $44 ; doublet
+; OPC_NOP = $4B ; doublet
+
+OPC_EOR_izp = $52
+; OPC_NOP = $53 ; doublet
+; OPC_NOP = $54 ; doublet
+; OPC_NOP = $5A ; doublet
+; OPC_NOP = $5B ; doublet
+OPC_EOR_abx = $5C
+
+; OPC_NOP = $62 ; doublet
+; OPC_NOP = $63 ; doublet
+OPC_STZ_zp = $64
+; OPC_NOP = $6B ; doublet
+
+OPC_ADC_izp = $72
+; OPC_NOP = $73 ; doublet
+OPC_STZ_zpx = $74
+OPC_PLY = $7A
+; OPC_NOP = $7B ; doublet
+OPC_JMP_iax = $7C
+
+OPC_BRA = $80
+; OPC_NOP = $82 ; doublet
+; OPC_NOP = $83 ; doublet
+OPC_BIT_imm = $89
+; OPC_NOP = $8B ; doublet
+
+OPC_STA_izp = $92
+; OPC_NOP = $93 ; doublet
+; OPC_NOP = $9B ; doublet
+OPC_STZ_abs = $9C
+OPC_STZ_abx = $9E
+
+; OPC_NOP = $A3 ; doublet
+; OPC_NOP = $AB ; doublet
+
+OPC_LDA_izp = $B2
+; OPC_NOP = $B3 ; doublet
+; OPC_NOP = $BB ; doublet
+
+; OPC_NOP = $C2 ; doublet
+; OPC_NOP = $C3 ; doublet
+; OPC_NOP = $CB ; doublet
+
+OPC_CMP_izp = $D2
+; OPC_NOP = $D3 ; doublet
+; OPC_NOP = $D4 ; doublet
+OPC_PHX = $DA
+; OPC_NOP = $DB ; doublet
+; OPC_NOP = $DC ; doublet
+
+; OPC_NOP = $E2 ; doublet
+; OPC_NOP = $E3 ; doublet
+; OPC_NOP = $EB ; doublet
+
+OPC_SBC_izp = $F2
+; OPC_NOP = $F3 ; doublet
+; OPC_NOP = $F4 ; doublet
+OPC_PLX = $FA
+; OPC_NOP = $FB ; doublet
+; OPC_NOP = $FC ; doublet
+
+
+.if (.cpu .bitand ::CPU_ISET_65C02)
+
+; bit instructions for 65C02
+
+OPC_RMB0 = $07
+OPC_RMB1 = $17
+OPC_RMB2 = $27
+OPC_RMB3 = $37
+OPC_RMB4 = $47
+OPC_RMB5 = $57
+OPC_RMB6 = $67
+OPC_RMB7 = $77
+
+OPC_SMB0 = $87
+OPC_SMB1 = $97
+OPC_SMB2 = $A7
+OPC_SMB3 = $B7
+OPC_SMB4 = $C7
+OPC_SMB5 = $D7
+OPC_SMB6 = $E7
+OPC_SMB7 = $F7
+
+OPC_BBR0 = $0F
+OPC_BBR1 = $1F
+OPC_BBR2 = $2F
+OPC_BBR3 = $3F
+OPC_BBR4 = $4F
+OPC_BBR5 = $5F
+OPC_BBR6 = $6F
+OPC_BBR7 = $7F
+
+OPC_BBS0 = $8F
+OPC_BBS1 = $9F
+OPC_BBS2 = $AF
+OPC_BBS3 = $BF
+OPC_BBS4 = $CF
+OPC_BBS5 = $DF
+OPC_BBS6 = $EF
+OPC_BBS7 = $FF
+
+.else
+
+; no bit instructions for 65SC02
+
+; OPC_NOP = $07 ; doublet
+; OPC_NOP = $17 ; doublet
+; OPC_NOP = $27 ; doublet
+; OPC_NOP = $37 ; doublet
+; OPC_NOP = $47 ; doublet
+; OPC_NOP = $57 ; doublet
+; OPC_NOP = $67 ; doublet
+; OPC_NOP = $77 ; doublet
+; OPC_NOP = $87 ; doublet
+; OPC_NOP = $97 ; doublet
+; OPC_NOP = $A7 ; doublet
+; OPC_NOP = $B7 ; doublet
+; OPC_NOP = $C7 ; doublet
+; OPC_NOP = $D7 ; doublet
+; OPC_NOP = $E7 ; doublet
+; OPC_NOP = $F7 ; doublet
+; OPC_NOP = $0F ; doublet
+; OPC_NOP = $1F ; doublet
+; OPC_NOP = $2F ; doublet
+; OPC_NOP = $3F ; doublet
+; OPC_NOP = $4F ; doublet
+; OPC_NOP = $5F ; doublet
+; OPC_NOP = $6F ; doublet
+; OPC_NOP = $7F ; doublet
+; OPC_NOP = $8F ; doublet
+; OPC_NOP = $9F ; doublet
+; OPC_NOP = $AF ; doublet
+; OPC_NOP = $BF ; doublet
+; OPC_NOP = $CF ; doublet
+; OPC_NOP = $DF ; doublet
+; OPC_NOP = $EF ; doublet
+; OPC_NOP = $FF ; doublet
+
+.endif
+
+.elseif (.cpu .bitand ::CPU_ISET_6502X)
+
+; stable, undocumented opcodes
+
+; OPC_KIL = $02 ; unstable
+OPC_SLO_izx = $03
+OPC_NOP_zp = $04
+OPC_SLO_zp = $07
+OPC_ANC_imm = $0B
+OPC_NOP_abs = $0C
+OPC_SLO_abs = $0F
+
+; OPC_KIL = $12 ; unstable
+OPC_SLO_izy = $13
+OPC_NOP_zpx = $14
+OPC_SLO_zpx = $17
+;OPC_NOP = $1A
+OPC_SLO_aby = $1B
+OPC_NOP_abx = $1C
+OPC_SLO_abx = $1F
+
+; OPC_KIL = $22 ; unstable
+OPC_RLA_izx = $23
+OPC_RLA_zp = $27
+OPC_ANC_imm = $2B
+OPC_RLA_abs = $2F
+
+; OPC_KIL = $32 ; unstable
+OPC_RLA_izy = $33
+OPC_NOP_zpx = $34
+OPC_RLA_zpx = $37
+; OPC_NOP = $3A ; doublet
+OPC_RLA_aby = $3B
+OPC_NOP_abx = $3C
+OPC_RLA_abx = $3F
+
+; OPC_KIL = $42 ; unstable
+OPC_SRE_izx = $43
+OPC_NOP_zp = $44
+OPC_SRE_zp = $47
+OPC_ALR_imm = $4B
+OPC_SRE_abs = $4F
+
+; OPC_KIL = $52 ; unstable
+OPC_SRE_izy = $53
+OPC_NOP_zpx = $54
+OPC_SRE_zpx = $57
+; OPC_NOP = $5A ; doublet
+OPC_SRE_aby = $5B
+OPC_NOP_abx = $5C
+OPC_SRE_abx = $5F
+
+; OPC_KIL = $62
+OPC_RRA_izx = $63
+OPC_NOP_zp = $64
+OPC_RRA_zp = $67
+OPC_ARR_imm = $6B
+OPC_RRA_abs = $6F
+
+; OPC_KIL = $72
+OPC_RRA_izy = $73
+OPC_NOP_zpx = $74
+OPC_RRA_zpx = $77
+; OPC_NOP = $7A ; doublet
+OPC_RRA_aby = $7B
+OPC_NOP_abx = $7C
+OPC_RRA_abx = $7F
+
+OPC_NOP_imm = $80
+; OPC_NOP_imm = $82 ; doublet
+OPC_SAX_izx = $83
+OPC_SAX_zp = $87
+; OPC_NOP_imm = $89 ; doublet
+; OPC_XAA = $8B ; unstable
+OPC_SAX_abs = $8F
+
+; OPC_KIL = $92 ; unstable
+; OPC_AHX_izy = $93 ; unstable
+OPC_SAX_zpy = $97
+; OPC_TAS_aby = $9B ; unstable
+; OPC_SHY_abx = $9C ; unstable
+; OPC_SHX_aby = $9E ; unstable
+; OPC_AHX_aby = $9F ; unstable
+
+OPC_LAX_izx = $A3
+OPC_LAX_zp = $A7
+; OPC_LAX_imm = $AB ; unstable
+OPC_LAX_abs = $AF
+
+; OPC_KIL = $B2 ; unstable
+OPC_LAX_izy = $B3
+OPC_LAX_zpy = $B7
+OPC_LAS_aby = $BB
+OPC_LAX_aby = $BF
+
+; OPC_NOP_imm = $C2 ; doublet
+OPC_DCP_izx = $C3
+OPC_DCP_zp = $C7
+OPC_AXS_imm = $CB
+OPC_DCP_abs = $CF
+
+; OPC_KIL = $D2 ; unstable
+OPC_DCP_izy = $D3
+OPC_NOP_zpx = $D4
+OPC_DCP_zpx = $D7
+OPC_NOP_DA = $DA
+OPC_DCP_aby = $DB
+OPC_NOP_abx = $DC
+OPC_DCP_abx = $DF
+
+; OPC_NOP_imm = $E2 ; doublet
+OPC_ISC_izx = $E3
+OPC_ISC_zp = $E7
+; OPC_SBC_imm = $EB ; doublet
+OPC_ISC_abs = $EF
+
+; OPC_KIL = $F2 ; unstable
+OPC_ISC_izy = $F3
+OPC_NOP_zpx = $F4
+OPC_ISC_zpx = $F7
+OPC_NOP_FA = $FA
+OPC_ISC_aby = $FB
+OPC_NOP_abx = $FC
+OPC_ISC_abx = $FF
+
+.endif
-; smc.mac\r
-; ca65 Macro-Pack for Self Modifying Code (SMC)\r
-;\r
-; (c) Christian Krüger, latest change: 17-Jul-2016\r
-;\r
-; This software is provided 'as-is', without any expressed or implied\r
-; warranty. In no event will the authors be held liable for any damages\r
-; arising from the use of this software.\r
-;\r
-; Permission is granted to anyone to use this software for any purpose,\r
-; including commercial applications, and to alter it and redistribute it\r
-; freely, subject to the following restrictions:\r
-;\r
-; 1. The origin of this software must not be misrepresented; you must not\r
-; claim that you wrote the original software. If you use this software\r
-; in a product, an acknowledgment in the product documentation would be\r
-; appreciated but is not required.\r
-; 2. Altered source versions must be plainly marked as such, and must not\r
-; be misrepresented as being the original software.\r
-; 3. This notice may not be removed or altered from any source\r
-; distribution.\r
-;\r
-\r
-.define _SMCDesignator .mid(0, .tcount(label) - 1, label) .ident(.concat(.string(.right(1, label)), "_SMC"))\r
-.define _SMCAlias .mid(0, .tcount(alias) - 1, alias) .ident(.concat(.string(.right(1, alias)), "_SMC"))\r
-.define SMC_AbsAdr $FADE\r
-.define SMC_ZpAdr $00\r
-.define SMC_Opcode nop\r
-.define SMC_Value $42\r
-\r
-.macro SMC_OperateOnValue opcode, label\r
- opcode _SMCDesignator+1\r
-.endmacro\r
-\r
-.macro SMC_OperateOnLowByte opcode, label\r
- SMC_OperateOnValue opcode, label\r
-.endmacro\r
-\r
-.macro SMC_OperateOnHighByte opcode, label\r
- opcode _SMCDesignator + 2\r
-.endmacro\r
-\r
-.macro SMC_Import alias\r
-.import _SMCAlias\r
-.endmacro\r
-\r
-.macro SMC_Export alias, label\r
-.export _SMCAlias := _SMCDesignator\r
-.endmacro\r
-\r
-.macro SMC label, statement\r
-_SMCDesignator: statement\r
-.endmacro\r
-\r
-.macro SMC_TransferOpcode label, opcode, register\r
-.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )\r
- lda #opcode\r
- sta _SMCDesignator\r
-.elseif .match ({register}, x)\r
- ldx #opcode\r
- stx _SMCDesignator\r
-.elseif .match ({register}, y)\r
- ldy #opcode\r
- sty _SMCDesignator\r
-.else\r
- .error "Invalid usage of macro 'SMC_TransferOpcode'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_LoadOpcode label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- lda _SMCDesignator\r
-.elseif .match ({register}, x)\r
- ldx _SMCDesignator\r
-.elseif .match ({register}, y)\r
- ldy _SMCDesignator\r
-.else\r
- .error "Invalid usage of macro 'SMC_LoadOpcode'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_StoreOpcode label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- sta _SMCDesignator\r
-.elseif .match ({register}, x)\r
- stx _SMCDesignator\r
-.elseif .match ({register}, y)\r
- sty _SMCDesignator\r
-.else\r
- .error "Invalid usage of macro 'SMC_StoreOpcode'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_ChangeBranch label, destination, register\r
-.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )\r
- lda #(<(destination - _SMCDesignator -2))\r
- sta _SMCDesignator+1\r
-.elseif .match ({register}, x)\r
- ldx #(<(destination - _SMCDesignator - 2))\r
- stx _SMCDesignator+1\r
-.elseif .match ({register}, y)\r
- ldy #(<(destination - _SMCDesignator - 2))\r
- sty _SMCDesignator+1\r
-.else\r
- .error "Invalid usage of macro 'SMC_ChangeBranch'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_TransferValue label, value, register\r
-.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )\r
- lda value\r
- sta _SMCDesignator+1\r
-.elseif .match ({register}, x)\r
- ldx value\r
- stx _SMCDesignator+1\r
-.elseif .match ({register}, y)\r
- ldy value\r
- sty _SMCDesignator+1\r
-.else\r
- .error "Invalid usage of macro 'SMC_TransferValue'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_LoadValue label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- lda _SMCDesignator+1\r
-.elseif .match ({register}, x)\r
- ldx _SMCDesignator+1\r
-.elseif .match ({register}, y)\r
- ldy _SMCDesignator+1\r
-.else\r
- .error "Invalid usage of macro 'SMC_LoadValue'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_StoreValue label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- sta _SMCDesignator+1\r
-.elseif .match ({register}, x)\r
- stx _SMCDesignator+1\r
-.elseif .match ({register}, y)\r
- sty _SMCDesignator+1\r
-.else\r
- .error "Invalid usage of macro 'SMC_StoreValue'"\r
-.endif\r
-.endmacro\r
-\r
-\r
-.macro SMC_TransferLowByte label, value, register\r
-SMC_TransferValue label, value, register\r
-.endmacro\r
-\r
-.macro SMC_LoadLowByte label, register\r
-SMC_LoadValue label, register\r
-.endmacro\r
-\r
-.macro SMC_StoreLowByte label, register\r
-SMC_StoreValue label, register\r
-.endmacro\r
-\r
-.macro SMC_TransferHighByte label, value, register\r
-.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )\r
- lda value\r
- sta _SMCDesignator+2\r
-.elseif .match ({register}, x)\r
- ldx value\r
- stx _SMCDesignator+2\r
-.elseif .match ({register}, y)\r
- ldy value\r
- sty _SMCDesignator+2\r
-.else\r
- .error "Invalid usage of macro 'SMC_TransferHighByte'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_LoadHighByte label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- lda _SMCDesignator+2\r
-.elseif .match ({register}, x)\r
- ldx _SMCDesignator+2\r
-.elseif .match ({register}, y)\r
- ldy _SMCDesignator+2\r
-.else\r
- .error "Invalid usage of macro 'SMC_LoadHighByte'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_StoreHighByte label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- sta _SMCDesignator+2\r
-.elseif .match ({register}, x)\r
- stx _SMCDesignator+2\r
-.elseif .match ({register}, y)\r
- sty _SMCDesignator+2\r
-.else\r
- .error "Invalid usage of macro 'SMC_StoreHighByte'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_TransferAddressSingle label, address, register\r
-.if .paramcount = 2 .or .match ((register), a) .or .match ({register}, )\r
- .if (.match (.left (1, {address}), #))\r
- ; immediate mode\r
- lda #<(.right (.tcount ({address})-1, {address}))\r
- sta _SMCDesignator+1\r
- lda #>(.right (.tcount ({address})-1, {address}))\r
- sta _SMCDesignator+2\r
- .else\r
- ; assume absolute or zero page\r
- lda address\r
- sta _SMCDesignator+1\r
- lda 1+(address)\r
- sta _SMCDesignator+2\r
- .endif\r
-.elseif .match ((register), x)\r
- .if (.match (.left (1, {address}), #))\r
- ; immediate mode\r
- ldx #<(.right (.tcount ({address})-1, {address}))\r
- stx _SMCDesignator+1\r
- ldx #>(.right (.tcount ({address})-1, {address}))\r
- stx _SMCDesignator+2\r
- .else\r
- ; assume absolute or zero page\r
- ldx address\r
- stx _SMCDesignator+1\r
- ldx 1+(address)\r
- stx _SMCDesignator+2\r
- .endif\r
-.elseif .match ((register), y)\r
- .if (.match (.left (1, {address}), #))\r
- ; immediate mode\r
- ldy #<(.right (.tcount ({address})-1, {address}))\r
- sty _SMCDesignator+1\r
- ldy #>(.right (.tcount ({address})-1, {address}))\r
- sty _SMCDesignator+2\r
- .else\r
- ; assume absolute or zero page\r
- ldy address\r
- sty _SMCDesignator+1\r
- ldy 1+(address)\r
- sty _SMCDesignator+2\r
- .endif\r
-.else\r
- .error "Invalid usage of macro 'SMC_TransferAddressSingle'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_TransferAddress label, address\r
-.if (.match (.left (1, {address}), #))\r
- ; immediate mode\r
- lda #<(.right (.tcount ({address})-1, {address}))\r
- sta _SMCDesignator+1\r
- ldx #>(.right (.tcount ({address})-1, {address}))\r
- stx _SMCDesignator+2\r
-.else\r
- ; assume absolute or zero page\r
- lda {address}\r
- sta _SMCDesignator+1\r
- ldx 1+{address}\r
- stx _SMCDesignator)+2\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_StoreAddress label\r
- sta _SMCDesignator+1\r
- stx _SMCDesignator+2\r
-.endmacro\r
+; smc.mac
+; ca65 Macro-Pack for Self Modifying Code (SMC)
+;
+; (c) Christian Krüger, latest change: 17-Jul-2016
+;
+; This software is provided 'as-is', without any expressed or implied
+; warranty. In no event will the authors be held liable for any damages
+; arising from the use of this software.
+;
+; Permission is granted to anyone to use this software for any purpose,
+; including commercial applications, and to alter it and redistribute it
+; freely, subject to the following restrictions:
+;
+; 1. The origin of this software must not be misrepresented; you must not
+; claim that you wrote the original software. If you use this software
+; in a product, an acknowledgment in the product documentation would be
+; appreciated but is not required.
+; 2. Altered source versions must be plainly marked as such, and must not
+; be misrepresented as being the original software.
+; 3. This notice may not be removed or altered from any source
+; distribution.
+;
+
+.define _SMCDesignator .mid(0, .tcount(label) - 1, label) .ident(.concat(.string(.right(1, label)), "_SMC"))
+.define _SMCAlias .mid(0, .tcount(alias) - 1, alias) .ident(.concat(.string(.right(1, alias)), "_SMC"))
+.define SMC_AbsAdr $FADE
+.define SMC_ZpAdr $00
+.define SMC_Opcode nop
+.define SMC_Value $42
+
+.macro SMC_OperateOnValue opcode, label
+ opcode _SMCDesignator+1
+.endmacro
+
+.macro SMC_OperateOnLowByte opcode, label
+ SMC_OperateOnValue opcode, label
+.endmacro
+
+.macro SMC_OperateOnHighByte opcode, label
+ opcode _SMCDesignator + 2
+.endmacro
+
+.macro SMC_Import alias
+.import _SMCAlias
+.endmacro
+
+.macro SMC_Export alias, label
+.export _SMCAlias := _SMCDesignator
+.endmacro
+
+.macro SMC label, statement
+_SMCDesignator: statement
+.endmacro
+
+.macro SMC_TransferOpcode label, opcode, register
+.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
+ lda #opcode
+ sta _SMCDesignator
+.elseif .match ({register}, x)
+ ldx #opcode
+ stx _SMCDesignator
+.elseif .match ({register}, y)
+ ldy #opcode
+ sty _SMCDesignator
+.else
+ .error "Invalid usage of macro 'SMC_TransferOpcode'"
+.endif
+.endmacro
+
+.macro SMC_LoadOpcode label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ lda _SMCDesignator
+.elseif .match ({register}, x)
+ ldx _SMCDesignator
+.elseif .match ({register}, y)
+ ldy _SMCDesignator
+.else
+ .error "Invalid usage of macro 'SMC_LoadOpcode'"
+.endif
+.endmacro
+
+.macro SMC_StoreOpcode label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ sta _SMCDesignator
+.elseif .match ({register}, x)
+ stx _SMCDesignator
+.elseif .match ({register}, y)
+ sty _SMCDesignator
+.else
+ .error "Invalid usage of macro 'SMC_StoreOpcode'"
+.endif
+.endmacro
+
+.macro SMC_ChangeBranch label, destination, register
+.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
+ lda #(<(destination - _SMCDesignator -2))
+ sta _SMCDesignator+1
+.elseif .match ({register}, x)
+ ldx #(<(destination - _SMCDesignator - 2))
+ stx _SMCDesignator+1
+.elseif .match ({register}, y)
+ ldy #(<(destination - _SMCDesignator - 2))
+ sty _SMCDesignator+1
+.else
+ .error "Invalid usage of macro 'SMC_ChangeBranch'"
+.endif
+.endmacro
+
+.macro SMC_TransferValue label, value, register
+.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
+ lda value
+ sta _SMCDesignator+1
+.elseif .match ({register}, x)
+ ldx value
+ stx _SMCDesignator+1
+.elseif .match ({register}, y)
+ ldy value
+ sty _SMCDesignator+1
+.else
+ .error "Invalid usage of macro 'SMC_TransferValue'"
+.endif
+.endmacro
+
+.macro SMC_LoadValue label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ lda _SMCDesignator+1
+.elseif .match ({register}, x)
+ ldx _SMCDesignator+1
+.elseif .match ({register}, y)
+ ldy _SMCDesignator+1
+.else
+ .error "Invalid usage of macro 'SMC_LoadValue'"
+.endif
+.endmacro
+
+.macro SMC_StoreValue label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ sta _SMCDesignator+1
+.elseif .match ({register}, x)
+ stx _SMCDesignator+1
+.elseif .match ({register}, y)
+ sty _SMCDesignator+1
+.else
+ .error "Invalid usage of macro 'SMC_StoreValue'"
+.endif
+.endmacro
+
+
+.macro SMC_TransferLowByte label, value, register
+SMC_TransferValue label, value, register
+.endmacro
+
+.macro SMC_LoadLowByte label, register
+SMC_LoadValue label, register
+.endmacro
+
+.macro SMC_StoreLowByte label, register
+SMC_StoreValue label, register
+.endmacro
+
+.macro SMC_TransferHighByte label, value, register
+.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
+ lda value
+ sta _SMCDesignator+2
+.elseif .match ({register}, x)
+ ldx value
+ stx _SMCDesignator+2
+.elseif .match ({register}, y)
+ ldy value
+ sty _SMCDesignator+2
+.else
+ .error "Invalid usage of macro 'SMC_TransferHighByte'"
+.endif
+.endmacro
+
+.macro SMC_LoadHighByte label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ lda _SMCDesignator+2
+.elseif .match ({register}, x)
+ ldx _SMCDesignator+2
+.elseif .match ({register}, y)
+ ldy _SMCDesignator+2
+.else
+ .error "Invalid usage of macro 'SMC_LoadHighByte'"
+.endif
+.endmacro
+
+.macro SMC_StoreHighByte label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ sta _SMCDesignator+2
+.elseif .match ({register}, x)
+ stx _SMCDesignator+2
+.elseif .match ({register}, y)
+ sty _SMCDesignator+2
+.else
+ .error "Invalid usage of macro 'SMC_StoreHighByte'"
+.endif
+.endmacro
+
+.macro SMC_TransferAddressSingle label, address, register
+.if .paramcount = 2 .or .match ((register), a) .or .match ({register}, )
+ .if (.match (.left (1, {address}), #))
+ ; immediate mode
+ lda #<(.right (.tcount ({address})-1, {address}))
+ sta _SMCDesignator+1
+ lda #>(.right (.tcount ({address})-1, {address}))
+ sta _SMCDesignator+2
+ .else
+ ; assume absolute or zero page
+ lda address
+ sta _SMCDesignator+1
+ lda 1+(address)
+ sta _SMCDesignator+2
+ .endif
+.elseif .match ((register), x)
+ .if (.match (.left (1, {address}), #))
+ ; immediate mode
+ ldx #<(.right (.tcount ({address})-1, {address}))
+ stx _SMCDesignator+1
+ ldx #>(.right (.tcount ({address})-1, {address}))
+ stx _SMCDesignator+2
+ .else
+ ; assume absolute or zero page
+ ldx address
+ stx _SMCDesignator+1
+ ldx 1+(address)
+ stx _SMCDesignator+2
+ .endif
+.elseif .match ((register), y)
+ .if (.match (.left (1, {address}), #))
+ ; immediate mode
+ ldy #<(.right (.tcount ({address})-1, {address}))
+ sty _SMCDesignator+1
+ ldy #>(.right (.tcount ({address})-1, {address}))
+ sty _SMCDesignator+2
+ .else
+ ; assume absolute or zero page
+ ldy address
+ sty _SMCDesignator+1
+ ldy 1+(address)
+ sty _SMCDesignator+2
+ .endif
+.else
+ .error "Invalid usage of macro 'SMC_TransferAddressSingle'"
+.endif
+.endmacro
+
+.macro SMC_TransferAddress label, address
+.if (.match (.left (1, {address}), #))
+ ; immediate mode
+ lda #<(.right (.tcount ({address})-1, {address}))
+ sta _SMCDesignator+1
+ ldx #>(.right (.tcount ({address})-1, {address}))
+ stx _SMCDesignator+2
+.else
+ ; assume absolute or zero page
+ lda {address}
+ sta _SMCDesignator+1
+ ldx 1+{address}
+ stx _SMCDesignator)+2
+.endif
+.endmacro
+
+.macro SMC_StoreAddress label
+ sta _SMCDesignator+1
+ stx _SMCDesignator+2
+.endmacro
-/*****************************************************************************/\r
-/* */\r
-/* osic1p.h */\r
-/* */\r
-/* Challenger 1P system specific definitions */\r
-/* */\r
-/* */\r
-/* */\r
-/* (C) 2015 Stephan Muehlstrasser */\r
-/* */\r
-/* */\r
-/* This software is provided 'as-is', without any expressed or implied */\r
-/* warranty. In no event will the authors be held liable for any damages */\r
-/* arising from the use of this software. */\r
-/* */\r
-/* Permission is granted to anyone to use this software for any purpose, */\r
-/* including commercial applications, and to alter it and redistribute it */\r
-/* freely, subject to the following restrictions: */\r
-/* */\r
-/* 1. The origin of this software must not be misrepresented; you must not */\r
-/* claim that you wrote the original software. If you use this software */\r
-/* in a product, an acknowledgment in the product documentation would be */\r
-/* appreciated but is not required. */\r
-/* 2. Altered source versions must be plainly marked as such, and must not */\r
-/* be misrepresented as being the original software. */\r
-/* 3. This notice may not be removed or altered from any source */\r
-/* distribution. */\r
-/* */\r
-/*****************************************************************************/\r
-\r
-#ifndef _OSIC1P_H\r
-#define _OSIC1P_H\r
-\r
-/* Check for errors */\r
-#if !defined(__OSIC1P__)\r
-# error "This module may only be used when compiling for the Challenger 1P!"\r
-#endif\r
-\r
-/* The following #defines will cause the matching functions calls in conio.h\r
-** to be overlaid by macros with the same names, saving the function call\r
-** overhead.\r
-*/\r
-#define _textcolor(color) COLOR_WHITE\r
-#define _bgcolor(color) COLOR_BLACK\r
-#define _bordercolor(color) COLOR_BLACK\r
-\r
-#endif\r
+/*****************************************************************************/
+/* */
+/* osic1p.h */
+/* */
+/* Challenger 1P system specific definitions */
+/* */
+/* */
+/* */
+/* (C) 2015 Stephan Muehlstrasser */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+#ifndef _OSIC1P_H
+#define _OSIC1P_H
+
+/* Check for errors */
+#if !defined(__OSIC1P__)
+# error "This module may only be used when compiling for the Challenger 1P!"
+#endif
+
+/* The following #defines will cause the matching functions calls in conio.h
+** to be overlaid by macros with the same names, saving the function call
+** overhead.
+*/
+#define _textcolor(color) COLOR_WHITE
+#define _bgcolor(color) COLOR_BLACK
+#define _bordercolor(color) COLOR_BLACK
+
+#endif
-/*****************************************************************************/\r
-/* */\r
-/* zlib.h */\r
-/* */\r
-/* Decompression routines for the 'deflate' format */\r
-/* */\r
-/* */\r
-/* */\r
-/* (C) 2000-2015 Piotr Fusik <fox@scene.pl> */\r
-/* */\r
-/* This file is based on the zlib.h from 'zlib' general purpose compression */\r
-/* library, version 1.1.3, (C) 1995-1998 Jean-loup Gailly and Mark Adler. */\r
-/* */\r
-/* Jean-loup Gailly Mark Adler */\r
-/* jloup@gzip.org madler@alumni.caltech.edu */\r
-/* */\r
-/* This software is provided 'as-is', without any expressed or implied */\r
-/* warranty. In no event will the authors be held liable for any damages */\r
-/* arising from the use of this software. */\r
-/* */\r
-/* Permission is granted to anyone to use this software for any purpose, */\r
-/* including commercial applications, and to alter it and redistribute it */\r
-/* freely, subject to the following restrictions: */\r
-/* */\r
-/* 1. The origin of this software must not be misrepresented; you must not */\r
-/* claim that you wrote the original software. If you use this software */\r
-/* in a product, an acknowledgment in the product documentation would be */\r
-/* appreciated but is not required. */\r
-/* 2. Altered source versions must be plainly marked as such, and must not */\r
-/* be misrepresented as being the original software. */\r
-/* 3. This notice may not be removed or altered from any source */\r
-/* distribution. */\r
-/* */\r
-/*****************************************************************************/\r
-\r
-\r
-\r
-#ifndef _ZLIB_H\r
-#define _ZLIB_H\r
-\r
-#define Z_OK 0\r
-#define Z_DATA_ERROR (-3)\r
-/* Return codes for uncompress() */\r
-\r
-#define Z_DEFLATED 8\r
-/* The deflate compression method (the only one supported) */\r
-\r
-#define Z_NULL 0\r
-\r
-\r
-unsigned __fastcall__ inflatemem (char* dest, const char* source);\r
-/*\r
- Decompresses the source buffer into the destination buffer.\r
- Returns the size of the uncompressed data (number of bytes written starting\r
- from dest).\r
-\r
- This function expects data in the DEFLATE format, described in RFC\r
- (Request for Comments) 1951 in the file\r
- ftp://ds.internic.net/rfc/rfc1951.txt.\r
-\r
- This function does not exist in the original zlib. Its implementation\r
- using original zlib might be following:\r
-\r
- unsigned inflatemem (char* dest, const char* source)\r
- {\r
- z_stream stream;\r
-\r
- stream.next_in = (Bytef*) source;\r
- stream.avail_in = 65535;\r
-\r
- stream.next_out = dest;\r
- stream.avail_out = 65535;\r
-\r
- stream.zalloc = (alloc_func) 0;\r
- stream.zfree = (free_func) 0;\r
-\r
- inflateInit2(&stream, -MAX_WBITS);\r
- inflate(&stream, Z_FINISH);\r
- inflateEnd(&stream);\r
-\r
- return stream.total_out;\r
- }\r
-*/\r
-\r
-\r
-int __fastcall__ uncompress (char* dest, unsigned* destLen,\r
- const char* source, unsigned sourceLen);\r
-/*\r
- Original zlib description:\r
-\r
- Decompresses the source buffer into the destination buffer. sourceLen is\r
- the byte length of the source buffer. Upon entry, destLen is the total\r
- size of the destination buffer, which must be large enough to hold the\r
- entire uncompressed data. (The size of the uncompressed data must have\r
- been saved previously by the compressor and transmitted to the decompressor\r
- by some mechanism outside the scope of this compression library.)\r
- Upon exit, destLen is the actual size of the compressed buffer.\r
- This function can be used to decompress a whole file at once if the\r
- input file is mmap'ed.\r
-\r
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not\r
- enough memory, Z_BUF_ERROR if there was not enough room in the output\r
- buffer, or Z_DATA_ERROR if the input data was corrupted.\r
-\r
- Implementation notes:\r
-\r
- This function expects data in the ZLIB format, described in RFC 1950\r
- in the file ftp://ds.internic.net/rfc/rfc1950.txt. The ZLIB format is\r
- essentially the DEFLATE format plus a very small header and Adler-32\r
- checksum.\r
-\r
- Z_MEM_ERROR and Z_BUF_ERROR are never returned in this implementation.\r
-*/\r
-\r
-\r
-unsigned long __fastcall__ adler32 (unsigned long adler, const char* buf,\r
- unsigned len);\r
-\r
-/*\r
- Original zlib description:\r
-\r
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and\r
- return the updated checksum. If buf is NULL, this function returns\r
- the required initial value for the checksum.\r
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed\r
- much faster. Usage example:\r
-\r
- unsigned long adler = adler32(0L, Z_NULL, 0);\r
-\r
- while (read_buffer(buffer, length) != EOF) {\r
- adler = adler32(adler, buffer, length);\r
- }\r
- if (adler != original_adler) error();\r
-\r
- Implementation notes:\r
-\r
- This function isn't actually much faster than crc32(), but it is smaller\r
- and does not use any lookup tables.\r
-*/\r
-\r
-\r
-unsigned long __fastcall__ crc32 (unsigned long crc, const char* buf,\r
- unsigned len);\r
-/*\r
- Original zlib description:\r
-\r
- Update a running crc with the bytes buf[0..len-1] and return the updated\r
- crc. If buf is NULL, this function returns the required initial value\r
- for the crc. Pre- and post-conditioning (one's complement) is performed\r
- within this function so it shouldn't be done by the application.\r
- Usage example:\r
-\r
- unsigned long crc = crc32(0L, Z_NULL, 0);\r
-\r
- while (read_buffer(buffer, length) != EOF) {\r
- crc = crc32(crc, buffer, length);\r
- }\r
- if (crc != original_crc) error();\r
-\r
- Implementation notes:\r
-\r
- This function uses statically allocated 1 KB lookup table. The table is\r
- initialised before it is used for the first time (that is, if buffer is\r
- NULL or length is zero, then the lookup table isn't initialised).\r
-*/\r
-\r
-\r
-/* end of zlib.h */\r
-#endif\r
-\r
-\r
-\r
+/*****************************************************************************/
+/* */
+/* zlib.h */
+/* */
+/* Decompression routines for the 'deflate' format */
+/* */
+/* */
+/* */
+/* (C) 2000-2015 Piotr Fusik <fox@scene.pl> */
+/* */
+/* This file is based on the zlib.h from 'zlib' general purpose compression */
+/* library, version 1.1.3, (C) 1995-1998 Jean-loup Gailly and Mark Adler. */
+/* */
+/* Jean-loup Gailly Mark Adler */
+/* jloup@gzip.org madler@alumni.caltech.edu */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#define Z_OK 0
+#define Z_DATA_ERROR (-3)
+/* Return codes for uncompress() */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported) */
+
+#define Z_NULL 0
+
+
+unsigned __fastcall__ inflatemem (char* dest, const char* source);
+/*
+ Decompresses the source buffer into the destination buffer.
+ Returns the size of the uncompressed data (number of bytes written starting
+ from dest).
+
+ This function expects data in the DEFLATE format, described in RFC
+ (Request for Comments) 1951 in the file
+ ftp://ds.internic.net/rfc/rfc1951.txt.
+
+ This function does not exist in the original zlib. Its implementation
+ using original zlib might be following:
+
+ unsigned inflatemem (char* dest, const char* source)
+ {
+ z_stream stream;
+
+ stream.next_in = (Bytef*) source;
+ stream.avail_in = 65535;
+
+ stream.next_out = dest;
+ stream.avail_out = 65535;
+
+ stream.zalloc = (alloc_func) 0;
+ stream.zfree = (free_func) 0;
+
+ inflateInit2(&stream, -MAX_WBITS);
+ inflate(&stream, Z_FINISH);
+ inflateEnd(&stream);
+
+ return stream.total_out;
+ }
+*/
+
+
+int __fastcall__ uncompress (char* dest, unsigned* destLen,
+ const char* source, unsigned sourceLen);
+/*
+ Original zlib description:
+
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
+
+ Implementation notes:
+
+ This function expects data in the ZLIB format, described in RFC 1950
+ in the file ftp://ds.internic.net/rfc/rfc1950.txt. The ZLIB format is
+ essentially the DEFLATE format plus a very small header and Adler-32
+ checksum.
+
+ Z_MEM_ERROR and Z_BUF_ERROR are never returned in this implementation.
+*/
+
+
+unsigned long __fastcall__ adler32 (unsigned long adler, const char* buf,
+ unsigned len);
+
+/*
+ Original zlib description:
+
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is NULL, this function returns
+ the required initial value for the checksum.
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster. Usage example:
+
+ unsigned long adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+
+ Implementation notes:
+
+ This function isn't actually much faster than crc32(), but it is smaller
+ and does not use any lookup tables.
+*/
+
+
+unsigned long __fastcall__ crc32 (unsigned long crc, const char* buf,
+ unsigned len);
+/*
+ Original zlib description:
+
+ Update a running crc with the bytes buf[0..len-1] and return the updated
+ crc. If buf is NULL, this function returns the required initial value
+ for the crc. Pre- and post-conditioning (one's complement) is performed
+ within this function so it shouldn't be done by the application.
+ Usage example:
+
+ unsigned long crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+
+ Implementation notes:
+
+ This function uses statically allocated 1 KB lookup table. The table is
+ initialised before it is used for the first time (that is, if buffer is
+ NULL or length is zero, then the lookup table isn't initialised).
+*/
+
+
+/* end of zlib.h */
+#endif
+
+
+
-;\r
-; Extended memory driver for 65816 based extra RAM. Driver works without\r
-; problems when statically linked.\r
-;\r
-; Marco van den Heuvel, 2015-12-01\r
-;\r
-\r
- .include "zeropage.inc"\r
-\r
- .include "em-kernel.inc"\r
- .include "em-error.inc"\r
-\r
-\r
- .macpack generic\r
- .macpack module\r
-\r
-\r
-; ------------------------------------------------------------------------\r
-; Header. Includes jump table\r
-\r
- module_header _c64_65816_emd\r
-\r
-; Driver signature\r
-\r
- .byte $65, $6d, $64 ; "emd"\r
- .byte EMD_API_VERSION ; EM API version number\r
-\r
-; Library reference\r
-\r
- .addr $0000\r
-\r
-; Jump table\r
-\r
- .addr INSTALL\r
- .addr UNINSTALL\r
- .addr PAGECOUNT\r
- .addr MAP\r
- .addr USE\r
- .addr COMMIT\r
- .addr COPYFROM\r
- .addr COPYTO\r
-\r
-; ------------------------------------------------------------------------\r
-; Data.\r
-\r
-.bss\r
-isnotscpu: .res 1 ; SuperCPU not present\r
-curpage: .res 1 ; Current page number\r
-curbank: .res 1 ; Current bank number (+1)\r
-bankcount: .res 1 ; Number of available banks (pages = banks * 256)\r
-window: .res 256 ; Memory "window"\r
-\r
-.code\r
-\r
-; ------------------------------------------------------------------------\r
-; INSTALL routine. Is called after the driver is loaded into memory. If\r
-; possible, check if the hardware is present and determine the amount of\r
-; memory available.\r
-; Must return an EM_ERR_xx code in a/x.\r
-;\r
-\r
-INSTALL:\r
- sei\r
- clc\r
- sed\r
- lda #$99\r
- adc #$01 ; on 65C02, 65SC02, 65CE02, 65802 and 65816 sets the zero flag correctly\r
- cld\r
- bne @not_present\r
- clc\r
-.P816\r
- sep #$01 ; nop #$01 on 65C02/65SC02 and lda ($01,s),y on 65CE02\r
-.P02\r
- bcc @not_present\r
- lda $d0bc\r
- and #$80\r
- sta isnotscpu\r
- lda $07e8\r
- pha ; save value incase it was used somewhere else\r
- ldx #$ff\r
-@fillloop: ; fill from top (bank 255) to bottom\r
- txa\r
- pha\r
-.P816\r
- plb ; pull dbr\r
-.P02\r
- stx $07e8\r
- dex\r
- cpx #$ff\r
- bne @fillloop\r
- inx\r
-@compareloop: ; check from bottom to top\r
- txa\r
- pha\r
-.P816\r
- plb\r
-.P02\r
- cmp $07e8\r
- bne @found_pages\r
-.P816\r
- inc\r
-.P02\r
- sta $07e8\r
- cmp $07e8\r
- bne @found_pages\r
- inx\r
- bne @compareloop\r
-@found_pages:\r
- dex\r
- lda #$00\r
- pha\r
-.P816\r
- plb\r
-.P02\r
- pla\r
- sta $07e8\r
- cli\r
- lda isnotscpu\r
- bne @noextradex\r
- dex\r
-@noextradex:\r
- stx bankcount\r
- lda #<EM_ERR_OK\r
- ldx #>EM_ERR_OK\r
- rts\r
-@not_present:\r
- cli\r
- lda #<EM_ERR_NO_DEVICE\r
- ldx #>EM_ERR_NO_DEVICE\r
-; rts ; Run into UNINSTALL instead\r
-\r
-\r
-; ------------------------------------------------------------------------\r
-; UNINSTALL routine. Is called before the driver is removed from memory.\r
-; Can do cleanup or whatever. Must not return anything.\r
-;\r
-\r
-UNINSTALL:\r
- rts\r
-\r
-\r
-; ------------------------------------------------------------------------\r
-; PAGECOUNT: Return the total number of available pages in a/x.\r
-;\r
-\r
-PAGECOUNT:\r
- lda #$00 ; a whole bank is either usable or not\r
- ldx bankcount\r
- rts\r
-\r
-; ------------------------------------------------------------------------\r
-; MAP: Map the page in a/x into memory and return a pointer to the page in\r
-; a/x. The contents of the currently mapped page (if any) may be discarded\r
-; by the driver.\r
-;\r
-\r
-MAP: sta curpage ; Remember the new page\r
- stx curbank ; Remember the new bank\r
-\r
- sta ptr2+1 ; src address low\r
- lda #$00\r
- sta ptr2 ; src address high\r
- inx\r
- ldy isnotscpu ; check if not scpu\r
- bne @notscpu\r
- inx\r
-@notscpu:\r
- stx tmp2 ; src bank\r
-\r
- sta tmp1 ; dst bank\r
-\r
- sta ptr3+1 ; length high\r
- lda #$ff\r
- sta ptr3 ; length low\r
-\r
- lda #<window\r
- sta ptr1 ; dst address low\r
- ldx #>window\r
- stx ptr1+1 ; dst address high\r
-\r
- jsr transfer\r
-\r
- rts\r
-\r
-; ------------------------------------------------------------------------\r
-; USE: Tell the driver that the window is now associated with a given page.\r
-\r
-USE: sta curpage ; Remember the page\r
- stx curbank ; Remember the bank\r
- lda #<window\r
- ldx #>window ; Return the window\r
- rts\r
-\r
-; ------------------------------------------------------------------------\r
-; COMMIT: Commit changes in the memory window to extended storage.\r
-\r
-COMMIT: lda curpage ; Get the current page\r
- sta ptr1+1 ; dst high\r
- ldx #$00\r
- stx ptr1 ; dst low\r
-\r
- lda #<window\r
- sta ptr2 ; src low\r
- lda #>window\r
- sta ptr2+1 ; src high\r
-\r
- stx ptr3+1 ; length high\r
- lda #$ff\r
- sta ptr3 ; length low\r
-\r
- stx tmp2 ; src bank\r
- ldy curbank ; Get the current bank\r
- iny\r
- ldx isnotscpu\r
- bne @notascpu\r
- iny\r
-@notascpu:\r
- sty tmp1 ; dst bank\r
-\r
- jsr transfer\r
-\r
- rts\r
-\r
-; ------------------------------------------------------------------------\r
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure\r
-; describing the request is passed in a/x.\r
-; The function must not return anything.\r
-;\r
-\r
-COPYFROM:\r
- sta ptr4\r
- stx ptr4+1 ; Save the passed em_copy pointer\r
-\r
- ldy #EM_COPY::COUNT+1 ; start at the end of the struct\r
- lda (ptr4),y ; get high byte of count\r
- tax\r
- dey\r
- lda (ptr4),y ; get low byte of count\r
- bne @nodex\r
- dex\r
-@nodex:\r
-.P816\r
- dec\r
-.P02\r
- sta ptr3 ; length low\r
- stx ptr3+1 ; length high\r
- dey\r
- lda (ptr4),y ; get bank\r
-.P816\r
- inc\r
-.P02\r
- ldx isnotscpu\r
- bne @notscpu64\r
-.P816\r
- inc\r
-.P02\r
-@notscpu64:\r
- sta tmp2 ; src bank\r
- dey\r
- lda (ptr4),y ; get page\r
- sta ptr2+1 ; src high\r
- dey\r
- lda (ptr4),y ; get offset in page\r
- sta ptr2 ; src low\r
- dey\r
- lda (ptr4),y ; get memory buffer high\r
- sta ptr1+1 ; dst high\r
- dey\r
- lda (ptr4),y ; get memory buffer low\r
- sta ptr1 ; dst low\r
- lda #$00\r
- sta tmp1 ; dst bank\r
-\r
- jsr transfer\r
-\r
- rts\r
-\r
-; ------------------------------------------------------------------------\r
-; COPYTO: Copy from linear into extended memory. A pointer to a structure\r
-; describing the request is passed in a/x.\r
-; The function must not return anything.\r
-;\r
-\r
-COPYTO: sta ptr4\r
- stx ptr4+1 ; Save the passed em_copy pointer\r
-\r
- ldy #EM_COPY::COUNT+1 ; start at the end of the struct\r
- lda (ptr4),y ; get high byte of count\r
- tax\r
- dey\r
- lda (ptr4),y ; get low byte of count\r
- bne @nodex2\r
- dex\r
-@nodex2:\r
-.P816\r
- dec\r
-.P02\r
- sta ptr3 ; length low\r
- txa\r
- sta ptr3+1 ; length high\r
- dey\r
- lda (ptr4),y ; get bank\r
-.P816\r
- inc\r
-.P02\r
- ldx isnotscpu\r
- bne @notascpu64\r
-.P816\r
- inc\r
-.P02\r
-@notascpu64:\r
- sta tmp1 ; dst bank\r
- dey\r
- lda (ptr4),y ; get page\r
- sta ptr1+1 ; dst high\r
- dey\r
- lda (ptr4),y ; get page offset\r
- sta ptr1 ; dst low\r
- dey\r
- lda (ptr4),y ; get memory buffer high\r
- sta ptr2+1 ; src low\r
- dey\r
- lda (ptr4),y ; get memory buffer low\r
- sta ptr2 ; src high\r
- lda #$00\r
- sta tmp2 ; src bank\r
-\r
- jsr transfer\r
-\r
- rts\r
-\r
-; ------------------------------------------------------------------------\r
-; Helper function for moving a block, the following is used:\r
-; ptr1: dst\r
-; ptr2: src\r
-; ptr3: length\r
-; tmp1: dst bank\r
-; tmp2: src bank\r
-\r
-transfer:\r
-.P816\r
-.A8\r
-.I8\r
- sei\r
- pha\r
- phx\r
- phy\r
- ldx tmp1 ; load srcbank\r
- stx @move+1 ; store srcbank in move + 1\r
- ldy tmp2 ; load dstbank\r
- sty @move+2 ; store dstbank in move + 2\r
- clc ; switch to native mode\r
- xce\r
- php ; save status bits\r
- rep #%00110000 ; set A and index to 16bit\r
-.A16\r
-.I16\r
- ldy ptr1\r
- ldx ptr2\r
- lda ptr3\r
-@move:\r
- mvn 0,0\r
- plp ; restore status bits\r
-.A8\r
-.I8\r
- lda #$00\r
- pha\r
- plb ; restore dbr\r
- sec\r
- xce ; switch to emul mode\r
- ply\r
- plx\r
- pla\r
- cli\r
- rts\r
-.P02\r
+;
+; Extended memory driver for 65816 based extra RAM. Driver works without
+; problems when statically linked.
+;
+; Marco van den Heuvel, 2015-12-01
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+ .macpack module
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+ module_header _c64_65816_emd
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Library reference
+
+ .addr $0000
+
+; Jump table
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr PAGECOUNT
+ .addr MAP
+ .addr USE
+ .addr COMMIT
+ .addr COPYFROM
+ .addr COPYTO
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+isnotscpu: .res 1 ; SuperCPU not present
+curpage: .res 1 ; Current page number
+curbank: .res 1 ; Current bank number (+1)
+bankcount: .res 1 ; Number of available banks (pages = banks * 256)
+window: .res 256 ; Memory "window"
+
+.code
+
+; ------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present and determine the amount of
+; memory available.
+; Must return an EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ sei
+ clc
+ sed
+ lda #$99
+ adc #$01 ; on 65C02, 65SC02, 65CE02, 65802 and 65816 sets the zero flag correctly
+ cld
+ bne @not_present
+ clc
+.P816
+ sep #$01 ; nop #$01 on 65C02/65SC02 and lda ($01,s),y on 65CE02
+.P02
+ bcc @not_present
+ lda $d0bc
+ and #$80
+ sta isnotscpu
+ lda $07e8
+ pha ; save value incase it was used somewhere else
+ ldx #$ff
+@fillloop: ; fill from top (bank 255) to bottom
+ txa
+ pha
+.P816
+ plb ; pull dbr
+.P02
+ stx $07e8
+ dex
+ cpx #$ff
+ bne @fillloop
+ inx
+@compareloop: ; check from bottom to top
+ txa
+ pha
+.P816
+ plb
+.P02
+ cmp $07e8
+ bne @found_pages
+.P816
+ inc
+.P02
+ sta $07e8
+ cmp $07e8
+ bne @found_pages
+ inx
+ bne @compareloop
+@found_pages:
+ dex
+ lda #$00
+ pha
+.P816
+ plb
+.P02
+ pla
+ sta $07e8
+ cli
+ lda isnotscpu
+ bne @noextradex
+ dex
+@noextradex:
+ stx bankcount
+ lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+ rts
+@not_present:
+ cli
+ lda #<EM_ERR_NO_DEVICE
+ ldx #>EM_ERR_NO_DEVICE
+; rts ; Run into UNINSTALL instead
+
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda #$00 ; a whole bank is either usable or not
+ ldx bankcount
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage ; Remember the new page
+ stx curbank ; Remember the new bank
+
+ sta ptr2+1 ; src address low
+ lda #$00
+ sta ptr2 ; src address high
+ inx
+ ldy isnotscpu ; check if not scpu
+ bne @notscpu
+ inx
+@notscpu:
+ stx tmp2 ; src bank
+
+ sta tmp1 ; dst bank
+
+ sta ptr3+1 ; length high
+ lda #$ff
+ sta ptr3 ; length low
+
+ lda #<window
+ sta ptr1 ; dst address low
+ ldx #>window
+ stx ptr1+1 ; dst address high
+
+ jsr transfer
+
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage ; Remember the page
+ stx curbank ; Remember the bank
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: lda curpage ; Get the current page
+ sta ptr1+1 ; dst high
+ ldx #$00
+ stx ptr1 ; dst low
+
+ lda #<window
+ sta ptr2 ; src low
+ lda #>window
+ sta ptr2+1 ; src high
+
+ stx ptr3+1 ; length high
+ lda #$ff
+ sta ptr3 ; length low
+
+ stx tmp2 ; src bank
+ ldy curbank ; Get the current bank
+ iny
+ ldx isnotscpu
+ bne @notascpu
+ iny
+@notascpu:
+ sty tmp1 ; dst bank
+
+ jsr transfer
+
+ rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ sta ptr4
+ stx ptr4+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::COUNT+1 ; start at the end of the struct
+ lda (ptr4),y ; get high byte of count
+ tax
+ dey
+ lda (ptr4),y ; get low byte of count
+ bne @nodex
+ dex
+@nodex:
+.P816
+ dec
+.P02
+ sta ptr3 ; length low
+ stx ptr3+1 ; length high
+ dey
+ lda (ptr4),y ; get bank
+.P816
+ inc
+.P02
+ ldx isnotscpu
+ bne @notscpu64
+.P816
+ inc
+.P02
+@notscpu64:
+ sta tmp2 ; src bank
+ dey
+ lda (ptr4),y ; get page
+ sta ptr2+1 ; src high
+ dey
+ lda (ptr4),y ; get offset in page
+ sta ptr2 ; src low
+ dey
+ lda (ptr4),y ; get memory buffer high
+ sta ptr1+1 ; dst high
+ dey
+ lda (ptr4),y ; get memory buffer low
+ sta ptr1 ; dst low
+ lda #$00
+ sta tmp1 ; dst bank
+
+ jsr transfer
+
+ rts
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO: sta ptr4
+ stx ptr4+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::COUNT+1 ; start at the end of the struct
+ lda (ptr4),y ; get high byte of count
+ tax
+ dey
+ lda (ptr4),y ; get low byte of count
+ bne @nodex2
+ dex
+@nodex2:
+.P816
+ dec
+.P02
+ sta ptr3 ; length low
+ txa
+ sta ptr3+1 ; length high
+ dey
+ lda (ptr4),y ; get bank
+.P816
+ inc
+.P02
+ ldx isnotscpu
+ bne @notascpu64
+.P816
+ inc
+.P02
+@notascpu64:
+ sta tmp1 ; dst bank
+ dey
+ lda (ptr4),y ; get page
+ sta ptr1+1 ; dst high
+ dey
+ lda (ptr4),y ; get page offset
+ sta ptr1 ; dst low
+ dey
+ lda (ptr4),y ; get memory buffer high
+ sta ptr2+1 ; src low
+ dey
+ lda (ptr4),y ; get memory buffer low
+ sta ptr2 ; src high
+ lda #$00
+ sta tmp2 ; src bank
+
+ jsr transfer
+
+ rts
+
+; ------------------------------------------------------------------------
+; Helper function for moving a block, the following is used:
+; ptr1: dst
+; ptr2: src
+; ptr3: length
+; tmp1: dst bank
+; tmp2: src bank
+
+transfer:
+.P816
+.A8
+.I8
+ sei
+ pha
+ phx
+ phy
+ ldx tmp1 ; load srcbank
+ stx @move+1 ; store srcbank in move + 1
+ ldy tmp2 ; load dstbank
+ sty @move+2 ; store dstbank in move + 2
+ clc ; switch to native mode
+ xce
+ php ; save status bits
+ rep #%00110000 ; set A and index to 16bit
+.A16
+.I16
+ ldy ptr1
+ ldx ptr2
+ lda ptr3
+@move:
+ mvn 0,0
+ plp ; restore status bits
+.A8
+.I8
+ lda #$00
+ pha
+ plb ; restore dbr
+ sec
+ xce ; switch to emul mode
+ ply
+ plx
+ pla
+ cli
+ rts
+.P02
-;\r
-; char cgetc (void);\r
-;\r
-\r
- .constructor initcgetc\r
- .export _cgetc\r
- .import cursor\r
-\r
- .include "osic1p.inc"\r
- .include "extzp.inc"\r
- .include "zeropage.inc"\r
-\r
-; Initialize one-character buffer that is filled by kbhit()\r
- .segment "ONCE"\r
-initcgetc:\r
- lda #$00\r
- sta CHARBUF ; No character in buffer initially\r
- rts\r
-\r
-; Input routine from 65V PROM MONITOR, show cursor if enabled\r
- .code\r
-_cgetc:\r
- lda CHARBUF ; character in buffer available?\r
- beq nobuffer\r
- tax ; save character in X\r
- lda #$00\r
- sta CHARBUF ; empty buffer\r
- beq restorex ; restore X and return\r
-nobuffer:\r
- lda cursor ; show cursor?\r
- beq nocursor\r
- ldy CURS_X\r
- lda (SCREEN_PTR),y ; fetch current character\r
- sta tmp1 ; save it\r
- lda #$A1 ; full white square\r
- sta (SCREEN_PTR),y ; store at cursor position\r
-nocursor:\r
- jsr INPUTC ; get input character in A\r
- ldx cursor\r
- beq done ; was cursor on?\r
- tax ; save A in X\r
- lda tmp1 ; fetch saved character\r
- ldy CURS_X\r
- sta (SCREEN_PTR),y ; store at cursor position\r
-\r
-restorex:\r
- txa ; restore saved character from X\r
-done:\r
- ldx #$00 ; high byte of int return value\r
- rts\r
+;
+; char cgetc (void);
+;
+
+ .constructor initcgetc
+ .export _cgetc
+ .import cursor
+
+ .include "osic1p.inc"
+ .include "extzp.inc"
+ .include "zeropage.inc"
+
+; Initialize one-character buffer that is filled by kbhit()
+ .segment "ONCE"
+initcgetc:
+ lda #$00
+ sta CHARBUF ; No character in buffer initially
+ rts
+
+; Input routine from 65V PROM MONITOR, show cursor if enabled
+ .code
+_cgetc:
+ lda CHARBUF ; character in buffer available?
+ beq nobuffer
+ tax ; save character in X
+ lda #$00
+ sta CHARBUF ; empty buffer
+ beq restorex ; restore X and return
+nobuffer:
+ lda cursor ; show cursor?
+ beq nocursor
+ ldy CURS_X
+ lda (SCREEN_PTR),y ; fetch current character
+ sta tmp1 ; save it
+ lda #$A1 ; full white square
+ sta (SCREEN_PTR),y ; store at cursor position
+nocursor:
+ jsr INPUTC ; get input character in A
+ ldx cursor
+ beq done ; was cursor on?
+ tax ; save A in X
+ lda tmp1 ; fetch saved character
+ ldy CURS_X
+ sta (SCREEN_PTR),y ; store at cursor position
+
+restorex:
+ txa ; restore saved character from X
+done:
+ ldx #$00 ; high byte of int return value
+ rts
-; Addresses\r
-INPUTC := $FD00 ; Input character from keyboard\r
-RESET := $FF00 ; Reset address, show boot prompt\r
-KBD := $DF00 ; Polled keyboard register\r
+; Addresses
+INPUTC := $FD00 ; Input character from keyboard
+RESET := $FF00 ; Reset address, show boot prompt
+KBD := $DF00 ; Polled keyboard register
-;\r
-; Macro definitions for screen layout modules\r
-;\r
-\r
- .include "extzp.inc"\r
- \r
-.linecont +\r
-\r
-;\r
-; Internal function for screensize()\r
-;\r
-.macro osi_screensize ScrWidth, ScrHeight\r
- ; Macro implementation of internal screensize\r
- ; function for given width and height in\r
- ; characters\r
- \r
- .export screensize\r
-\r
-.proc screensize\r
- ldx #ScrWidth\r
- ldy #ScrHeight\r
- rts\r
-.endproc\r
-.endmacro\r
-\r
-;\r
-; void clrscr (void);\r
-;\r
-.macro osi_clrscr ScrBase, ScrRamSize\r
-\r
- .export _clrscr\r
-\r
-.proc _clrscr\r
- lda #<ScrBase ; Fill whole video RAM with blanks by calling\r
- ldx #>ScrBase ; memset appropriately\r
- jsr pushax\r
- \r
- lda #' '\r
- ldx #$00\r
- jsr pushax\r
- \r
- lda #<ScrRamSize\r
- ldx #>ScrRamSize\r
- jsr _memset\r
-\r
- lda #$00 ; Cursor in upper left corner\r
- sta CURS_X\r
- sta CURS_Y\r
- \r
- jmp plot ; Set the cursor position\r
-.endproc\r
-\r
-.endmacro\r
-\r
-;\r
-; cputc/cputcxy for Challenger 1P\r
-; Based on PET/CBM implementation\r
-;\r
-\r
-.macro osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \\r
- ScrollDist, ScrLo, ScrHi\r
-\r
- ; Number of characters to move for scrolling\r
- ; by one line\r
-ScrollLength = (ScrHeight - 1) * ScrollDist\r
-\r
-;\r
-; void cputcxy (unsigned char x, unsigned char y, char c);\r
-; void cputc (char c);\r
-;\r
- .export _cputcxy, _cputc, cputdirect, putchar\r
- .export newline, plot\r
-\r
-_cputcxy:\r
- pha ; Save C\r
- jsr gotoxy ; Set cursor, drop x and y\r
- pla ; Restore C\r
-\r
-; Plot a character - also used as internal function\r
-\r
-_cputc: cmp #$0A ; CR?\r
- bne L1\r
- lda #0\r
- sta CURS_X\r
- beq plot ; Recalculate pointers\r
-\r
-L1: cmp #$0D ; LF?\r
- beq newline ; Recalculate pointers\r
-\r
-cputdirect:\r
- jsr putchar ; Write the character to the screen\r
-\r
-; Advance cursor position, register Y contains horizontal position after\r
-; putchar\r
-\r
- cpy #(ScrWidth - 1) ; Check whether line is full\r
- bne L3\r
- jsr newline ; New line\r
- ldy #$FF ; + cr\r
-L3: iny\r
- sty CURS_X\r
- rts\r
-\r
-newline:\r
- inc CURS_Y\r
- lda CURS_Y\r
- cmp #ScrHeight ; Screen height\r
- bne plot\r
- dec CURS_Y ; Bottom of screen reached, scroll\r
-\r
- ; Scroll destination address\r
- lda #<(ScrBase + ScrFirstChar)\r
- ldx #>(ScrBase + ScrFirstChar)\r
- jsr pushax\r
- \r
- ; Scroll source address\r
- lda #<(ScrBase + ScrFirstChar + ScrollDist)\r
- ldx #>(ScrBase + ScrFirstChar + ScrollDist)\r
- jsr pushax\r
- \r
- ; Number of characters to move\r
- lda #<ScrollLength\r
- ldx #>ScrollLength\r
- jsr _memmove\r
-\r
- ; Address of first character in last line\r
- ; of screen\r
- lda #<(ScrBase + ScrFirstChar + ScrollLength)\r
- sta ptr1\r
- lda #>(ScrBase + ScrFirstChar + ScrollLength)\r
- sta ptr1+1\r
- \r
- ldy #ScrWidth ; Fill last line with blanks\r
- lda #' '\r
-clrln: sta (ptr1),y\r
- dey\r
- bpl clrln\r
-\r
-plot: ldy CURS_Y\r
- lda ScrLo,y\r
- sta SCREEN_PTR\r
- lda ScrHi,y\r
- sta SCREEN_PTR+1\r
- rts\r
-\r
-; Write one character to the screen without doing anything else, return X\r
-; position in register Y\r
-\r
-putchar:\r
- ldy CURS_X\r
- sta (SCREEN_PTR),y ; Set char\r
- rts\r
- \r
-.endmacro\r
-\r
-.macro osi_screen_funcs ScrBase, ScrRamSize, ScrFirstChar, \\r
- ScrWidth, ScrHeight, ScrollDist\r
-\r
- .import gotoxy\r
- .import _memmove, _memset, pushax\r
- .importzp ptr1\r
-\r
-.rodata\r
-\r
-; Screen address tables - offset to real screen\r
-ScrTabLo:\r
- .repeat ScrHeight, I\r
- .byte <(ScrBase + ScrFirstChar + I * ScrollDist)\r
- .endrep\r
- \r
-ScrTabHi:\r
- .repeat ScrHeight, I\r
- .byte >(ScrBase + ScrFirstChar + I * ScrollDist)\r
- .endrep\r
-\r
-.code\r
-\r
-osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \\r
- ScrollDist, ScrTabLo, ScrTabHi\r
-osi_screensize ScrWidth, ScrHeight\r
-osi_clrscr ScrBase, ScrRamSize\r
-\r
+;
+; Macro definitions for screen layout modules
+;
+
+ .include "extzp.inc"
+
+.linecont +
+
+;
+; Internal function for screensize()
+;
+.macro osi_screensize ScrWidth, ScrHeight
+ ; Macro implementation of internal screensize
+ ; function for given width and height in
+ ; characters
+
+ .export screensize
+
+.proc screensize
+ ldx #ScrWidth
+ ldy #ScrHeight
+ rts
+.endproc
+.endmacro
+
+;
+; void clrscr (void);
+;
+.macro osi_clrscr ScrBase, ScrRamSize
+
+ .export _clrscr
+
+.proc _clrscr
+ lda #<ScrBase ; Fill whole video RAM with blanks by calling
+ ldx #>ScrBase ; memset appropriately
+ jsr pushax
+
+ lda #' '
+ ldx #$00
+ jsr pushax
+
+ lda #<ScrRamSize
+ ldx #>ScrRamSize
+ jsr _memset
+
+ lda #$00 ; Cursor in upper left corner
+ sta CURS_X
+ sta CURS_Y
+
+ jmp plot ; Set the cursor position
+.endproc
+
+.endmacro
+
+;
+; cputc/cputcxy for Challenger 1P
+; Based on PET/CBM implementation
+;
+
+.macro osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \
+ ScrollDist, ScrLo, ScrHi
+
+ ; Number of characters to move for scrolling
+ ; by one line
+ScrollLength = (ScrHeight - 1) * ScrollDist
+
+;
+; void cputcxy (unsigned char x, unsigned char y, char c);
+; void cputc (char c);
+;
+ .export _cputcxy, _cputc, cputdirect, putchar
+ .export newline, plot
+
+_cputcxy:
+ pha ; Save C
+ jsr gotoxy ; Set cursor, drop x and y
+ pla ; Restore C
+
+; Plot a character - also used as internal function
+
+_cputc: cmp #$0A ; CR?
+ bne L1
+ lda #0
+ sta CURS_X
+ beq plot ; Recalculate pointers
+
+L1: cmp #$0D ; LF?
+ beq newline ; Recalculate pointers
+
+cputdirect:
+ jsr putchar ; Write the character to the screen
+
+; Advance cursor position, register Y contains horizontal position after
+; putchar
+
+ cpy #(ScrWidth - 1) ; Check whether line is full
+ bne L3
+ jsr newline ; New line
+ ldy #$FF ; + cr
+L3: iny
+ sty CURS_X
+ rts
+
+newline:
+ inc CURS_Y
+ lda CURS_Y
+ cmp #ScrHeight ; Screen height
+ bne plot
+ dec CURS_Y ; Bottom of screen reached, scroll
+
+ ; Scroll destination address
+ lda #<(ScrBase + ScrFirstChar)
+ ldx #>(ScrBase + ScrFirstChar)
+ jsr pushax
+
+ ; Scroll source address
+ lda #<(ScrBase + ScrFirstChar + ScrollDist)
+ ldx #>(ScrBase + ScrFirstChar + ScrollDist)
+ jsr pushax
+
+ ; Number of characters to move
+ lda #<ScrollLength
+ ldx #>ScrollLength
+ jsr _memmove
+
+ ; Address of first character in last line
+ ; of screen
+ lda #<(ScrBase + ScrFirstChar + ScrollLength)
+ sta ptr1
+ lda #>(ScrBase + ScrFirstChar + ScrollLength)
+ sta ptr1+1
+
+ ldy #ScrWidth ; Fill last line with blanks
+ lda #' '
+clrln: sta (ptr1),y
+ dey
+ bpl clrln
+
+plot: ldy CURS_Y
+ lda ScrLo,y
+ sta SCREEN_PTR
+ lda ScrHi,y
+ sta SCREEN_PTR+1
+ rts
+
+; Write one character to the screen without doing anything else, return X
+; position in register Y
+
+putchar:
+ ldy CURS_X
+ sta (SCREEN_PTR),y ; Set char
+ rts
+
+.endmacro
+
+.macro osi_screen_funcs ScrBase, ScrRamSize, ScrFirstChar, \
+ ScrWidth, ScrHeight, ScrollDist
+
+ .import gotoxy
+ .import _memmove, _memset, pushax
+ .importzp ptr1
+
+.rodata
+
+; Screen address tables - offset to real screen
+ScrTabLo:
+ .repeat ScrHeight, I
+ .byte <(ScrBase + ScrFirstChar + I * ScrollDist)
+ .endrep
+
+ScrTabHi:
+ .repeat ScrHeight, I
+ .byte >(ScrBase + ScrFirstChar + I * ScrollDist)
+ .endrep
+
+.code
+
+osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \
+ ScrollDist, ScrTabLo, ScrTabHi
+osi_screensize ScrWidth, ScrHeight
+osi_clrscr ScrBase, ScrRamSize
+
.endmacro
\ No newline at end of file
-/*\r
- !!DESCRIPTION!! div/mod test\r
- !!ORIGIN!!\r
- !!LICENCE!! public domain\r
-*/\r
-\r
-#include <stdio.h>\r
-\r
-void printc(signed char a,signed char b){\r
-signed char x=a/b,y=a%b,z=a*b;\r
- printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z);\r
-}\r
-void prints(short a,short b){\r
-short x=a/b,y=a%b,z=a*b;\r
- printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z);\r
-}\r
-void printl(long a,long b){\r
-long x=a/b,y=a%b,z=a*b;\r
- printf("%3ld,%3ld is %3ld,%3ld,%3ld\n",a,b,x,y,z);\r
-}\r
-\r
-int main(void) {\r
- printl( 3,-2);\r
- printl(-3,-2);\r
- printl(-3, 2);\r
- printl( 3, 2);\r
- printf("-\n");\r
- prints( 3,-2);\r
- prints(-3,-2);\r
- prints(-3, 2);\r
- prints( 3, 2);\r
- printf("-\n");\r
- printc( 3,-2);\r
- printc(-3,-2);\r
- printc(-3, 2);\r
- printc( 3, 2);\r
+/*
+ !!DESCRIPTION!! div/mod test
+ !!ORIGIN!!
+ !!LICENCE!! public domain
+*/
+
+#include <stdio.h>
+
+void printc(signed char a,signed char b){
+signed char x=a/b,y=a%b,z=a*b;
+ printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z);
+}
+void prints(short a,short b){
+short x=a/b,y=a%b,z=a*b;
+ printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z);
+}
+void printl(long a,long b){
+long x=a/b,y=a%b,z=a*b;
+ printf("%3ld,%3ld is %3ld,%3ld,%3ld\n",a,b,x,y,z);
+}
+
+int main(void) {
+ printl( 3,-2);
+ printl(-3,-2);
+ printl(-3, 2);
+ printl( 3, 2);
+ printf("-\n");
+ prints( 3,-2);
+ prints(-3,-2);
+ prints(-3, 2);
+ prints( 3, 2);
+ printf("-\n");
+ printc( 3,-2);
+ printc(-3,-2);
+ printc(-3, 2);
+ printc( 3, 2);
return 0;
-}\r
+}
-/*\r
- !!DESCRIPTION!! variable initialization\r
- !!ORIGIN!! LCC 4.1 Testsuite\r
- !!LICENCE!! own, freely distributeable for non-profit. read CPYRIGHT.LCC\r
-*/\r
-\r
-#include "common.h"\r
-/* todo: add back conditional stuff here ! */\r
-\r
-typedef struct { int codes[3]; char name[6]; } Word;\r
-\r
-#ifdef NO_IMPLICIT_FUNC_PROTOTYPES\r
-\r
-#ifdef NO_OLD_FUNC_DECL\r
-f();\r
-void g(Word *p);\r
-h();\r
-#else\r
-f();\r
-g();\r
-h();\r
-#endif\r
-\r
-#endif\r
-\r
-/*\r
-Word words[] = {\r
- 1, 2, 3,"if",\r
- { { 4, 5 }, { 'f', 'o', 'r' } },\r
- 6, 7, 8, {"else"},\r
- { { 9, 10, 11,}, 'w', 'h', 'i', 'l', 'e', },\r
- { 0 },\r
-}, *wordlist = words;\r
-*/\r
-\r
-Word words[] = {\r
- {{1, 2, 3},"if"},\r
- { { 4, 5 }, { 'f', 'o', 'r' } },\r
- {{6, 7, 8}, "else"},\r
- { { 9, 10, 11}, {'w', 'h', 'i', 'l', 'e', }},\r
- {{ 0 }},\r
-}, *wordlist = words;\r
-\r
-/*int x[][5] = { 1, 2, 3, 4, 0, { 5, 6 }, { 7 } };*/\r
-int x[][5] = { {1, 2, 3, 4, 0 }, { 5, 6 }, { 7 } };\r
-int *y[] = { x[0], x[1], x[2], 0 };\r
-\r
-main()\r
-{\r
- int i, j;\r
-\r
- for (i = 0; y[i]; i++) {\r
- for (j = 0; y[i][j]; j++)\r
- printf(" %d", y[i][j]);\r
- printf("\n");\r
- }\r
- f();\r
- g(wordlist);\r
- return 0;\r
-}\r
-\r
-f() {\r
- static char *keywords[] = {"if", "for", "else", "while", 0, };\r
- char **p;\r
-\r
- for (p = keywords; *p; p++)\r
- printf("%s\n", *p);\r
-}\r
-\r
-#ifdef NO_OLD_FUNC_DECL\r
-void g(Word *p)\r
-#else\r
-g(p)\r
-Word *p;\r
-#endif\r
-{\r
- int i;\r
-\r
- for ( ; p->codes[0]; p++) {\r
- for (i = 0; i < sizeof p->codes/sizeof(p->codes[0]); i++)\r
- printf("%d ", p->codes[i]);\r
- printf("%s\n", p->name);\r
- }\r
- h();\r
-}\r
-\r
-h()\r
-{\r
- int i;\r
-\r
- for (i = 0; i < sizeof(words)/sizeof(Word); i++)\r
- printf("%d %d %d %s\n", words[i].codes[0],\r
- words[i].codes[1], words[i].codes[2],\r
- &words[i].name[0]);\r
-}\r
+/*
+ !!DESCRIPTION!! variable initialization
+ !!ORIGIN!! LCC 4.1 Testsuite
+ !!LICENCE!! own, freely distributeable for non-profit. read CPYRIGHT.LCC
+*/
+
+#include "common.h"
+/* todo: add back conditional stuff here ! */
+
+typedef struct { int codes[3]; char name[6]; } Word;
+
+#ifdef NO_IMPLICIT_FUNC_PROTOTYPES
+
+#ifdef NO_OLD_FUNC_DECL
+f();
+void g(Word *p);
+h();
+#else
+f();
+g();
+h();
+#endif
+
+#endif
+
+/*
+Word words[] = {
+ 1, 2, 3,"if",
+ { { 4, 5 }, { 'f', 'o', 'r' } },
+ 6, 7, 8, {"else"},
+ { { 9, 10, 11,}, 'w', 'h', 'i', 'l', 'e', },
+ { 0 },
+}, *wordlist = words;
+*/
+
+Word words[] = {
+ {{1, 2, 3},"if"},
+ { { 4, 5 }, { 'f', 'o', 'r' } },
+ {{6, 7, 8}, "else"},
+ { { 9, 10, 11}, {'w', 'h', 'i', 'l', 'e', }},
+ {{ 0 }},
+}, *wordlist = words;
+
+/*int x[][5] = { 1, 2, 3, 4, 0, { 5, 6 }, { 7 } };*/
+int x[][5] = { {1, 2, 3, 4, 0 }, { 5, 6 }, { 7 } };
+int *y[] = { x[0], x[1], x[2], 0 };
+
+main()
+{
+ int i, j;
+
+ for (i = 0; y[i]; i++) {
+ for (j = 0; y[i][j]; j++)
+ printf(" %d", y[i][j]);
+ printf("\n");
+ }
+ f();
+ g(wordlist);
+ return 0;
+}
+
+f() {
+ static char *keywords[] = {"if", "for", "else", "while", 0, };
+ char **p;
+
+ for (p = keywords; *p; p++)
+ printf("%s\n", *p);
+}
+
+#ifdef NO_OLD_FUNC_DECL
+void g(Word *p)
+#else
+g(p)
+Word *p;
+#endif
+{
+ int i;
+
+ for ( ; p->codes[0]; p++) {
+ for (i = 0; i < sizeof p->codes/sizeof(p->codes[0]); i++)
+ printf("%d ", p->codes[i]);
+ printf("%s\n", p->name);
+ }
+ h();
+}
+
+h()
+{
+ int i;
+
+ for (i = 0; i < sizeof(words)/sizeof(Word); i++)
+ printf("%d %d %d %s\n", words[i].codes[0],
+ words[i].codes[1], words[i].codes[2],
+ &words[i].name[0]);
+}
-/*\r
- !!DESCRIPTION!! pointer test\r
- !!ORIGIN!!\r
- !!LICENCE!! public domain\r
-*/\r
-\r
-#include "common.h"\r
-#include <stdio.h>\r
-\r
-/*\r
- check behaviour on incompletely declared arrays\r
-*/\r
-\r
-char i1[];\r
-\r
-void test1(void) {\r
-int a;\r
-\r
- a=sizeof(i1[0]);\r
- printf("%04x - ",a);\r
- if(sizeof(i1[0])==sizeof(char)) {\r
- /* gcc gives size of element */\r
- printf("sizeof(i1[0]) gives size of element\n");\r
- }\r
- if(sizeof(i1[0])==sizeof(char*)) {\r
- printf("sizeof(i1[0]) gives size of pointer to element\n");\r
- }\r
-}\r
-\r
-/*\r
- check behaviour on string init\r
-*/\r
-\r
-char t1[]="abcde";\r
-char t2[]={"abcde"};\r
-\r
-char *t3="abcde";\r
-char *t4={"abcde"};\r
-\r
-void test2(void) {\r
-char c1,c2,c3,c4;\r
-int i,e=0;\r
- for(i=0;i<5;i++){\r
- c1=t1[i];c2=t2[i];c3=t3[i];c4=t4[i];\r
-/* printf("%02x %02x %02x %02x\n",c1,c2,c3,c4); */\r
- printf("%c %c %c %c\n",c1,c2,c3,c4);\r
- if(!((c1==c2)&(c1==c3)&(c1==c4))) e=1;\r
- }\r
- if(e) printf("test2 failed.\n");\r
- else printf("test2 ok.\n");\r
-}\r
-\r
-/*\r
- check behaviour on extern-declarations inside functions\r
-*/\r
-\r
-typedef struct {\r
- char *name;\r
- void *func;\r
-} A3;\r
-\r
-#ifdef NO_SLOPPY_STRUCT_INIT\r
-A3 a3[] = {\r
- { "test3", (void*) NULL },\r
- { "test3", (void*) NULL },\r
-};\r
-#else\r
-/*gcc warning: missing braces around initializer (near initialization for `a3[0]')\r
- this type of struct-initialization seems to be kinda common */\r
-A3 a3[] = {\r
- "test3", (void*) NULL ,\r
- "test3", (void*) NULL ,\r
-};\r
-#endif\r
-\r
-void test3a(A3 *list, int number){\r
- printf("%s %d\n",list->name,number);\r
-}\r
-\r
-static void test31(void)\r
-{\r
- extern A3 a3[];\r
- test3a(a3, -1);\r
-}\r
-\r
-#if 0\r
-/* this variation compiles and works with cc65, but gives an error with gcc :=P */\r
-static void test32(void)\r
-{\r
- extern A3 *a3;\r
- test3a(a3, -1);\r
-}\r
-#endif\r
-\r
-static void test30(void)\r
-{\r
- test3a(a3, -1);\r
-}\r
-\r
-/*\r
- todo: add test on function pointers in the form of (*func)(arg) ...\r
- cc65 seems to have problems here aswell ;/\r
-*/\r
-\r
-int main(void) {\r
- test1();\r
- test2();\r
- test30();\r
- test31();\r
-/* test32(); */\r
- return 0;\r
-}\r
+/*
+ !!DESCRIPTION!! pointer test
+ !!ORIGIN!!
+ !!LICENCE!! public domain
+*/
+
+#include "common.h"
+#include <stdio.h>
+
+/*
+ check behaviour on incompletely declared arrays
+*/
+
+char i1[];
+
+void test1(void) {
+int a;
+
+ a=sizeof(i1[0]);
+ printf("%04x - ",a);
+ if(sizeof(i1[0])==sizeof(char)) {
+ /* gcc gives size of element */
+ printf("sizeof(i1[0]) gives size of element\n");
+ }
+ if(sizeof(i1[0])==sizeof(char*)) {
+ printf("sizeof(i1[0]) gives size of pointer to element\n");
+ }
+}
+
+/*
+ check behaviour on string init
+*/
+
+char t1[]="abcde";
+char t2[]={"abcde"};
+
+char *t3="abcde";
+char *t4={"abcde"};
+
+void test2(void) {
+char c1,c2,c3,c4;
+int i,e=0;
+ for(i=0;i<5;i++){
+ c1=t1[i];c2=t2[i];c3=t3[i];c4=t4[i];
+/* printf("%02x %02x %02x %02x\n",c1,c2,c3,c4); */
+ printf("%c %c %c %c\n",c1,c2,c3,c4);
+ if(!((c1==c2)&(c1==c3)&(c1==c4))) e=1;
+ }
+ if(e) printf("test2 failed.\n");
+ else printf("test2 ok.\n");
+}
+
+/*
+ check behaviour on extern-declarations inside functions
+*/
+
+typedef struct {
+ char *name;
+ void *func;
+} A3;
+
+#ifdef NO_SLOPPY_STRUCT_INIT
+A3 a3[] = {
+ { "test3", (void*) NULL },
+ { "test3", (void*) NULL },
+};
+#else
+/*gcc warning: missing braces around initializer (near initialization for `a3[0]')
+ this type of struct-initialization seems to be kinda common */
+A3 a3[] = {
+ "test3", (void*) NULL ,
+ "test3", (void*) NULL ,
+};
+#endif
+
+void test3a(A3 *list, int number){
+ printf("%s %d\n",list->name,number);
+}
+
+static void test31(void)
+{
+ extern A3 a3[];
+ test3a(a3, -1);
+}
+
+#if 0
+/* this variation compiles and works with cc65, but gives an error with gcc :=P */
+static void test32(void)
+{
+ extern A3 *a3;
+ test3a(a3, -1);
+}
+#endif
+
+static void test30(void)
+{
+ test3a(a3, -1);
+}
+
+/*
+ todo: add test on function pointers in the form of (*func)(arg) ...
+ cc65 seems to have problems here aswell ;/
+*/
+
+int main(void) {
+ test1();
+ test2();
+ test30();
+ test31();
+/* test32(); */
+ return 0;
+}
-/*\r
- !!DESCRIPTION!! switch test\r
- !!ORIGIN!!\r
- !!LICENCE!! public domain\r
-*/\r
-\r
-/*#define STANDALONE*/\r
-\r
-#include <stdio.h>\r
-\r
+/*
+ !!DESCRIPTION!! switch test
+ !!ORIGIN!!
+ !!LICENCE!! public domain
+*/
+
+/*#define STANDALONE*/
+
+#include <stdio.h>
+
void testlimits(int i) {
- printf("%d:",i);\r
-\r
+ printf("%d:",i);
+
switch(i) {
- case -1: /* works */\r
- /* case 0xffff: */ /* 'range error' (-1) */\r
-\r
- printf("-1\n");\r
- break;\r
- /* max int */\r
-\r
-/* case 0x7fff: */ /* works */\r
- case 32767: /* works */\r
- /* case 32768: */ /* 'range error' (correct for that one!) */\r
-\r
- printf("max\n");\r
- break;\r
- /* min int */\r
-\r
- case -32768: /* 'warning. constant is long' */\r
- /* case 0x8000: */ /* 'range error' */\r
- /* case -32769: */ /* 'range error' (correct for that one!) */\r
- printf("min\n");\r
- break;\r
- }\r
- printf("\n");\r
-}\r
-\r
-void testdefault1(unsigned char i) {\r
-/* we want a signed char */\r
-#ifdef REFCC\r
-\r
-#ifdef REFCC_UNSIGNED_CHARS\r
-signed char k;\r
-#else\r
-char k;\r
-#endif\r
- \r
-#else\r
- \r
-#ifdef UNSIGNED_CHARS\r
-signed char k;\r
-#else\r
-char k;\r
-#endif\r
-\r
-#endif\r
-\r
- for(;i<254;) {\r
- k = i;\r
- printf(">%d\n",i);i++;\r
- switch(k) {\r
- case 1:\r
- break;\r
- case 2:\r
- break;\r
- case 3:\r
- break;\r
- case 4:\r
- break;\r
- case 5:\r
- break;\r
- case 6:\r
- break;\r
- case 7:\r
- break;\r
- case 8:\r
- break;\r
- case 9:\r
- break;\r
- case 10:\r
- break;\r
- case 11:\r
- break;\r
- case 12:\r
- break;\r
- case 13:\r
- break;\r
- case 14:\r
- break;\r
- case 15:\r
- break;\r
- case 17:\r
- break;\r
- /* triggers bug ? */\r
- /* gcc warning: case label value exceeds maximum value for type */\r
- /* cc65 error: range error */\r
-\r
- /*\r
- case 170:\r
- break;\r
- */\r
- case 18:\r
- break;\r
- case 19:\r
- break;\r
- case 20:\r
- break;\r
- case 21:\r
- break;\r
- case 22:\r
- break;\r
- case 23:\r
- break;\r
- case 24:\r
- switch(k) {\r
- case 1:\r
- break;\r
- case 2:\r
- break;\r
- case 3:\r
- break;\r
- case 4:\r
- case 5:\r
- break;\r
- case 6:\r
- case 7:\r
- break;\r
- case 8:\r
- case 9:\r
- break;\r
- }\r
- break;\r
- case 100:\r
- break;\r
- default:\r
- printf(">>>default\n");\r
- /* triggers bug if this break; is missing? */\r
- /* break; */\r
- }\r
- }\r
-}\r
-\r
-void testdefault2(unsigned char i) {\r
-/* we want a unsigned char */\r
-#ifdef REFCC\r
-\r
-#ifdef REFCC_UNSIGNED_CHARS\r
-char k;\r
-#else\r
-unsigned char k;\r
-#endif\r
- \r
-#else\r
- \r
-#ifdef UNSIGNED_CHARS\r
-char k;\r
-#else\r
-unsigned char k;\r
-#endif\r
-\r
-#endif\r
-\r
- for(;i<254;) {\r
- k = i;\r
- printf(">%d\n",i);i++;\r
- switch(k) {\r
- case 1:\r
- break;\r
- case 2:\r
- break;\r
- case 3:\r
- break;\r
- case 4:\r
- break;\r
- case 5:\r
- break;\r
- case 6:\r
- break;\r
- case 7:\r
- break;\r
- case 8:\r
- break;\r
- case 9:\r
- break;\r
- case 10:\r
- break;\r
- case 11:\r
- break;\r
- case 12:\r
- break;\r
- case 13:\r
- break;\r
- case 14:\r
- break;\r
- case 15:\r
- break;\r
- case 17:\r
- break;\r
- /* triggers bug ? */\r
-\r
- case 170:\r
- break;\r
- \r
- case 18:\r
- break;\r
- case 19:\r
- break;\r
- case 20:\r
- break;\r
- case 21:\r
- break;\r
- case 22:\r
- break;\r
- case 23:\r
- break;\r
- case 24:\r
- switch(k) {\r
- case 1:\r
- break;\r
- case 2:\r
- break;\r
- case 3:\r
- break;\r
- case 4:\r
- case 5:\r
- break;\r
- case 6:\r
- case 7:\r
- break;\r
- case 8:\r
- case 9:\r
- break;\r
- }\r
- break;\r
- case 100:\r
- break;\r
- default:\r
- printf(">>>default\n");\r
- /* triggers bug if this break; is missing? */\r
- /* break; */\r
- }\r
- }\r
+ case -1: /* works */
+ /* case 0xffff: */ /* 'range error' (-1) */
+
+ printf("-1\n");
+ break;
+ /* max int */
+
+/* case 0x7fff: */ /* works */
+ case 32767: /* works */
+ /* case 32768: */ /* 'range error' (correct for that one!) */
+
+ printf("max\n");
+ break;
+ /* min int */
+
+ case -32768: /* 'warning. constant is long' */
+ /* case 0x8000: */ /* 'range error' */
+ /* case -32769: */ /* 'range error' (correct for that one!) */
+ printf("min\n");
+ break;
+ }
+ printf("\n");
+}
+
+void testdefault1(unsigned char i) {
+/* we want a signed char */
+#ifdef REFCC
+
+#ifdef REFCC_UNSIGNED_CHARS
+signed char k;
+#else
+char k;
+#endif
+
+#else
+
+#ifdef UNSIGNED_CHARS
+signed char k;
+#else
+char k;
+#endif
+
+#endif
+
+ for(;i<254;) {
+ k = i;
+ printf(">%d\n",i);i++;
+ switch(k) {
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ case 4:
+ break;
+ case 5:
+ break;
+ case 6:
+ break;
+ case 7:
+ break;
+ case 8:
+ break;
+ case 9:
+ break;
+ case 10:
+ break;
+ case 11:
+ break;
+ case 12:
+ break;
+ case 13:
+ break;
+ case 14:
+ break;
+ case 15:
+ break;
+ case 17:
+ break;
+ /* triggers bug ? */
+ /* gcc warning: case label value exceeds maximum value for type */
+ /* cc65 error: range error */
+
+ /*
+ case 170:
+ break;
+ */
+ case 18:
+ break;
+ case 19:
+ break;
+ case 20:
+ break;
+ case 21:
+ break;
+ case 22:
+ break;
+ case 23:
+ break;
+ case 24:
+ switch(k) {
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ case 4:
+ case 5:
+ break;
+ case 6:
+ case 7:
+ break;
+ case 8:
+ case 9:
+ break;
+ }
+ break;
+ case 100:
+ break;
+ default:
+ printf(">>>default\n");
+ /* triggers bug if this break; is missing? */
+ /* break; */
+ }
+ }
+}
+
+void testdefault2(unsigned char i) {
+/* we want a unsigned char */
+#ifdef REFCC
+
+#ifdef REFCC_UNSIGNED_CHARS
+char k;
+#else
+unsigned char k;
+#endif
+
+#else
+
+#ifdef UNSIGNED_CHARS
+char k;
+#else
+unsigned char k;
+#endif
+
+#endif
+
+ for(;i<254;) {
+ k = i;
+ printf(">%d\n",i);i++;
+ switch(k) {
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ case 4:
+ break;
+ case 5:
+ break;
+ case 6:
+ break;
+ case 7:
+ break;
+ case 8:
+ break;
+ case 9:
+ break;
+ case 10:
+ break;
+ case 11:
+ break;
+ case 12:
+ break;
+ case 13:
+ break;
+ case 14:
+ break;
+ case 15:
+ break;
+ case 17:
+ break;
+ /* triggers bug ? */
+
+ case 170:
+ break;
+
+ case 18:
+ break;
+ case 19:
+ break;
+ case 20:
+ break;
+ case 21:
+ break;
+ case 22:
+ break;
+ case 23:
+ break;
+ case 24:
+ switch(k) {
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ case 4:
+ case 5:
+ break;
+ case 6:
+ case 7:
+ break;
+ case 8:
+ case 9:
+ break;
+ }
+ break;
+ case 100:
+ break;
+ default:
+ printf(">>>default\n");
+ /* triggers bug if this break; is missing? */
+ /* break; */
+ }
+ }
}
int main(void) {
- testlimits(32767);\r
- testlimits(-32768);\r
- testlimits(-1);\r
- \r
- testdefault1(1);\r
- testdefault1(2);\r
- testdefault1(3);\r
- testdefault1(4);\r
- \r
- testdefault2(1);\r
- testdefault2(2);\r
- testdefault2(3);\r
- testdefault2(4);\r
-\r
- return 0;\r
-}\r
+ testlimits(32767);
+ testlimits(-32768);
+ testlimits(-1);
+
+ testdefault1(1);
+ testdefault1(2);
+ testdefault1(3);
+ testdefault1(4);
+
+ testdefault2(1);
+ testdefault2(2);
+ testdefault2(3);
+ testdefault2(4);
+
+ return 0;
+}
/*
- !!DESCRIPTION!! varargs test\r
- !!ORIGIN!!\r
- !!LICENCE!! public domain\r
-*/\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <stdarg.h>\r
-\r
-void chk0(char *format,...);\r
-void chk1(int fd,char *format,...);\r
-\r
-#if 0\r
-// old workaround for broken varargs\r
-\r
-void chk0(char *format,...){\r
- __asm__ ("pha"); // save argument size\r
- {\r
-//va_list ap;\r
-char *ap;\r
-char *_format;\r
-static char string[0x100];\r
-\r
-// va_start(ap,format);\r
- __asm__ ("pla"); // restore argument size\r
- __asm__ ("ldx #$00"); // clear hibyte of AX\r
- ap=__AX__;\r
- ap+=(char*)&format;\r
- // get value of format\r
- ap-=2;\r
- _format=*((char**)ap);\r
-\r
-// vsprintf(string,format,ap);\r
- vsprintf(&string[0],_format,ap);\r
- printf("format:%s,string:%s\n",_format,string);\r
-// va_end(ap);\r
-\r
- }\r
-}\r
-\r
-void chk1(int fd,char *format,...){\r
- __asm__ ("pha"); // save argument size\r
- {\r
-//va_list ap;\r
-char *ap;\r
-char *_format;\r
-int _fd;\r
-static char string[0x100];\r
-\r
-// va_start(ap,format);\r
- __asm__ ("pla"); // restore argument size\r
- __asm__ ("ldx #$00"); // clear hibyte of AX\r
- ap=__AX__;\r
- ap+=(char*)&format;\r
- // get value of fd\r
- ap-=2;\r
- _fd=*((int*)ap);\r
- // get value of format\r
- ap-=2;\r
- _format=*((char**)ap);\r
-\r
-// vsprintf(string,format,ap);\r
- vsprintf(&string[0],_format,ap);\r
- printf("fd:%d,format:%s,string:%s\n",_fd,_format,string);\r
-// va_end(ap);\r
-\r
- }\r
-}\r
-\r
-#endif\r
-\r
-void chk0(char *format,...){\r
-va_list ap;\r
-static char string[0x100];\r
- va_start(ap,format);\r
- vsprintf(string,format,ap);\r
- printf("format:%s,string:%s\n",format,string);\r
- va_end(ap);\r
-}\r
-\r
-void chk1(int fd,char *format,...){\r
-va_list ap;\r
-static char string[0x100];\r
-\r
- va_start(ap,format);\r
-\r
- vsprintf(string,format,ap);\r
- printf("fd:%d,format:%s,string:%s\n",fd,format,string);\r
- va_end(ap);\r
+ !!DESCRIPTION!! varargs test
+ !!ORIGIN!!
+ !!LICENCE!! public domain
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+void chk0(char *format,...);
+void chk1(int fd,char *format,...);
+
+#if 0
+// old workaround for broken varargs
+
+void chk0(char *format,...){
+ __asm__ ("pha"); // save argument size
+ {
+//va_list ap;
+char *ap;
+char *_format;
+static char string[0x100];
+
+// va_start(ap,format);
+ __asm__ ("pla"); // restore argument size
+ __asm__ ("ldx #$00"); // clear hibyte of AX
+ ap=__AX__;
+ ap+=(char*)&format;
+ // get value of format
+ ap-=2;
+ _format=*((char**)ap);
+
+// vsprintf(string,format,ap);
+ vsprintf(&string[0],_format,ap);
+ printf("format:%s,string:%s\n",_format,string);
+// va_end(ap);
+
+ }
+}
+
+void chk1(int fd,char *format,...){
+ __asm__ ("pha"); // save argument size
+ {
+//va_list ap;
+char *ap;
+char *_format;
+int _fd;
+static char string[0x100];
+
+// va_start(ap,format);
+ __asm__ ("pla"); // restore argument size
+ __asm__ ("ldx #$00"); // clear hibyte of AX
+ ap=__AX__;
+ ap+=(char*)&format;
+ // get value of fd
+ ap-=2;
+ _fd=*((int*)ap);
+ // get value of format
+ ap-=2;
+ _format=*((char**)ap);
+
+// vsprintf(string,format,ap);
+ vsprintf(&string[0],_format,ap);
+ printf("fd:%d,format:%s,string:%s\n",_fd,_format,string);
+// va_end(ap);
+
+ }
}
-int main(int argc,char **argv) {\r
- printf("varargs test\n");\r
-\r
- printf("\nchk0/0:\n");chk0("chk0 %s","arg0");\r
- printf("\nchk0/1:\n");chk0("chk0 %s %s","arg0","arg1");\r
- printf("\nchk0/2:\n");chk0("chk0 %s %s %s","arg0","arg1","arg2");\r
-\r
- printf("\nchk1/0:\n");chk1(0xfd,"chk1 %s","arg0");\r
- printf("\nchk1/1:\n");chk1(0xfd,"chk1 %s %s","arg0","arg1");\r
- printf("\nchk1/2:\n");chk1(0xfd,"chk1 %s %s %s","arg0","arg1","arg2");\r
-\r
+#endif
+
+void chk0(char *format,...){
+va_list ap;
+static char string[0x100];
+ va_start(ap,format);
+ vsprintf(string,format,ap);
+ printf("format:%s,string:%s\n",format,string);
+ va_end(ap);
+}
+
+void chk1(int fd,char *format,...){
+va_list ap;
+static char string[0x100];
+
+ va_start(ap,format);
+
+ vsprintf(string,format,ap);
+ printf("fd:%d,format:%s,string:%s\n",fd,format,string);
+ va_end(ap);
+}
+
+int main(int argc,char **argv) {
+ printf("varargs test\n");
+
+ printf("\nchk0/0:\n");chk0("chk0 %s","arg0");
+ printf("\nchk0/1:\n");chk0("chk0 %s %s","arg0","arg1");
+ printf("\nchk0/2:\n");chk0("chk0 %s %s %s","arg0","arg1","arg2");
+
+ printf("\nchk1/0:\n");chk1(0xfd,"chk1 %s","arg0");
+ printf("\nchk1/1:\n");chk1(0xfd,"chk1 %s %s","arg0","arg1");
+ printf("\nchk1/2:\n");chk1(0xfd,"chk1 %s %s %s","arg0","arg1","arg2");
+
return 0;
-}\r
+}
-/* mul-test.c -- Test the multiplication operator. */\r
-\r
-#include <time.h>\r
-#include <conio.h>\r
-#include <ctype.h>\r
-\r
-\r
-/* Number of elements in the progress bar. Use a power of 2, to avoid the\r
-** multiplication (which is about to be tested).\r
-*/\r
-#define BAR_ELEMENTS 32U\r
-\r
-#if defined(__CBM__)\r
-static const unsigned char revers_bar[8] = {\r
- 0, 0, 0, 0, 0, 1, 1, 1\r
-};\r
-static const unsigned char small_bar[8] = {\r
- ' ', 0xa5, 0xb4, 0xb5, 0xa1, 0xb6, 0xaa, 0xa7\r
-};\r
-\r
-#elif defined(__ATARI__)\r
-#endif\r
-\r
-/* Screen co-ordinates for the progress meter */\r
-static unsigned char Width, Height;\r
-static unsigned char X, Y;\r
-\r
-static void ProgressMeter (unsigned Val)\r
-/* Print the progress bar. */\r
-{\r
- gotoxy (X, Y);\r
- cprintf (" %5lu/65536\r\n", (unsigned long) Val);\r
- revers (1);\r
- cclear (Val / (unsigned)(65536U / BAR_ELEMENTS));\r
-\r
-/* Commodore and Atari computers can show eight times greater precision. */\r
-#if defined(__CBM__)\r
- Val = (Val / (unsigned)(65536U / BAR_ELEMENTS / 8)) % 8;\r
- revers (revers_bar[Val]);\r
- cputc (small_bar[Val]);\r
-\r
-#elif defined(__ATARI__)\r
-#endif\r
-\r
- revers (0);\r
-}\r
-\r
-\r
-\r
-int main(void)\r
-{\r
- char C;\r
-\r
- /* Clock variables */\r
- clock_t Ticks;\r
- clock_t Wait;\r
- unsigned Days;\r
- unsigned Hours;\r
- unsigned Minu;\r
- unsigned Sec;\r
- unsigned Milli;\r
-\r
- /* Actual test variables */\r
- register unsigned lhs = 0;\r
- register unsigned rhs = 0;\r
- register unsigned res;\r
-\r
- /* Clear the screen, and output an informational message. */\r
- clrscr ();\r
- screensize (&Width, &Height);\r
- cprintf ("This program does an exhaustive test of\r\n"\r
- "the multiplication routine. It runs for\r\n"\r
- "several days; so, please wait very\r\n"\r
- "patiently (or, speed up your emulator).\r\n"\r
- "\n"\r
- "Progress: ");\r
-\r
- /* Remember the current position for the progress bar */\r
- X = wherex ();\r
- Y = wherey ();\r
-\r
- /* Mark the maximum limit of the bar. */\r
- revers (1);\r
- cputcxy (BAR_ELEMENTS, Y, ' ');\r
- cputcxy (BAR_ELEMENTS, Y + 1, ' ');\r
- revers (0);\r
-\r
-/* [Targets that have clock() will define CLOCKS_PER_SEC.] */\r
-#ifdef CLOCKS_PER_SEC\r
-\r
- /* Start timing the test. */\r
- Ticks = clock();\r
-#endif\r
-\r
- do {\r
-\r
- /* Update the progress bar */\r
- ProgressMeter (lhs);\r
-\r
-/* Enable this to test the progress-meter code.\r
-** (And, run emulators at their maximun speed.)\r
-*/\r
-#if 0\r
- continue;\r
-#endif\r
-\r
- /* Do one row of tests */\r
- res = 0;\r
- do {\r
- if (lhs * rhs != res) {\r
-#ifdef CLOCKS_PER_SEC\r
- Wait = clock ();\r
-#endif\r
- gotoxy (0, Y+3);\r
- cprintf ("Error on %u * %u: %u != %u\r\n", lhs, rhs, lhs * rhs, res);\r
- cprintf ("Press a key -- 'Q' to quit. ");\r
- cursor (1);\r
- C = toupper (cgetc ());\r
- cclearxy (0, Y+3, Width);\r
- cclearxy (0, Y+4, Width);\r
-\r
-#ifdef CLOCKS_PER_SEC\r
-\r
- /* Don't time the user's interaction. */\r
- Ticks += clock () - Wait;\r
-#endif\r
-\r
- if (C == 'Q') {\r
- goto Done;\r
- }\r
- }\r
-\r
- if (kbhit () && toupper (cgetc ()) == 'Q') {\r
- goto Done;\r
- }\r
-\r
- res += lhs;\r
- } while (++rhs != 0);\r
-\r
- } while (++lhs != 0);\r
-\r
-Done:\r
-#ifdef CLOCKS_PER_SEC\r
-\r
- /* Calculate the time used */\r
- Ticks = clock() - Ticks;\r
- Milli = ((Ticks % CLOCKS_PER_SEC) * 1000) / CLOCKS_PER_SEC;\r
- Sec = (unsigned) (Ticks / CLOCKS_PER_SEC);\r
- Minu = Sec / 60;\r
- Hours = Minu / 60;\r
- Days = Hours / 24;\r
- Hours %= 24;\r
- Minu %= 60;\r
- Sec %= 60;\r
-\r
- /* Print the time used */\r
- gotoxy (0, Y+3);\r
- cprintf ("Time used:\r\n"\r
- " %u days,\r\n"\r
- " %u hours,\r\n"\r
- " %u minutes,\r\n"\r
- " %u.%03u seconds.\n", Days, Hours, Minu, Sec, Milli);\r
-#endif\r
-\r
- cprintf ("\rTap a key, to exit. ");\r
- cgetc();\r
- return 0;\r
-}\r
-\r
-\r
+/* mul-test.c -- Test the multiplication operator. */
+
+#include <time.h>
+#include <conio.h>
+#include <ctype.h>
+
+
+/* Number of elements in the progress bar. Use a power of 2, to avoid the
+** multiplication (which is about to be tested).
+*/
+#define BAR_ELEMENTS 32U
+
+#if defined(__CBM__)
+static const unsigned char revers_bar[8] = {
+ 0, 0, 0, 0, 0, 1, 1, 1
+};
+static const unsigned char small_bar[8] = {
+ ' ', 0xa5, 0xb4, 0xb5, 0xa1, 0xb6, 0xaa, 0xa7
+};
+
+#elif defined(__ATARI__)
+#endif
+
+/* Screen co-ordinates for the progress meter */
+static unsigned char Width, Height;
+static unsigned char X, Y;
+
+static void ProgressMeter (unsigned Val)
+/* Print the progress bar. */
+{
+ gotoxy (X, Y);
+ cprintf (" %5lu/65536\r\n", (unsigned long) Val);
+ revers (1);
+ cclear (Val / (unsigned)(65536U / BAR_ELEMENTS));
+
+/* Commodore and Atari computers can show eight times greater precision. */
+#if defined(__CBM__)
+ Val = (Val / (unsigned)(65536U / BAR_ELEMENTS / 8)) % 8;
+ revers (revers_bar[Val]);
+ cputc (small_bar[Val]);
+
+#elif defined(__ATARI__)
+#endif
+
+ revers (0);
+}
+
+
+
+int main(void)
+{
+ char C;
+
+ /* Clock variables */
+ clock_t Ticks;
+ clock_t Wait;
+ unsigned Days;
+ unsigned Hours;
+ unsigned Minu;
+ unsigned Sec;
+ unsigned Milli;
+
+ /* Actual test variables */
+ register unsigned lhs = 0;
+ register unsigned rhs = 0;
+ register unsigned res;
+
+ /* Clear the screen, and output an informational message. */
+ clrscr ();
+ screensize (&Width, &Height);
+ cprintf ("This program does an exhaustive test of\r\n"
+ "the multiplication routine. It runs for\r\n"
+ "several days; so, please wait very\r\n"
+ "patiently (or, speed up your emulator).\r\n"
+ "\n"
+ "Progress: ");
+
+ /* Remember the current position for the progress bar */
+ X = wherex ();
+ Y = wherey ();
+
+ /* Mark the maximum limit of the bar. */
+ revers (1);
+ cputcxy (BAR_ELEMENTS, Y, ' ');
+ cputcxy (BAR_ELEMENTS, Y + 1, ' ');
+ revers (0);
+
+/* [Targets that have clock() will define CLOCKS_PER_SEC.] */
+#ifdef CLOCKS_PER_SEC
+
+ /* Start timing the test. */
+ Ticks = clock();
+#endif
+
+ do {
+
+ /* Update the progress bar */
+ ProgressMeter (lhs);
+
+/* Enable this to test the progress-meter code.
+** (And, run emulators at their maximun speed.)
+*/
+#if 0
+ continue;
+#endif
+
+ /* Do one row of tests */
+ res = 0;
+ do {
+ if (lhs * rhs != res) {
+#ifdef CLOCKS_PER_SEC
+ Wait = clock ();
+#endif
+ gotoxy (0, Y+3);
+ cprintf ("Error on %u * %u: %u != %u\r\n", lhs, rhs, lhs * rhs, res);
+ cprintf ("Press a key -- 'Q' to quit. ");
+ cursor (1);
+ C = toupper (cgetc ());
+ cclearxy (0, Y+3, Width);
+ cclearxy (0, Y+4, Width);
+
+#ifdef CLOCKS_PER_SEC
+
+ /* Don't time the user's interaction. */
+ Ticks += clock () - Wait;
+#endif
+
+ if (C == 'Q') {
+ goto Done;
+ }
+ }
+
+ if (kbhit () && toupper (cgetc ()) == 'Q') {
+ goto Done;
+ }
+
+ res += lhs;
+ } while (++rhs != 0);
+
+ } while (++lhs != 0);
+
+Done:
+#ifdef CLOCKS_PER_SEC
+
+ /* Calculate the time used */
+ Ticks = clock() - Ticks;
+ Milli = ((Ticks % CLOCKS_PER_SEC) * 1000) / CLOCKS_PER_SEC;
+ Sec = (unsigned) (Ticks / CLOCKS_PER_SEC);
+ Minu = Sec / 60;
+ Hours = Minu / 60;
+ Days = Hours / 24;
+ Hours %= 24;
+ Minu %= 60;
+ Sec %= 60;
+
+ /* Print the time used */
+ gotoxy (0, Y+3);
+ cprintf ("Time used:\r\n"
+ " %u days,\r\n"
+ " %u hours,\r\n"
+ " %u minutes,\r\n"
+ " %u.%03u seconds.\n", Days, Hours, Minu, Sec, Milli);
+#endif
+
+ cprintf ("\rTap a key, to exit. ");
+ cgetc();
+ return 0;
+}
+
+