diff --git a/asminc/ascii_charmap.inc b/asminc/ascii_charmap.inc new file mode 100644 index 000000000..ecbf2640f --- /dev/null +++ b/asminc/ascii_charmap.inc @@ -0,0 +1,287 @@ +;/*****************************************************************************/ +;/* */ +;/* ascii_charmap.inc */ +;/* */ +;/* No translations, encodings are stored as they were typed in the host. */ +;/* */ +;/* */ +;/* 2019-09-07, Greg King */ +;/* */ +;/* 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 must not be removed or altered from any source */ +;/* distribution. */ +;/* */ +;/*****************************************************************************/ + +;/* ASCII */ +.charmap $00, $00 +.charmap $01, $01 +.charmap $02, $02 +.charmap $03, $03 +.charmap $04, $04 +.charmap $05, $05 +.charmap $06, $06 +.charmap $07, $07 +.charmap $08, $08 +.charmap $09, $09 +.charmap $0A, $0A +.charmap $0B, $0B +.charmap $0C, $0C +.charmap $0D, $0D +.charmap $0E, $0E +.charmap $0F, $0F +.charmap $10, $10 +.charmap $11, $11 +.charmap $12, $12 +.charmap $13, $13 +.charmap $14, $14 +.charmap $15, $15 +.charmap $16, $16 +.charmap $17, $17 +.charmap $18, $18 +.charmap $19, $19 +.charmap $1A, $1A +.charmap $1B, $1B +.charmap $1C, $1C +.charmap $1D, $1D +.charmap $1E, $1E +.charmap $1F, $1F +.charmap $20, $20 +.charmap $21, $21 +.charmap $22, $22 +.charmap $23, $23 +.charmap $24, $24 +.charmap $25, $25 +.charmap $26, $26 +.charmap $27, $27 +.charmap $28, $28 +.charmap $29, $29 +.charmap $2A, $2A +.charmap $2B, $2B +.charmap $2C, $2C +.charmap $2D, $2D +.charmap $2E, $2E +.charmap $2F, $2F +.charmap $30, $30 +.charmap $31, $31 +.charmap $32, $32 +.charmap $33, $33 +.charmap $34, $34 +.charmap $35, $35 +.charmap $36, $36 +.charmap $37, $37 +.charmap $38, $38 +.charmap $39, $39 +.charmap $3A, $3A +.charmap $3B, $3B +.charmap $3C, $3C +.charmap $3D, $3D +.charmap $3E, $3E +.charmap $3F, $3F +.charmap $40, $40 +.charmap $41, $41 +.charmap $42, $42 +.charmap $43, $43 +.charmap $44, $44 +.charmap $45, $45 +.charmap $46, $46 +.charmap $47, $47 +.charmap $48, $48 +.charmap $49, $49 +.charmap $4A, $4A +.charmap $4B, $4B +.charmap $4C, $4C +.charmap $4D, $4D +.charmap $4E, $4E +.charmap $4F, $4F +.charmap $50, $50 +.charmap $51, $51 +.charmap $52, $52 +.charmap $53, $53 +.charmap $54, $54 +.charmap $55, $55 +.charmap $56, $56 +.charmap $57, $57 +.charmap $58, $58 +.charmap $59, $59 +.charmap $5A, $5A +.charmap $5B, $5B +.charmap $5C, $5C +.charmap $5D, $5D +.charmap $5E, $5E +.charmap $5F, $5F +.charmap $60, $60 +.charmap $61, $61 +.charmap $62, $62 +.charmap $63, $63 +.charmap $64, $64 +.charmap $65, $65 +.charmap $66, $66 +.charmap $67, $67 +.charmap $68, $68 +.charmap $69, $69 +.charmap $6A, $6A +.charmap $6B, $6B +.charmap $6C, $6C +.charmap $6D, $6D +.charmap $6E, $6E +.charmap $6F, $6F +.charmap $70, $70 +.charmap $71, $71 +.charmap $72, $72 +.charmap $73, $73 +.charmap $74, $74 +.charmap $75, $75 +.charmap $76, $76 +.charmap $77, $77 +.charmap $78, $78 +.charmap $79, $79 +.charmap $7A, $7A +.charmap $7B, $7B +.charmap $7C, $7C +.charmap $7D, $7D +.charmap $7E, $7E +.charmap $7F, $7F + +;/* beyond ASCII */ +.charmap $80, $80 +.charmap $81, $81 +.charmap $82, $82 +.charmap $83, $83 +.charmap $84, $84 +.charmap $85, $85 +.charmap $86, $86 +.charmap $87, $87 +.charmap $88, $88 +.charmap $89, $89 +.charmap $8A, $8A +.charmap $8B, $8B +.charmap $8C, $8C +.charmap $8D, $8D +.charmap $8E, $8E +.charmap $8F, $8F +.charmap $90, $90 +.charmap $91, $91 +.charmap $92, $92 +.charmap $93, $93 +.charmap $94, $94 +.charmap $95, $95 +.charmap $96, $96 +.charmap $97, $97 +.charmap $98, $98 +.charmap $99, $99 +.charmap $9A, $9A +.charmap $9B, $9B +.charmap $9C, $9C +.charmap $9D, $9D +.charmap $9E, $9E +.charmap $9F, $9F +.charmap $A0, $A0 +.charmap $A1, $A1 +.charmap $A2, $A2 +.charmap $A3, $A3 +.charmap $A4, $A4 +.charmap $A5, $A5 +.charmap $A6, $A6 +.charmap $A7, $A7 +.charmap $A8, $A8 +.charmap $A9, $A9 +.charmap $AA, $AA +.charmap $AB, $AB +.charmap $AC, $AC +.charmap $AD, $AD +.charmap $AE, $AE +.charmap $AF, $AF +.charmap $B0, $B0 +.charmap $B1, $B1 +.charmap $B2, $B2 +.charmap $B3, $B3 +.charmap $B4, $B4 +.charmap $B5, $B5 +.charmap $B6, $B6 +.charmap $B7, $B7 +.charmap $B8, $B8 +.charmap $B9, $B9 +.charmap $BA, $BA +.charmap $BB, $BB +.charmap $BC, $BC +.charmap $BD, $BD +.charmap $BE, $BE +.charmap $BF, $BF +.charmap $C0, $C0 +.charmap $C1, $C1 +.charmap $C2, $C2 +.charmap $C3, $C3 +.charmap $C4, $C4 +.charmap $C5, $C5 +.charmap $C6, $C6 +.charmap $C7, $C7 +.charmap $C8, $C8 +.charmap $C9, $C9 +.charmap $CA, $CA +.charmap $CB, $CB +.charmap $CC, $CC +.charmap $CD, $CD +.charmap $CE, $CE +.charmap $CF, $CF +.charmap $D0, $D0 +.charmap $D1, $D1 +.charmap $D2, $D2 +.charmap $D3, $D3 +.charmap $D4, $D4 +.charmap $D5, $D5 +.charmap $D6, $D6 +.charmap $D7, $D7 +.charmap $D8, $D8 +.charmap $D9, $D9 +.charmap $DA, $DA +.charmap $DB, $DB +.charmap $DC, $DC +.charmap $DD, $DD +.charmap $DE, $DE +.charmap $DF, $DF +.charmap $E0, $E0 +.charmap $E1, $E1 +.charmap $E2, $E2 +.charmap $E3, $E3 +.charmap $E4, $E4 +.charmap $E5, $E5 +.charmap $E6, $E6 +.charmap $E7, $E7 +.charmap $E8, $E8 +.charmap $E9, $E9 +.charmap $EA, $EA +.charmap $EB, $EB +.charmap $EC, $EC +.charmap $ED, $ED +.charmap $EE, $EE +.charmap $EF, $EF +.charmap $F0, $F0 +.charmap $F1, $F1 +.charmap $F2, $F2 +.charmap $F3, $F3 +.charmap $F4, $F4 +.charmap $F5, $F5 +.charmap $F6, $F6 +.charmap $F7, $F7 +.charmap $F8, $F8 +.charmap $F9, $F9 +.charmap $FA, $FA +.charmap $FB, $FB +.charmap $FC, $FC +.charmap $FD, $FD +.charmap $FE, $FE +.charmap $FF, $FF diff --git a/asminc/atari_atascii_charmap.inc b/asminc/atari_atascii_charmap.inc new file mode 100644 index 000000000..7c6b5e542 --- /dev/null +++ b/asminc/atari_atascii_charmap.inc @@ -0,0 +1,301 @@ +;/*****************************************************************************/ +;/* */ +;/* atari_atascii_charmap.inc */ +;/* */ +;/* Atari system standard string mapping ISO-8859-1 -> AtASCII */ +;/* */ +;/* */ +;/* */ +;/* C 2016 Christian Krueger */ +;/* */ +;/* */ +;/* 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. */ +;/* */ +;/*****************************************************************************/ + +.charmap $00, $00 +.charmap $01, $01 +.charmap $02, $02 +.charmap $03, $03 +.charmap $04, $04 +.charmap $05, $05 +.charmap $06, $06 +.charmap $07, $FD +.charmap $08, $08 +.charmap $09, $7F +.charmap $0A, $9B +.charmap $0B, $0B +.charmap $0C, $7D +.charmap $0D, $0D +.charmap $0E, $0E +.charmap $0F, $0F + +.charmap $10, $10 +.charmap $11, $11 +.charmap $12, $12 +.charmap $13, $13 +.charmap $14, $14 +.charmap $15, $15 +.charmap $16, $16 +.charmap $17, $17 +.charmap $18, $18 +.charmap $19, $19 +.charmap $1A, $1A +.charmap $1B, $1B +.charmap $1C, $1C +.charmap $1D, $1D +.charmap $1E, $1E +.charmap $1F, $1F + +.charmap $20, $20 +.charmap $21, $21 +.charmap $22, $22 +.charmap $23, $23 +.charmap $24, $24 +.charmap $25, $25 +.charmap $26, $26 +.charmap $27, $27 +.charmap $28, $28 +.charmap $29, $29 +.charmap $2A, $2A +.charmap $2B, $2B +.charmap $2C, $2C +.charmap $2D, $2D +.charmap $2E, $2E +.charmap $2F, $2F + +.charmap $30, $30 +.charmap $31, $31 +.charmap $32, $32 +.charmap $33, $33 +.charmap $34, $34 +.charmap $35, $35 +.charmap $36, $36 +.charmap $37, $37 +.charmap $38, $38 +.charmap $39, $39 +.charmap $3A, $3A +.charmap $3B, $3B +.charmap $3C, $3C +.charmap $3D, $3D +.charmap $3E, $3E +.charmap $3F, $3F + +.charmap $40, $40 +.charmap $41, $41 +.charmap $42, $42 +.charmap $43, $43 +.charmap $44, $44 +.charmap $45, $45 +.charmap $46, $46 +.charmap $47, $47 +.charmap $48, $48 +.charmap $49, $49 +.charmap $4A, $4A +.charmap $4B, $4B +.charmap $4C, $4C +.charmap $4D, $4D +.charmap $4E, $4E +.charmap $4F, $4F + +.charmap $50, $50 +.charmap $51, $51 +.charmap $52, $52 +.charmap $53, $53 +.charmap $54, $54 +.charmap $55, $55 +.charmap $56, $56 +.charmap $57, $57 +.charmap $58, $58 +.charmap $59, $59 +.charmap $5A, $5A +.charmap $5B, $5B +.charmap $5C, $5C +.charmap $5D, $5D +.charmap $5E, $5E +.charmap $5F, $5F + +.charmap $60, $60 +.charmap $61, $61 +.charmap $62, $62 +.charmap $63, $63 +.charmap $64, $64 +.charmap $65, $65 +.charmap $66, $66 +.charmap $67, $67 +.charmap $68, $68 +.charmap $69, $69 +.charmap $6A, $6A +.charmap $6B, $6B +.charmap $6C, $6C +.charmap $6D, $6D +.charmap $6E, $6E +.charmap $6F, $6F + +.charmap $70, $70 +.charmap $71, $71 +.charmap $72, $72 +.charmap $73, $73 +.charmap $74, $74 +.charmap $75, $75 +.charmap $76, $76 +.charmap $77, $77 +.charmap $78, $78 +.charmap $79, $79 +.charmap $7A, $7A +.charmap $7B, $7B +.charmap $7C, $7C +.charmap $7D, $7D +.charmap $7E, $7E +.charmap $7F, $7F + +.charmap $80, $80 +.charmap $81, $81 +.charmap $82, $82 +.charmap $83, $83 +.charmap $84, $84 +.charmap $85, $85 +.charmap $86, $86 +.charmap $87, $87 +.charmap $88, $88 +.charmap $89, $89 +.charmap $8A, $8A +.charmap $8B, $8B +.charmap $8C, $8C +.charmap $8D, $8D +.charmap $8E, $8E +.charmap $8F, $8F + +.charmap $90, $90 +.charmap $91, $91 +.charmap $92, $92 +.charmap $93, $93 +.charmap $94, $94 +.charmap $95, $95 +.charmap $96, $96 +.charmap $97, $97 +.charmap $98, $98 +.charmap $99, $99 +.charmap $9A, $9A +.charmap $9B, $9B +.charmap $9C, $9C +.charmap $9D, $9D +.charmap $9E, $9E +.charmap $9F, $9F + +.charmap $A0, $A0 +.charmap $A1, $A1 +.charmap $A2, $A2 +.charmap $A3, $A3 +.charmap $A4, $A4 +.charmap $A5, $A5 +.charmap $A6, $A6 +.charmap $A7, $A7 +.charmap $A8, $A8 +.charmap $A9, $A9 +.charmap $AA, $AA +.charmap $AB, $AB +.charmap $AC, $AC +.charmap $AD, $AD +.charmap $AE, $AE +.charmap $AF, $AF + +.charmap $B0, $B0 +.charmap $B1, $B1 +.charmap $B2, $B2 +.charmap $B3, $B3 +.charmap $B4, $B4 +.charmap $B5, $B5 +.charmap $B6, $B6 +.charmap $B7, $B7 +.charmap $B8, $B8 +.charmap $B9, $B9 +.charmap $BA, $BA +.charmap $BB, $BB +.charmap $BC, $BC +.charmap $BD, $BD +.charmap $BE, $BE +.charmap $BF, $BF + +.charmap $C0, $C0 +.charmap $C1, $C1 +.charmap $C2, $C2 +.charmap $C3, $C3 +.charmap $C4, $C4 +.charmap $C5, $C5 +.charmap $C6, $C6 +.charmap $C7, $C7 +.charmap $C8, $C8 +.charmap $C9, $C9 +.charmap $CA, $CA +.charmap $CB, $CB +.charmap $CC, $CC +.charmap $CD, $CD +.charmap $CE, $CE +.charmap $CF, $CF + +.charmap $D0, $D0 +.charmap $D1, $D1 +.charmap $D2, $D2 +.charmap $D3, $D3 +.charmap $D4, $D4 +.charmap $D5, $D5 +.charmap $D6, $D6 +.charmap $D7, $D7 +.charmap $D8, $D8 +.charmap $D9, $D9 +.charmap $DA, $DA +.charmap $DB, $DB +.charmap $DC, $DC +.charmap $DD, $DD +.charmap $DE, $DE +.charmap $DF, $DF + +.charmap $E0, $E0 +.charmap $E1, $E1 +.charmap $E2, $E2 +.charmap $E3, $E3 +.charmap $E4, $E4 +.charmap $E5, $E5 +.charmap $E6, $E6 +.charmap $E7, $E7 +.charmap $E8, $E8 +.charmap $E9, $E9 +.charmap $EA, $EA +.charmap $EB, $EB +.charmap $EC, $EC +.charmap $ED, $ED +.charmap $EE, $EE +.charmap $EF, $EF + +.charmap $F0, $F0 +.charmap $F1, $F1 +.charmap $F2, $F2 +.charmap $F3, $F3 +.charmap $F4, $F4 +.charmap $F5, $F5 +.charmap $F6, $F6 +.charmap $F7, $F7 +.charmap $F8, $F8 +.charmap $F9, $F9 +.charmap $FA, $FA +.charmap $FB, $FB +.charmap $FC, $FC +.charmap $FD, $FD +.charmap $FE, $FE +.charmap $FF, $FF diff --git a/asminc/atari_screen_charmap.inc b/asminc/atari_screen_charmap.inc new file mode 100644 index 000000000..193ea0685 --- /dev/null +++ b/asminc/atari_screen_charmap.inc @@ -0,0 +1,303 @@ +;/*****************************************************************************/ +;/* */ +;/* atari_screen_charmap.inc */ +;/* */ +;/* Atari system internal string mapping ISO-8859-1 -> Internal/Screen-Code */ +;/* */ +;/* */ +;/* */ +;/* C 2016 Christian Krueger */ +;/* */ +;/* */ +;/* 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. */ +;/* */ +;/*****************************************************************************/ + +.charmap $00, $40 +.charmap $01, $41 +.charmap $02, $42 +.charmap $03, $43 +.charmap $04, $44 +.charmap $05, $45 +.charmap $06, $46 +.charmap $07, $FD +.charmap $08, $48 +.charmap $09, $7F +.charmap $0A, $DB +.charmap $0B, $4B +.charmap $0C, $7D +.charmap $0D, $4D +.charmap $0E, $4E +.charmap $0F, $4F + +.charmap $10, $50 +.charmap $11, $51 +.charmap $12, $52 +.charmap $13, $53 +.charmap $14, $54 +.charmap $15, $55 +.charmap $16, $56 +.charmap $17, $57 +.charmap $18, $58 +.charmap $19, $59 +.charmap $1A, $5A +.charmap $1B, $5B +.charmap $1C, $5C +.charmap $1D, $5D +.charmap $1E, $5E +.charmap $1F, $5F + +.charmap $20, $00 + +.charmap $21, $01 +.charmap $22, $02 +.charmap $23, $03 +.charmap $24, $04 +.charmap $25, $05 +.charmap $26, $06 +.charmap $27, $07 +.charmap $28, $08 +.charmap $29, $09 +.charmap $2A, $0A +.charmap $2B, $0B +.charmap $2C, $0C +.charmap $2D, $0D +.charmap $2E, $0E +.charmap $2F, $0F + +.charmap $30, $10 +.charmap $31, $11 +.charmap $32, $12 +.charmap $33, $13 +.charmap $34, $14 +.charmap $35, $15 +.charmap $36, $16 +.charmap $37, $17 +.charmap $38, $18 +.charmap $39, $19 +.charmap $3A, $1A +.charmap $3B, $1B +.charmap $3C, $1C +.charmap $3D, $1D +.charmap $3E, $1E +.charmap $3F, $1F + +.charmap $40, $20 +.charmap $41, $21 +.charmap $42, $22 +.charmap $43, $23 +.charmap $44, $24 +.charmap $45, $25 +.charmap $46, $26 +.charmap $47, $27 +.charmap $48, $28 +.charmap $49, $29 +.charmap $4A, $2A +.charmap $4B, $2B +.charmap $4C, $2C +.charmap $4D, $2D +.charmap $4E, $2E +.charmap $4F, $2F + +.charmap $50, $30 +.charmap $51, $31 +.charmap $52, $32 +.charmap $53, $33 +.charmap $54, $34 +.charmap $55, $35 +.charmap $56, $36 +.charmap $57, $37 +.charmap $58, $38 +.charmap $59, $39 +.charmap $5A, $3A +.charmap $5B, $3B +.charmap $5C, $3C +.charmap $5D, $3D +.charmap $5E, $3E +.charmap $5F, $3F + +.charmap $60, $60 +.charmap $61, $61 +.charmap $62, $62 +.charmap $63, $63 +.charmap $64, $64 +.charmap $65, $65 +.charmap $66, $66 +.charmap $67, $67 +.charmap $68, $68 +.charmap $69, $69 +.charmap $6A, $6A +.charmap $6B, $6B +.charmap $6C, $6C +.charmap $6D, $6D +.charmap $6E, $6E +.charmap $6F, $6F + +.charmap $70, $70 +.charmap $71, $71 +.charmap $72, $72 +.charmap $73, $73 +.charmap $74, $74 +.charmap $75, $75 +.charmap $76, $76 +.charmap $77, $77 +.charmap $78, $78 +.charmap $79, $79 +.charmap $7A, $7A +.charmap $7B, $7B +.charmap $7C, $7C +.charmap $7D, $7D +.charmap $7E, $7E +.charmap $7F, $7F + +.charmap $80, $C0 +.charmap $81, $C1 +.charmap $82, $C2 +.charmap $83, $C3 +.charmap $84, $C4 +.charmap $85, $C5 +.charmap $86, $C6 +.charmap $87, $C7 +.charmap $88, $C8 +.charmap $89, $C9 +.charmap $8A, $CA +.charmap $8B, $CB +.charmap $8C, $CC +.charmap $8D, $CD +.charmap $8E, $CE +.charmap $8F, $CF + +.charmap $90, $D0 +.charmap $91, $D1 +.charmap $92, $D2 +.charmap $93, $D3 +.charmap $94, $D4 +.charmap $95, $D5 +.charmap $96, $D6 +.charmap $97, $D7 +.charmap $98, $D8 +.charmap $99, $D9 +.charmap $9A, $DA +.charmap $9B, $DB +.charmap $9C, $DC +.charmap $9D, $DD +.charmap $9E, $DE +.charmap $9F, $DF + +.charmap $A0, $80 +.charmap $A1, $81 +.charmap $A2, $82 +.charmap $A3, $83 +.charmap $A4, $84 +.charmap $A5, $85 +.charmap $A6, $86 +.charmap $A7, $87 +.charmap $A8, $88 +.charmap $A9, $89 +.charmap $AA, $8A +.charmap $AB, $8B +.charmap $AC, $8C +.charmap $AD, $8D +.charmap $AE, $8E +.charmap $AF, $8F + +.charmap $B0, $90 +.charmap $B1, $91 +.charmap $B2, $92 +.charmap $B3, $93 +.charmap $B4, $94 +.charmap $B5, $95 +.charmap $B6, $96 +.charmap $B7, $97 +.charmap $B8, $98 +.charmap $B9, $99 +.charmap $BA, $9A +.charmap $BB, $9B +.charmap $BC, $9C +.charmap $BD, $9D +.charmap $BE, $9E +.charmap $BF, $9F + +.charmap $C0, $A0 +.charmap $C1, $A1 +.charmap $C2, $A2 +.charmap $C3, $A3 +.charmap $C4, $A4 +.charmap $C5, $A5 +.charmap $C6, $A6 +.charmap $C7, $A7 +.charmap $C8, $A8 +.charmap $C9, $A9 +.charmap $CA, $AA +.charmap $CB, $AB +.charmap $CC, $AC +.charmap $CD, $AD +.charmap $CE, $AE +.charmap $CF, $AF + +.charmap $D0, $B0 +.charmap $D1, $B1 +.charmap $D2, $B2 +.charmap $D3, $B3 +.charmap $D4, $B4 +.charmap $D5, $B5 +.charmap $D6, $B6 +.charmap $D7, $B7 +.charmap $D8, $B8 +.charmap $D9, $B9 +.charmap $DA, $BA +.charmap $DB, $BB +.charmap $DC, $BC +.charmap $DD, $BD +.charmap $DE, $BE +.charmap $DF, $BF + +.charmap $E0, $E0 +.charmap $E1, $E1 +.charmap $E2, $E2 +.charmap $E3, $E3 +.charmap $E4, $E4 +.charmap $E5, $E5 +.charmap $E6, $E6 +.charmap $E7, $E7 +.charmap $E8, $E8 +.charmap $E9, $E9 +.charmap $EA, $EA +.charmap $EB, $EB +.charmap $EC, $EC +.charmap $ED, $ED +.charmap $EE, $EE +.charmap $EF, $EF + +.charmap $F0, $F0 +.charmap $F1, $F1 +.charmap $F2, $F2 +.charmap $F3, $F3 +.charmap $F4, $F4 +.charmap $F5, $F5 +.charmap $F6, $F6 +.charmap $F7, $F7 +.charmap $F8, $F8 +.charmap $F9, $F9 +.charmap $FA, $FA +.charmap $FB, $FB +.charmap $FC, $FC +.charmap $FD, $FD +.charmap $FE, $FE +.charmap $FF, $FF + diff --git a/asminc/cbm_petscii_charmap.inc b/asminc/cbm_petscii_charmap.inc new file mode 100644 index 000000000..525bffb01 --- /dev/null +++ b/asminc/cbm_petscii_charmap.inc @@ -0,0 +1,291 @@ +;/*****************************************************************************/ +;/* */ +;/* cbm_petscii_charmap.inc */ +;/* */ +;/* CBM system standard string mapping ISO-8859-1 -> PetSCII */ +;/* */ +;/* */ +;/* 2019-03-10, Greg King */ +;/* */ +;/* 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 must not be removed or altered from any source */ +;/* distribution. */ +;/* */ +;/*****************************************************************************/ + +.charmap $00, $00 +.charmap $01, $01 +.charmap $02, $02 +.charmap $03, $03 +.charmap $04, $04 +.charmap $05, $05 +.charmap $06, $06 +.charmap $07, $07 +.charmap $08, $14 +.charmap $09, $09 +.charmap $0A, $0D +.charmap $0B, $11 +.charmap $0C, $93 +.charmap $0D, $0A +.charmap $0E, $0E +.charmap $0F, $0F +.charmap $10, $10 +.charmap $11, $0B +.charmap $12, $12 +.charmap $13, $13 +.charmap $14, $08 +.charmap $15, $15 +.charmap $16, $16 +.charmap $17, $17 +.charmap $18, $18 +.charmap $19, $19 +.charmap $1A, $1A +.charmap $1B, $1B +.charmap $1C, $1C +.charmap $1D, $1D +.charmap $1E, $1E +.charmap $1F, $1F + +.charmap $20, $20 +.charmap $21, $21 +.charmap $22, $22 +.charmap $23, $23 +.charmap $24, $24 +.charmap $25, $25 +.charmap $26, $26 +.charmap $27, $27 +.charmap $28, $28 +.charmap $29, $29 +.charmap $2A, $2A +.charmap $2B, $2B +.charmap $2C, $2C +.charmap $2D, $2D +.charmap $2E, $2E +.charmap $2F, $2F +.charmap $30, $30 +.charmap $31, $31 +.charmap $32, $32 +.charmap $33, $33 +.charmap $34, $34 +.charmap $35, $35 +.charmap $36, $36 +.charmap $37, $37 +.charmap $38, $38 +.charmap $39, $39 +.charmap $3A, $3A +.charmap $3B, $3B +.charmap $3C, $3C +.charmap $3D, $3D +.charmap $3E, $3E +.charmap $3F, $3F + +.charmap $40, $40 +.charmap $41, $C1 +.charmap $42, $C2 +.charmap $43, $C3 +.charmap $44, $C4 +.charmap $45, $C5 +.charmap $46, $C6 +.charmap $47, $C7 +.charmap $48, $C8 +.charmap $49, $C9 +.charmap $4A, $CA +.charmap $4B, $CB +.charmap $4C, $CC +.charmap $4D, $CD +.charmap $4E, $CE +.charmap $4F, $CF +.charmap $50, $D0 +.charmap $51, $D1 +.charmap $52, $D2 +.charmap $53, $D3 +.charmap $54, $D4 +.charmap $55, $D5 +.charmap $56, $D6 +.charmap $57, $D7 +.charmap $58, $D8 +.charmap $59, $D9 +.charmap $5A, $DA +.charmap $5B, $5B +.charmap $5C, $BF +.charmap $5D, $5D +.charmap $5E, $5E +.charmap $5F, $A4 + +.charmap $60, $AD +.charmap $61, $41 +.charmap $62, $42 +.charmap $63, $43 +.charmap $64, $44 +.charmap $65, $45 +.charmap $66, $46 +.charmap $67, $47 +.charmap $68, $48 +.charmap $69, $49 +.charmap $6A, $4A +.charmap $6B, $4B +.charmap $6C, $4C +.charmap $6D, $4D +.charmap $6E, $4E +.charmap $6F, $4F +.charmap $70, $50 +.charmap $71, $51 +.charmap $72, $52 +.charmap $73, $53 +.charmap $74, $54 +.charmap $75, $55 +.charmap $76, $56 +.charmap $77, $57 +.charmap $78, $58 +.charmap $79, $59 +.charmap $7A, $5A +.charmap $7B, $B3 +.charmap $7C, $DD +.charmap $7D, $AB +.charmap $7E, $B1 +.charmap $7F, $DF + +.charmap $80, $80 +.charmap $81, $81 +.charmap $82, $82 +.charmap $83, $83 +.charmap $84, $84 +.charmap $85, $85 +.charmap $86, $86 +.charmap $87, $87 +.charmap $88, $88 +.charmap $89, $89 +.charmap $8A, $8A +.charmap $8B, $8B +.charmap $8C, $8C +.charmap $8D, $8D +.charmap $8E, $8E +.charmap $8F, $8F +.charmap $90, $90 +.charmap $91, $91 +.charmap $92, $92 +.charmap $93, $0C +.charmap $94, $94 +.charmap $95, $95 +.charmap $96, $96 +.charmap $97, $97 +.charmap $98, $98 +.charmap $99, $99 +.charmap $9A, $9A +.charmap $9B, $9B +.charmap $9C, $9C +.charmap $9D, $9D +.charmap $9E, $9E +.charmap $9F, $9F + +.charmap $A0, $A0 +.charmap $A1, $A1 +.charmap $A2, $A2 +.charmap $A3, $A3 +.charmap $A4, $A4 +.charmap $A5, $A5 +.charmap $A6, $A6 +.charmap $A7, $A7 +.charmap $A8, $A8 +.charmap $A9, $A9 +.charmap $AA, $AA +.charmap $AB, $AB +.charmap $AC, $AC +.charmap $AD, $AD +.charmap $AE, $AE +.charmap $AF, $AF +.charmap $B0, $B0 +.charmap $B1, $B1 +.charmap $B2, $B2 +.charmap $B3, $B3 +.charmap $B4, $B4 +.charmap $B5, $B5 +.charmap $B6, $B6 +.charmap $B7, $B7 +.charmap $B8, $B8 +.charmap $B9, $B9 +.charmap $BA, $BA +.charmap $BB, $BB +.charmap $BC, $BC +.charmap $BD, $BD +.charmap $BE, $BE +.charmap $BF, $BF + +.charmap $C0, $60 +.charmap $C1, $61 +.charmap $C2, $62 +.charmap $C3, $63 +.charmap $C4, $64 +.charmap $C5, $65 +.charmap $C6, $66 +.charmap $C7, $67 +.charmap $C8, $68 +.charmap $C9, $69 +.charmap $CA, $6A +.charmap $CB, $6B +.charmap $CC, $6C +.charmap $CD, $6D +.charmap $CE, $6E +.charmap $CF, $6F +.charmap $D0, $70 +.charmap $D1, $71 +.charmap $D2, $72 +.charmap $D3, $73 +.charmap $D4, $74 +.charmap $D5, $75 +.charmap $D6, $76 +.charmap $D7, $77 +.charmap $D8, $78 +.charmap $D9, $79 +.charmap $DA, $7A +.charmap $DB, $7B +.charmap $DC, $7C +.charmap $DD, $7D +.charmap $DE, $7E +.charmap $DF, $7F + +.charmap $E0, $E0 +.charmap $E1, $E1 +.charmap $E2, $E2 +.charmap $E3, $E3 +.charmap $E4, $E4 +.charmap $E5, $E5 +.charmap $E6, $E6 +.charmap $E7, $E7 +.charmap $E8, $E8 +.charmap $E9, $E9 +.charmap $EA, $EA +.charmap $EB, $EB +.charmap $EC, $EC +.charmap $ED, $ED +.charmap $EE, $EE +.charmap $EF, $EF +.charmap $F0, $F0 +.charmap $F1, $F1 +.charmap $F2, $F2 +.charmap $F3, $F3 +.charmap $F4, $F4 +.charmap $F5, $F5 +.charmap $F6, $F6 +.charmap $F7, $F7 +.charmap $F8, $F8 +.charmap $F9, $F9 +.charmap $FA, $FA +.charmap $FB, $FB +.charmap $FC, $FC +.charmap $FD, $FD +.charmap $FE, $FE +.charmap $FF, $FF diff --git a/asminc/cbm_screen_charmap.inc b/asminc/cbm_screen_charmap.inc new file mode 100644 index 000000000..12d02553d --- /dev/null +++ b/asminc/cbm_screen_charmap.inc @@ -0,0 +1,305 @@ +;/*****************************************************************************/ +;/* */ +;/* cbm_screen_charmap.inc */ +;/* */ +;/* c Copyright 2019, Gerhard W. Gruber (sparhawk@gmx.at) */ +;/* */ +;/* When using CBM mode, this include converts character literals */ +;/* from ASCII to screen-code mapping, so you can write directly */ +;/* to the screen memory. */ +;/* */ +;/* If this include is used, no additional macros are needed. */ +;/* */ +;/*****************************************************************************/ + +; Char $00 -> c + 128 +.charmap $00, $80 + +; Char $01 ... $1A -> c + 128 + 64 control alphabet +.charmap $01, $C1 +.charmap $02, $C2 +.charmap $03, $C3 +.charmap $04, $C4 +.charmap $05, $C5 +.charmap $06, $C6 +.charmap $07, $C7 +.charmap $08, $C8 +.charmap $09, $C9 +.charmap $0A, $CA +.charmap $0B, $CB +.charmap $0C, $CC +.charmap $0D, $CD +.charmap $0E, $CE +.charmap $0F, $CF +.charmap $10, $D0 +.charmap $11, $D1 +.charmap $12, $D2 +.charmap $13, $D3 +.charmap $14, $D4 +.charmap $15, $D5 +.charmap $16, $D6 +.charmap $17, $D7 +.charmap $18, $D8 +.charmap $19, $D9 +.charmap $1A, $DA + +; Char $1B ... $1F -> c + 128 +.charmap $1B, $9B +.charmap $1C, $9C +.charmap $1D, $9D +.charmap $1E, $9E +.charmap $1F, $9F + +; Char $20 ... $3F -> c +.charmap $20, $20 +.charmap $21, $21 +.charmap $22, $22 +.charmap $23, $23 +.charmap $24, $24 +.charmap $25, $25 +.charmap $26, $26 +.charmap $27, $27 +.charmap $28, $28 +.charmap $29, $29 +.charmap $2A, $2A +.charmap $2B, $2B +.charmap $2C, $2C +.charmap $2D, $2D +.charmap $2E, $2E +.charmap $2F, $2F +.charmap $30, $30 +.charmap $31, $31 +.charmap $32, $32 +.charmap $33, $33 +.charmap $34, $34 +.charmap $35, $35 +.charmap $36, $36 +.charmap $37, $37 +.charmap $38, $38 +.charmap $39, $39 +.charmap $3A, $3A +.charmap $3B, $3B +.charmap $3C, $3C +.charmap $3D, $3D +.charmap $3E, $3E +.charmap $3F, $3F + +; Char $40 -> c - 64 +.charmap $40, $00 + +; Char $41 ... $5A -> c upper-case alphabet +.charmap $41, $41 +.charmap $42, $42 +.charmap $43, $43 +.charmap $44, $44 +.charmap $45, $45 +.charmap $46, $46 +.charmap $47, $47 +.charmap $48, $48 +.charmap $49, $49 +.charmap $4A, $4A +.charmap $4B, $4B +.charmap $4C, $4C +.charmap $4D, $4D +.charmap $4E, $4E +.charmap $4F, $4F +.charmap $50, $50 +.charmap $51, $51 +.charmap $52, $52 +.charmap $53, $53 +.charmap $54, $54 +.charmap $55, $55 +.charmap $56, $56 +.charmap $57, $57 +.charmap $58, $58 +.charmap $59, $59 +.charmap $5A, $5A + +; Char $5B ... $5F -> c - 64 +.charmap $5B, $1B +.charmap $5C, $1C +.charmap $5D, $1D +.charmap $5E, $1E +.charmap $5F, $1F + +; Char $60 -> c - 32 +.charmap $60, $40 + +; Char $61 ... $7A -> c - 32 - 64 lower-case alphabet +.charmap $61, $01 +.charmap $62, $02 +.charmap $63, $03 +.charmap $64, $04 +.charmap $65, $05 +.charmap $66, $06 +.charmap $67, $07 +.charmap $68, $08 +.charmap $69, $09 +.charmap $6A, $0A +.charmap $6B, $0B +.charmap $6C, $0C +.charmap $6D, $0D +.charmap $6E, $0E +.charmap $6F, $0F +.charmap $70, $10 +.charmap $71, $11 +.charmap $72, $12 +.charmap $73, $13 +.charmap $74, $14 +.charmap $75, $15 +.charmap $76, $16 +.charmap $77, $17 +.charmap $78, $18 +.charmap $79, $19 +.charmap $7A, $1A + +; Char $7B ... $7F -> c - 32 +.charmap $7B, $5B +.charmap $7C, $5C +.charmap $7D, $5D +.charmap $7E, $5E +.charmap $7F, $5F + +; Char $80 -> c + 64 +.charmap $80, $C0 + +; Char $81 ... $9A -> c control alphabet +.charmap $81, $81 +.charmap $82, $82 +.charmap $83, $83 +.charmap $84, $84 +.charmap $85, $85 +.charmap $86, $86 +.charmap $87, $87 +.charmap $88, $88 +.charmap $89, $89 +.charmap $8A, $8A +.charmap $8B, $8B +.charmap $8C, $8C +.charmap $8D, $8D +.charmap $8E, $8E +.charmap $8F, $8F +.charmap $90, $90 +.charmap $91, $91 +.charmap $92, $92 +.charmap $93, $93 +.charmap $94, $94 +.charmap $95, $95 +.charmap $96, $96 +.charmap $97, $97 +.charmap $98, $98 +.charmap $99, $99 +.charmap $9A, $9A + +; Char $9B ... $9F -> c + 64 +.charmap $9B, $DB +.charmap $9C, $DC +.charmap $9D, $DD +.charmap $9E, $DE +.charmap $9F, $DF + +; Char $A0 ... $BF -> c - 64 +.charmap $A0, $60 +.charmap $A1, $61 +.charmap $A2, $62 +.charmap $A3, $63 +.charmap $A4, $64 +.charmap $A5, $65 +.charmap $A6, $66 +.charmap $A7, $67 +.charmap $A8, $68 +.charmap $A9, $69 +.charmap $AA, $6A +.charmap $AB, $6B +.charmap $AC, $6C +.charmap $AD, $6D +.charmap $AE, $6E +.charmap $AF, $6F +.charmap $B0, $70 +.charmap $B1, $71 +.charmap $B2, $72 +.charmap $B3, $73 +.charmap $B4, $74 +.charmap $B5, $75 +.charmap $B6, $76 +.charmap $B7, $77 +.charmap $B8, $78 +.charmap $B9, $79 +.charmap $BA, $7A +.charmap $BB, $7B +.charmap $BC, $7C +.charmap $BD, $7D +.charmap $BE, $7E +.charmap $BF, $7F + +; Char $C0 ... $DF -> c - 128 +.charmap $C0, $40 + +; Char $C1 ... $DA -> c - 128 - 64 lower-case alphabet +.charmap $C1, $01 +.charmap $C2, $02 +.charmap $C3, $03 +.charmap $C4, $04 +.charmap $C5, $05 +.charmap $C6, $06 +.charmap $C7, $07 +.charmap $C8, $08 +.charmap $C9, $09 +.charmap $CA, $0A +.charmap $CB, $0B +.charmap $CC, $0C +.charmap $CD, $0D +.charmap $CE, $0E +.charmap $CF, $0F +.charmap $D0, $10 +.charmap $D1, $11 +.charmap $D2, $12 +.charmap $D3, $13 +.charmap $D4, $14 +.charmap $D5, $15 +.charmap $D6, $16 +.charmap $D7, $17 +.charmap $D8, $18 +.charmap $D9, $19 +.charmap $DA, $1A + +; Char $DB ... $DF -> c - 128 +.charmap $DB, $5B +.charmap $DC, $5C +.charmap $DD, $5D +.charmap $DE, $5E +.charmap $DF, $5F + +; Char $E0 ... $FF -> c - 128 +.charmap $E0, $60 +.charmap $E1, $61 +.charmap $E2, $62 +.charmap $E3, $63 +.charmap $E4, $64 +.charmap $E5, $65 +.charmap $E6, $66 +.charmap $E7, $67 +.charmap $E8, $68 +.charmap $E9, $69 +.charmap $EA, $6A +.charmap $EB, $6B +.charmap $EC, $6C +.charmap $ED, $6D +.charmap $EE, $6E +.charmap $EF, $6F +.charmap $F0, $70 +.charmap $F1, $71 +.charmap $F2, $72 +.charmap $F3, $73 +.charmap $F4, $74 +.charmap $F5, $75 +.charmap $F6, $76 +.charmap $F7, $77 +.charmap $F8, $78 +.charmap $F9, $79 +.charmap $FA, $7A +.charmap $FB, $7B +.charmap $FC, $7C +.charmap $FD, $7D +.charmap $FE, $7E +.charmap $FF, $7F diff --git a/asminc/em-kernel.inc b/asminc/em-kernel.inc index e7cdf9a70..889ffba98 100644 --- a/asminc/em-kernel.inc +++ b/asminc/em-kernel.inc @@ -7,7 +7,7 @@ ;/* */ ;/* */ ;/* (C) 2002-2003 Ullrich von Bassewitz */ -;/* Römerstrasse 52 */ +;/* Roemerstrasse 52 */ ;/* D-70794 Filderstadt */ ;/* EMail: uz@cc65.org */ ;/* */ diff --git a/asminc/joy-kernel.inc b/asminc/joy-kernel.inc index ef729fe3c..791934197 100644 --- a/asminc/joy-kernel.inc +++ b/asminc/joy-kernel.inc @@ -7,7 +7,7 @@ ;/* */ ;/* */ ;/* (C) 2002-2006, Ullrich von Bassewitz */ -;/* Römerstraße 52 */ +;/* Roemerstrasse 52 */ ;/* D-70794 Filderstadt */ ;/* EMail: uz@cc65.org */ ;/* */ diff --git a/asminc/ser-kernel.inc b/asminc/ser-kernel.inc index 546587515..79ace64e9 100644 --- a/asminc/ser-kernel.inc +++ b/asminc/ser-kernel.inc @@ -7,7 +7,7 @@ ;* * ;* * ;*(C) 2003-2006, Ullrich von Bassewitz * -;* Römerstrasse 52 * +;* Roemerstrasse 52 * ;* D-70794 Filderstadt * ;*EMail: uz@cc65.org * ;* * diff --git a/asminc/stdio.inc b/asminc/stdio.inc index 3b22c47f6..c727e8d0b 100644 --- a/asminc/stdio.inc +++ b/asminc/stdio.inc @@ -7,7 +7,7 @@ ;* */ ;* */ ;* (C) 2003-2005, Ullrich von Bassewitz */ -;* Römerstrasse 52 */ +;* Roemerstrasse 52 */ ;* D-70794 Filderstadt */ ;* EMail: uz@cc65.org */ ;* */ diff --git a/asminc/utsname.inc b/asminc/utsname.inc index 6e2289244..2c7052ce1 100644 --- a/asminc/utsname.inc +++ b/asminc/utsname.inc @@ -7,7 +7,7 @@ ;/* */ ;/* */ ;/* (C) 2003 Ullrich von Bassewitz */ -;/* Römerstrasse 52 */ +;/* Roemerstrasse 52 */ ;/* D-70794 Filderstadt */ ;/* EMail: uz@cc65.org */ ;/* */ diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 91c02c7ad..f957e1247 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -575,15 +575,13 @@ url="ca65.html" name="assembler manual">. Explanation of File Types - ProDOS associates a file type and an auxiliary type with each file. + ProDOS 8 associates a file type and an auxiliary type with each file. These type specifications are separate from the file's name, unlike Windows which uses the file name's suffix (a.k.a. extension) to specify the file type. For example, . The header file Example @@ -624,8 +620,8 @@ url="ca65.html" name="assembler manual">. carriage return instead of a line-feed (Linux/BSD/MacOS) or carriage return, line-feed pair (Windows). - The "sequential" text file terminology is in contrast to a - "random-access" text file which would + The 'sequential' text file terminology is in contrast to a + 'random-access' text file which would have a fixed-length, non-zero record length, so that the file position of any individual record can be calculated. diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 2d4381353..4aafbc256 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -580,15 +580,13 @@ url="ca65.html" name="assembler manual">. Explanation of File Types - ProDOS associates a file type and an auxiliary type with each file. + ProDOS 8 associates a file type and an auxiliary type with each file. These type specifications are separate from the file's name, unlike Windows which uses the file name's suffix (a.k.a. extension) to specify the file type. For example, . The header file Example @@ -629,8 +625,8 @@ url="ca65.html" name="assembler manual">. carriage return instead of a line-feed (Linux/BSD/MacOS) or carriage return, line-feed pair (Windows). - The "sequential" text file terminology is in contrast to a - "random-access" text file which would + The 'sequential' text file terminology is in contrast to a + 'random-access' text file which would have a fixed-length, non-zero record length, so that the file position of any individual record can be calculated. diff --git a/doc/ca65.sgml b/doc/ca65.sgml index cebdca12e..3fc534066 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1353,15 +1353,15 @@ writable. Pseudo functions -Pseudo functions expect their arguments in parenthesis, and they have a result, -either a string or an expression. +Pseudo functions expect their arguments in parentheses, and they have a result, +either a string or an expression value. .ADDRSIZE - The .BANK The or similar functions to address just part of it. - Please note that .BLANK - Builtin function. The function evaluates its argument in braces and yields + Builtin function. The function evaluates its argument in parentheses and yields "false" if the argument is non blank (there is an argument), and "true" if there is no argument. The token list that makes up the function argument may optionally be enclosed in curly braces. This allows the inclusion of @@ -1479,7 +1479,7 @@ either a string or an expression. .CONST - Builtin function. The function evaluates its argument in braces and + Builtin function. The function evaluates its argument in parentheses and yields "true" if the argument is a constant expression (that is, an expression that yields a constant value at assembly time) and "false" otherwise. As an example, the .IFCONST statement may be replaced by @@ -1489,6 +1489,41 @@ either a string or an expression. +.DEF, .DEFINED + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is a symbol that already is defined somewhere in the source file up to the + current position. Otherwise, the function yields false. As an example, the + statement may be replaced by + + + .if .defined(a) + + + +.DEFINEDMACRO + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + already has been defined as the name of a macro. Otherwise, the function yields + false. Example: + + + .macro add foo + clc + adc foo + .endmacro + + .if .definedmacro(add) + add #$01 + .else + clc + adc #$01 + .endif + + + .HIBYTE The function returns the high byte (that is, bits 8-15) of its argument. @@ -1525,6 +1560,23 @@ either a string or an expression. +.ISMNEM, .ISMNEMONIC + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + + + .LEFT Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. .REF, .REFERENCED - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants @@ -2356,7 +2418,7 @@ Here's a list of all control commands and a description, what they do: Start a define style macro definition. The command is followed by an identifier (the macro name) and optionally by a list of formal arguments - in braces. + in parentheses. Please note that . -.DEF, .DEFINED - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is a symbol that is already defined somewhere in the source file up to the - current position. Otherwise the function yields false. As an example, the - statement may be replaced by - - - .if .defined(a) - - - -.DEFINEDMACRO - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - has already been defined as the name of a macro. Otherwise the function yields - false. Example: - - - .macro add foo - clc - adc foo - .endmacro - - .if .definedmacro(add) - add #$01 - .else - clc - adc #$01 - .endif - - - .DESTRUCTOR Export a symbol and mark it as a module destructor. This may be used @@ -3186,7 +3213,8 @@ Here's a list of all control commands and a description, what they do: .endif - See also: + See also: , and + .IMPORT @@ -3284,23 +3312,6 @@ Here's a list of all control commands and a description, what they do: the feature in more detail. -.ISMNEM, .ISMNEMONIC - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is defined as an instruction mnemonic that is recognized by the assembler. - Example: - - - .if .not .ismnemonic(ina) - .macro ina - clc - adc #$01 - .endmacro - .endif - - - .LINECONT Switch on or off line continuations using the backslash character @@ -3356,6 +3367,22 @@ Here's a list of all control commands and a description, what they do: +.LITERAL + + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + + .literal "Hello " + .literal "world", $0D, $00 + + +See: , + + .LOBYTES Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
-Pseudo functions expect their arguments in parenthesis, and they have a result, -either a string or an expression. +Pseudo functions expect their arguments in parentheses, and they have a result, +either a string or an expression value. .ADDRSIZE - The .BANK The or similar functions to address just part of it. - Please note that .BLANK - Builtin function. The function evaluates its argument in braces and yields + Builtin function. The function evaluates its argument in parentheses and yields "false" if the argument is non blank (there is an argument), and "true" if there is no argument. The token list that makes up the function argument may optionally be enclosed in curly braces. This allows the inclusion of @@ -1479,7 +1479,7 @@ either a string or an expression. .CONST - Builtin function. The function evaluates its argument in braces and + Builtin function. The function evaluates its argument in parentheses and yields "true" if the argument is a constant expression (that is, an expression that yields a constant value at assembly time) and "false" otherwise. As an example, the .IFCONST statement may be replaced by @@ -1489,6 +1489,41 @@ either a string or an expression. +.DEF, .DEFINED + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is a symbol that already is defined somewhere in the source file up to the + current position. Otherwise, the function yields false. As an example, the + statement may be replaced by + + + .if .defined(a) + + + +.DEFINEDMACRO + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + already has been defined as the name of a macro. Otherwise, the function yields + false. Example: + + + .macro add foo + clc + adc foo + .endmacro + + .if .definedmacro(add) + add #$01 + .else + clc + adc #$01 + .endif + + + .HIBYTE The function returns the high byte (that is, bits 8-15) of its argument. @@ -1525,6 +1560,23 @@ either a string or an expression. +.ISMNEM, .ISMNEMONIC + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + + + .LEFT Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. .REF, .REFERENCED - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants @@ -2356,7 +2418,7 @@ Here's a list of all control commands and a description, what they do: Start a define style macro definition. The command is followed by an identifier (the macro name) and optionally by a list of formal arguments - in braces. + in parentheses. Please note that . -.DEF, .DEFINED - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is a symbol that is already defined somewhere in the source file up to the - current position. Otherwise the function yields false. As an example, the - statement may be replaced by - - - .if .defined(a) - - - -.DEFINEDMACRO - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - has already been defined as the name of a macro. Otherwise the function yields - false. Example: - - - .macro add foo - clc - adc foo - .endmacro - - .if .definedmacro(add) - add #$01 - .else - clc - adc #$01 - .endif - - - .DESTRUCTOR Export a symbol and mark it as a module destructor. This may be used @@ -3186,7 +3213,8 @@ Here's a list of all control commands and a description, what they do: .endif - See also: + See also: , and + .IMPORT @@ -3284,23 +3312,6 @@ Here's a list of all control commands and a description, what they do: the feature in more detail. -.ISMNEM, .ISMNEMONIC - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is defined as an instruction mnemonic that is recognized by the assembler. - Example: - - - .if .not .ismnemonic(ina) - .macro ina - clc - adc #$01 - .endmacro - .endif - - - .LINECONT Switch on or off line continuations using the backslash character @@ -3356,6 +3367,22 @@ Here's a list of all control commands and a description, what they do: +.LITERAL + + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + + .literal "Hello " + .literal "world", $0D, $00 + + +See: , + + .LOBYTES Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
- The .BANK The or similar functions to address just part of it. - Please note that .BLANK - Builtin function. The function evaluates its argument in braces and yields + Builtin function. The function evaluates its argument in parentheses and yields "false" if the argument is non blank (there is an argument), and "true" if there is no argument. The token list that makes up the function argument may optionally be enclosed in curly braces. This allows the inclusion of @@ -1479,7 +1479,7 @@ either a string or an expression. .CONST - Builtin function. The function evaluates its argument in braces and + Builtin function. The function evaluates its argument in parentheses and yields "true" if the argument is a constant expression (that is, an expression that yields a constant value at assembly time) and "false" otherwise. As an example, the .IFCONST statement may be replaced by @@ -1489,6 +1489,41 @@ either a string or an expression. +.DEF, .DEFINED + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is a symbol that already is defined somewhere in the source file up to the + current position. Otherwise, the function yields false. As an example, the + statement may be replaced by + + + .if .defined(a) + + + +.DEFINEDMACRO + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + already has been defined as the name of a macro. Otherwise, the function yields + false. Example: + + + .macro add foo + clc + adc foo + .endmacro + + .if .definedmacro(add) + add #$01 + .else + clc + adc #$01 + .endif + + + .HIBYTE The function returns the high byte (that is, bits 8-15) of its argument. @@ -1525,6 +1560,23 @@ either a string or an expression. +.ISMNEM, .ISMNEMONIC + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + + + .LEFT Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. .REF, .REFERENCED - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants @@ -2356,7 +2418,7 @@ Here's a list of all control commands and a description, what they do: Start a define style macro definition. The command is followed by an identifier (the macro name) and optionally by a list of formal arguments - in braces. + in parentheses. Please note that . -.DEF, .DEFINED - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is a symbol that is already defined somewhere in the source file up to the - current position. Otherwise the function yields false. As an example, the - statement may be replaced by - - - .if .defined(a) - - - -.DEFINEDMACRO - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - has already been defined as the name of a macro. Otherwise the function yields - false. Example: - - - .macro add foo - clc - adc foo - .endmacro - - .if .definedmacro(add) - add #$01 - .else - clc - adc #$01 - .endif - - - .DESTRUCTOR Export a symbol and mark it as a module destructor. This may be used @@ -3186,7 +3213,8 @@ Here's a list of all control commands and a description, what they do: .endif - See also: + See also: , and + .IMPORT @@ -3284,23 +3312,6 @@ Here's a list of all control commands and a description, what they do: the feature in more detail. -.ISMNEM, .ISMNEMONIC - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is defined as an instruction mnemonic that is recognized by the assembler. - Example: - - - .if .not .ismnemonic(ina) - .macro ina - clc - adc #$01 - .endmacro - .endif - - - .LINECONT Switch on or off line continuations using the backslash character @@ -3356,6 +3367,22 @@ Here's a list of all control commands and a description, what they do: +.LITERAL + + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + + .literal "Hello " + .literal "world", $0D, $00 + + +See: , + + .LOBYTES Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
The or similar functions to address just part of it. - Please note that .BLANK - Builtin function. The function evaluates its argument in braces and yields + Builtin function. The function evaluates its argument in parentheses and yields "false" if the argument is non blank (there is an argument), and "true" if there is no argument. The token list that makes up the function argument may optionally be enclosed in curly braces. This allows the inclusion of @@ -1479,7 +1479,7 @@ either a string or an expression. .CONST - Builtin function. The function evaluates its argument in braces and + Builtin function. The function evaluates its argument in parentheses and yields "true" if the argument is a constant expression (that is, an expression that yields a constant value at assembly time) and "false" otherwise. As an example, the .IFCONST statement may be replaced by @@ -1489,6 +1489,41 @@ either a string or an expression. +.DEF, .DEFINED + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is a symbol that already is defined somewhere in the source file up to the + current position. Otherwise, the function yields false. As an example, the + statement may be replaced by + + + .if .defined(a) + + + +.DEFINEDMACRO + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + already has been defined as the name of a macro. Otherwise, the function yields + false. Example: + + + .macro add foo + clc + adc foo + .endmacro + + .if .definedmacro(add) + add #$01 + .else + clc + adc #$01 + .endif + + + .HIBYTE The function returns the high byte (that is, bits 8-15) of its argument. @@ -1525,6 +1560,23 @@ either a string or an expression. +.ISMNEM, .ISMNEMONIC + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + + + .LEFT Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. .REF, .REFERENCED - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants @@ -2356,7 +2418,7 @@ Here's a list of all control commands and a description, what they do: Start a define style macro definition. The command is followed by an identifier (the macro name) and optionally by a list of formal arguments - in braces. + in parentheses. Please note that . -.DEF, .DEFINED - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is a symbol that is already defined somewhere in the source file up to the - current position. Otherwise the function yields false. As an example, the - statement may be replaced by - - - .if .defined(a) - - - -.DEFINEDMACRO - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - has already been defined as the name of a macro. Otherwise the function yields - false. Example: - - - .macro add foo - clc - adc foo - .endmacro - - .if .definedmacro(add) - add #$01 - .else - clc - adc #$01 - .endif - - - .DESTRUCTOR Export a symbol and mark it as a module destructor. This may be used @@ -3186,7 +3213,8 @@ Here's a list of all control commands and a description, what they do: .endif - See also: + See also: , and + .IMPORT @@ -3284,23 +3312,6 @@ Here's a list of all control commands and a description, what they do: the feature in more detail. -.ISMNEM, .ISMNEMONIC - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is defined as an instruction mnemonic that is recognized by the assembler. - Example: - - - .if .not .ismnemonic(ina) - .macro ina - clc - adc #$01 - .endmacro - .endif - - - .LINECONT Switch on or off line continuations using the backslash character @@ -3356,6 +3367,22 @@ Here's a list of all control commands and a description, what they do: +.LITERAL + + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + + .literal "Hello " + .literal "world", $0D, $00 + + +See: , + + .LOBYTES Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
- Builtin function. The function evaluates its argument in braces and yields + Builtin function. The function evaluates its argument in parentheses and yields "false" if the argument is non blank (there is an argument), and "true" if there is no argument. The token list that makes up the function argument may optionally be enclosed in curly braces. This allows the inclusion of @@ -1479,7 +1479,7 @@ either a string or an expression. .CONST - Builtin function. The function evaluates its argument in braces and + Builtin function. The function evaluates its argument in parentheses and yields "true" if the argument is a constant expression (that is, an expression that yields a constant value at assembly time) and "false" otherwise. As an example, the .IFCONST statement may be replaced by @@ -1489,6 +1489,41 @@ either a string or an expression. +.DEF, .DEFINED + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is a symbol that already is defined somewhere in the source file up to the + current position. Otherwise, the function yields false. As an example, the + statement may be replaced by + + + .if .defined(a) + + + +.DEFINEDMACRO + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + already has been defined as the name of a macro. Otherwise, the function yields + false. Example: + + + .macro add foo + clc + adc foo + .endmacro + + .if .definedmacro(add) + add #$01 + .else + clc + adc #$01 + .endif + + + .HIBYTE The function returns the high byte (that is, bits 8-15) of its argument. @@ -1525,6 +1560,23 @@ either a string or an expression. +.ISMNEM, .ISMNEMONIC + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + + + .LEFT Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. .REF, .REFERENCED - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
- Builtin function. The function evaluates its argument in braces and + Builtin function. The function evaluates its argument in parentheses and yields "true" if the argument is a constant expression (that is, an expression that yields a constant value at assembly time) and "false" otherwise. As an example, the .IFCONST statement may be replaced by @@ -1489,6 +1489,41 @@ either a string or an expression. +.DEF, .DEFINED + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is a symbol that already is defined somewhere in the source file up to the + current position. Otherwise, the function yields false. As an example, the + statement may be replaced by + + + .if .defined(a) + + + +.DEFINEDMACRO + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + already has been defined as the name of a macro. Otherwise, the function yields + false. Example: + + + .macro add foo + clc + adc foo + .endmacro + + .if .definedmacro(add) + add #$01 + .else + clc + adc #$01 + .endif + + + .HIBYTE The function returns the high byte (that is, bits 8-15) of its argument. @@ -1525,6 +1560,23 @@ either a string or an expression. +.ISMNEM, .ISMNEMONIC + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + + + .LEFT Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. .REF, .REFERENCED - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
+ + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is a symbol that already is defined somewhere in the source file up to the + current position. Otherwise, the function yields false. As an example, the + statement may be replaced by + + + .if .defined(a) + + + +.DEFINEDMACRO + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + already has been defined as the name of a macro. Otherwise, the function yields + false. Example: + + + .macro add foo + clc + adc foo + .endmacro + + .if .definedmacro(add) + add #$01 + .else + clc + adc #$01 + .endif + + + .HIBYTE The function returns the high byte (that is, bits 8-15) of its argument. @@ -1525,6 +1560,23 @@ either a string or an expression. +.ISMNEM, .ISMNEMONIC + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + + + .LEFT Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. .REF, .REFERENCED - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
+ + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + already has been defined as the name of a macro. Otherwise, the function yields + false. Example: + + + .macro add foo + clc + adc foo + .endmacro + + .if .definedmacro(add) + add #$01 + .else + clc + adc #$01 + .endif + + + .HIBYTE The function returns the high byte (that is, bits 8-15) of its argument. @@ -1525,6 +1560,23 @@ either a string or an expression. +.ISMNEM, .ISMNEMONIC + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + + + .LEFT Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. .REF, .REFERENCED - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
The function returns the high byte (that is, bits 8-15) of its argument. @@ -1525,6 +1560,23 @@ either a string or an expression. +.ISMNEM, .ISMNEMONIC + + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + + + .LEFT Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. .REF, .REFERENCED - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
+ + Builtin function. The function expects an identifier as argument in parentheses. + The argument is evaluated, and the function yields "true" if the identifier + is defined as an instruction mnemonic that is recognized by the assembler. + Example: + + + .if .not .ismnemonic(ina) + .macro ina + clc + adc #$01 + .endmacro + .endif + + + .LEFT Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. .REF, .REFERENCED - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
Builtin function. Extracts the left part of a given token list. @@ -1719,7 +1771,7 @@ either a string or an expression. .REF, .REFERENCED - Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
- Builtin function. The function expects an identifier as argument in braces. + Builtin function. The function expects an identifier as argument in parentheses. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, @@ -1826,24 +1878,6 @@ either a string or an expression. -.STRAT - - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
- - Builtin function. The function accepts a string and an index as - arguments and returns the value of the character at the given position - as an integer value. The index is zero based. - - Example: - - - .macro M Arg - ; Check if the argument string starts with '#' - .if (.strat (Arg, 0) = '#') - ... - .endif - .endmacro - - - .SPRINTF Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
Builtin function. It expects a format string as first argument. The number @@ -1863,9 +1897,27 @@ either a string or an expression. +.STRAT + + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
+ + Builtin function. The function accepts a string and an index as + arguments and returns the value of the character at the given position + as an integer value. The index is zero based. + + Example: + + + .macro M Arg + ; Check if the argument string starts with '#' + .if (.strat (Arg, 0) = '#') + ... + .endif + .endmacro + + + .STRING - Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
- Builtin function. The function accepts an argument in braces and converts + Builtin function. The function accepts an argument in parentheses and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value. @@ -1884,7 +1936,7 @@ either a string or an expression. .STRLEN - Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
- Builtin function. The function accepts a string argument in braces and + Builtin function. The function accepts a string argument in parentheses and evaluates to the length of the string. Example: @@ -1901,7 +1953,7 @@ either a string or an expression. .TCOUNT - Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
- Builtin function. The function accepts a token list in braces. The function + Builtin function. The function accepts a token list in parentheses. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion @@ -2084,7 +2136,11 @@ Here's a list of all control commands and a description, what they do: This will put the string "Hello world" followed by a binary zero into the current segment. There may be more strings separated by commas, but - the binary zero is only appended once (after the last one). + the binary zero is only appended once (after the last one). Strings will + be translated using the current character mapping definition. + +See: ,, + .ASSERT @@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
@@ -2180,7 +2236,8 @@ Here's a list of all control commands and a description, what they do: .BYT, .BYTE Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
Define byte sized data. Must be followed by a sequence of (byte ranged) - expressions or strings. + expressions or strings. Strings will be translated using the current + character mapping definition. Example: @@ -2189,6 +2246,9 @@ Here's a list of all control commands and a description, what they do: .byt "world", $0D, $00 +See: , + + .CASE @@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
@@ -2207,8 +2267,10 @@ Here's a list of all control commands and a description, what they do: .CHARMAP - Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
- Apply a custom mapping for characters. The command is followed by two - numbers. The first one is the index of the source character (range 0..255); + Apply a custom mapping for characters for the commands and . The command + is followed by two numbers. The first one is the index of the source character + (range 0..255); the second one is the mapping (range 0..255). The mapping applies to all character and string constants
- - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is a symbol that is already defined somewhere in the source file up to the - current position. Otherwise the function yields false. As an example, the - statement may be replaced by - - - .if .defined(a) - - - -.DEFINEDMACRO - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - has already been defined as the name of a macro. Otherwise the function yields - false. Example: - - - .macro add foo - clc - adc foo - .endmacro - - .if .definedmacro(add) - add #$01 - .else - clc - adc #$01 - .endif - - - .DESTRUCTOR Export a symbol and mark it as a module destructor. This may be used @@ -3186,7 +3213,8 @@ Here's a list of all control commands and a description, what they do: .endif - See also: + See also: , and + .IMPORT @@ -3284,23 +3312,6 @@ Here's a list of all control commands and a description, what they do: the feature in more detail. -.ISMNEM, .ISMNEMONIC - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is defined as an instruction mnemonic that is recognized by the assembler. - Example: - - - .if .not .ismnemonic(ina) - .macro ina - clc - adc #$01 - .endmacro - .endif - - - .LINECONT Switch on or off line continuations using the backslash character @@ -3356,6 +3367,22 @@ Here's a list of all control commands and a description, what they do: +.LITERAL + + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + + .literal "Hello " + .literal "world", $0D, $00 + + +See: , + + .LOBYTES Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
- - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - has already been defined as the name of a macro. Otherwise the function yields - false. Example: - - - .macro add foo - clc - adc foo - .endmacro - - .if .definedmacro(add) - add #$01 - .else - clc - adc #$01 - .endif - - - .DESTRUCTOR Export a symbol and mark it as a module destructor. This may be used @@ -3186,7 +3213,8 @@ Here's a list of all control commands and a description, what they do: .endif - See also: + See also: , and + .IMPORT @@ -3284,23 +3312,6 @@ Here's a list of all control commands and a description, what they do: the feature in more detail. -.ISMNEM, .ISMNEMONIC - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is defined as an instruction mnemonic that is recognized by the assembler. - Example: - - - .if .not .ismnemonic(ina) - .macro ina - clc - adc #$01 - .endmacro - .endif - - - .LINECONT Switch on or off line continuations using the backslash character @@ -3356,6 +3367,22 @@ Here's a list of all control commands and a description, what they do: +.LITERAL + + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + + .literal "Hello " + .literal "world", $0D, $00 + + +See: , + + .LOBYTES Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
Export a symbol and mark it as a module destructor. This may be used @@ -3186,7 +3213,8 @@ Here's a list of all control commands and a description, what they do: .endif - See also: + See also: , and + .IMPORT @@ -3284,23 +3312,6 @@ Here's a list of all control commands and a description, what they do: the feature in more detail. -.ISMNEM, .ISMNEMONIC - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is defined as an instruction mnemonic that is recognized by the assembler. - Example: - - - .if .not .ismnemonic(ina) - .macro ina - clc - adc #$01 - .endmacro - .endif - - - .LINECONT Switch on or off line continuations using the backslash character @@ -3356,6 +3367,22 @@ Here's a list of all control commands and a description, what they do: +.LITERAL + + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + + .literal "Hello " + .literal "world", $0D, $00 + + +See: , + + .LOBYTES Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
@@ -3284,23 +3312,6 @@ Here's a list of all control commands and a description, what they do: the feature in more detail. -.ISMNEM, .ISMNEMONIC - - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is defined as an instruction mnemonic that is recognized by the assembler. - Example: - - - .if .not .ismnemonic(ina) - .macro ina - clc - adc #$01 - .endmacro - .endif - - - .LINECONT Switch on or off line continuations using the backslash character @@ -3356,6 +3367,22 @@ Here's a list of all control commands and a description, what they do: +.LITERAL + + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + + .literal "Hello " + .literal "world", $0D, $00 + + +See: , + + .LOBYTES Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
- - Builtin function. The function expects an identifier as argument in braces. - The argument is evaluated, and the function yields "true" if the identifier - is defined as an instruction mnemonic that is recognized by the assembler. - Example: - - - .if .not .ismnemonic(ina) - .macro ina - clc - adc #$01 - .endmacro - .endif - - - .LINECONT Switch on or off line continuations using the backslash character @@ -3356,6 +3367,22 @@ Here's a list of all control commands and a description, what they do: +.LITERAL + + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + + .literal "Hello " + .literal "world", $0D, $00 + + +See: , + + .LOBYTES Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
Switch on or off line continuations using the backslash character @@ -3356,6 +3367,22 @@ Here's a list of all control commands and a description, what they do: +.LITERAL + + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + + .literal "Hello " + .literal "world", $0D, $00 + + +See: , + + .LOBYTES Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
+ + Define byte sized data. Must be followed by a sequence of (byte ranged) + expressions or strings. Strings will disregard the current character + mapping definition and will be interpreted literally. + + Example: + + + .literal "Hello " + .literal "world", $0D, $00 + + +See: , + + .LOBYTES Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
Define byte sized data by extracting only the low byte (that is, bits 0-7) from @@ -3601,6 +3628,21 @@ Here's a list of all control commands and a description, what they do: See: +.POPCHARMAP + + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
+ + Pop the last character mapping from the stack, and activate it. + + This command will switch back to the character mapping that was last pushed onto the + character mapping stack using the + command, and remove this entry from the stack. + + The assembler will print an error message if the mappting stack is empty when + this command is issued. + + See: , + + .POPCPU Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
Pop the last CPU setting from the stack, and activate it. @@ -3675,6 +3717,22 @@ Here's a list of all control commands and a description, what they do: +.PUSHCHARMAP + + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
+ + Push the currently active character mapping onto a stack. The stack has a size of 16 + entries. + + to switch to another character mapping and to restore the old + characther mapping later, without knowledge of the current mapping. + + The assembler will print an error message if the character mapping stack is already full, + when this command is issued. + + See: , + + .PUSHCPU Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
Push the currently active CPU onto a stack. The stack has a size of 8 @@ -3707,6 +3765,46 @@ Here's a list of all control commands and a description, what they do: See: +.REFERTO, .REFTO + + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
+ + Mark a symbol as referenced. + + It is useful in combination with the + command. A subroutine with two entry points can be created. When the first + entry point is called, it sets some default value as an argument, and falls + through into the second entry point. .REFERTO helps to ensure that + the second part is included into binary when only the first entry point is + actually used from the code. + + Example: + + + .ifref NegateValue ; If this subroutine is used + NegateValue: ; Define it + lda #0 + sec + sbc Value + .ifref ResetValue ; If the ResetValue is also used + jmp SetValue ; Jump over it + .else + .refto SetValue ; Ensure that SetValue will be included + .endif + .endif + + .ifref ResetValue ; If this subroutine is used + ResetValue: ; Define it + lda #0 ; Set a default value + .refto SetValue ; Ensure that SetValue will be included + .endif + + .ifref SetValue ; If this or previous subroutine is used + SetValue: + sta Value + rts + .endif + + + .RELOC Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}
Switch back to relocatable mode. See the Since style macros may not @@ -4393,8 +4491,8 @@ Macros with parameters may also be useful: Note that, while formal parameters have to be placed in parentheses, the actual argument used when invoking the macro should not be. -The invoked arguments are separated by commas only, if parentheses are -used by accident they will become part of the replaced token. +The invoked arguments are separated by commas only; if parentheses are +used by accident, they will become part of the replaced token. If you wish to have an expression follow the macro invocation, the last parameter can be enclosed in curly braces {} to indicate the end of that diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 24f4422f4..ae80b11b0 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -546,6 +546,12 @@ Here is a description of all the command line options: Treat all warnings as errors. Warn about statements that don't have an effect. + + Warn if a pointer assignment changes the signedness of the target + of a pointer value, and the new signedness wasn't cast explicitly. + + Warn if a pointer assignment changes the type of the target + of a pointer value, and the new type wasn't cast explicitly. Warn about a / that changes a character's code number from/to 0x00. @@ -555,6 +561,10 @@ Here is a description of all the command line options: Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. + + Warn about unreachable code in cases of comparing constants, etc. + + Warn about unused functions. Warn about unused labels. diff --git a/include/_ted.h b/include/_ted.h index 68b59d706..c2cd0a04e 100644 --- a/include/_ted.h +++ b/include/_ted.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..a51ee79c5 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/cx16.h b/include/cx16.h index f3d02bd28..179021e84 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -278,6 +278,9 @@ struct __vera { #define VIA1 (*(volatile struct __6522 *)0x9F60) #define VIA2 (*(volatile struct __6522 *)0x9F70) +#define RAM_BANK (VIA1.pra) +#define ROM_BANK (VIA1.prb) + /* A structure with the x16emu's settings registers */ struct __emul { unsigned char debug; /* Boolean: debugging enabled */ @@ -295,7 +298,7 @@ struct __emul { #define EMULATOR (*(volatile struct __emul *)0x9FB0) /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ -#define BANK_RAM ((unsigned char[0x2000])0xA000) +#define BANK_RAM ((unsigned char *)0xA000) diff --git a/include/fcntl.h b/include/fcntl.h index 0d2398315..a1121159d 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/locale.h b/include/locale.h index 4134dd5db..3f23e01d2 100644 --- a/include/locale.h +++ b/include/locale.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/mouse/mouse-kernel.h b/include/mouse/mouse-kernel.h index f024b0926..e2d2ced10 100644 --- a/include/mouse/mouse-kernel.h +++ b/include/mouse/mouse-kernel.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003-2006, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/peekpoke.h b/include/peekpoke.h index 4c1156ec3..268dbfb98 100644 --- a/include/peekpoke.h +++ b/include/peekpoke.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..325ba7d89 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/signal.h b/include/signal.h index 5cb63fcae..0d5f6ad09 100644 --- a/include/signal.h +++ b/include/signal.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2005, Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/stdarg.h b/include/stdarg.h index adf73483c..f6a4fe934 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/stat.h b/include/sys/stat.h index c7e003808..d8fc09c75 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/include/sys/types.h b/include/sys/types.h index 9b1e9610f..e75dd7d46 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_poserror.c b/libsrc/common/_poserror.c index 95dbfdc9d..2777fee98 100644 --- a/libsrc/common/_poserror.c +++ b/libsrc/common/_poserror.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index f5d1784ec..840d42127 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -3,7 +3,7 @@ ; ; Ullrich von Bassewitz, 2000-10-21 ; - + .include "zeropage.inc" .export __printf @@ -32,8 +32,8 @@ FCount = ptr2 .code ; ---------------------------------------------------------------------------- -; Get one character from the format string and increment the pointer. Will -; return zero in Y. +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. GetFormatChar: ldy #0 @@ -51,7 +51,7 @@ OutputPadChar: lda PadChar ; ---------------------------------------------------------------------------- -; Call the output function with one character in A +; Call the output function with one character in .A Output1: sta CharArg @@ -92,7 +92,7 @@ GetSignedArg: jmp axlong ; Convert to long ; ---------------------------------------------------------------------------- -; Get a long argument from the argument list. Returns 0 in Y. +; Get a long argument from the argument list. Returns 0 in .Y. GetLongArg: jsr GetIntArg ; Get high word @@ -102,7 +102,7 @@ GetLongArg: ; Run into GetIntArg fetching the low word ; ---------------------------------------------------------------------------- -; Get an integer argument from the argument list. Returns 0 in Y. +; Get an integer argument from the argument list. Returns 0 in .Y. GetIntArg: jsr DecArgList2 @@ -114,7 +114,7 @@ GetIntArg: rts ; ---------------------------------------------------------------------------- -; Read an integer from the format string. Will return zero in Y. +; Read an integer from the format string. Will return zero in .Y. ReadInt: ldy #0 @@ -247,10 +247,10 @@ Save: lda regbank,y sta RegSave,y dey bpl Save + pla ; Restore low byte of ap ; Get the parameters from the stack - pla ; Restore low byte of ap sta ArgList ; Argument list pointer stx ArgList+1 @@ -307,7 +307,7 @@ MainLoop: inc Format+1 ; Calculate, how many characters must be output. Beware: This number may -; be zero. A still contains the low byte of the pointer. +; be zero. .A still contains the low byte of the pointer. @L3: sub FSave sta FCount @@ -343,7 +343,7 @@ MainLoop: ; We're back from out(), or we didn't call it. Check for end of string. -@L4: jsr GetFormatChar ; Get one char, zero in Y +@L4: jsr GetFormatChar ; Get one char, zero in .Y tax ; End of format string reached? bne NotDone ; End not reached @@ -357,7 +357,7 @@ Rest: lda RegSave,x rts ; Still a valid format character. Check for '%' and a '%%' sequence. Output -; anything that is not a format specifier. On intro, Y is zero. +; anything that is not a format specifier. On intro, .Y is zero. NotDone: cmp #'%' @@ -371,7 +371,7 @@ NotDone: ; We have a real format specifier ; Format is: %[flags][width][.precision][mod]type -; Y is zero on entry. +; .Y is zero on entry. FormatSpec: @@ -383,7 +383,7 @@ FormatSpec: dex bpl @L1 -; Start with reading the flags if there are any. X is $FF which is used +; Start with reading the flags if there are any. .X is $FF which is used ; for "true" ReadFlags: @@ -410,7 +410,7 @@ ReadFlags: @L4: jsr IncFormatPtr jmp ReadFlags ; ...and start over -; Done with flags, read the pad char. Y is still zero if we come here. +; Done with flags, read the pad char. .Y is still zero if we come here. ReadPadding: ldx #' ' ; PadChar @@ -421,8 +421,8 @@ ReadPadding: lda (Format),y ; Read current for later @L1: stx PadChar -; Read the width. Even here, Y is still zero. A contains the current character -; from the format string +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. ReadWidth: cmp #'*' @@ -435,7 +435,7 @@ ReadWidth: @L2: sta Width stx Width+1 ; ...and remember in Width -; Read the precision. Even here, Y is still zero. +; Read the precision. Even here, .Y is still zero. sty Prec ; Assume Precision is zero sty Prec+1 @@ -456,7 +456,7 @@ ReadPrec: @L2: sta Prec stx Prec+1 -; Read the modifiers. Y is still zero. +; Read the modifiers. .Y is still zero. ReadMod: lda (Format),y @@ -479,9 +479,9 @@ ReadMod: ; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to ; assemble strings. A zero page index (BufIdx) is used to keep the current -; write position. A pointer to the buffer (Str) is used to point to the the -; argument in case we will not use the buffer but a user supplied string. -; Y is zero when we come here. +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. DoFormat: sty BufIdx ; Clear BufIdx @@ -490,7 +490,7 @@ DoFormat: ldx #>Buf stx Str+1 -; Skip the current format character, then check it (current char in A) +; Skip the current format character, then check it (current char in .A) jsr IncFormatPtr @@ -777,8 +777,5 @@ ArgLen: .res 2 .data -; Stuff from OutData. Is used as a vector and must be aligned +; Stuff from OutData. Is used as a vector CallOutFunc: jmp $0000 - - - diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s new file mode 100644 index 000000000..e1d2a1cf4 --- /dev/null +++ b/libsrc/pce/_printf.s @@ -0,0 +1,791 @@ +; +; _printf: Basic layer for all printf type functions. +; +; 2000-10-21, Ullrich von Bassewitz +; 2021-05-04, Greg King +; + + .include "zeropage.inc" + + .export __printf + + .import popax, pushax, pusheax, decsp6, push1, axlong, axulong + .import _ltoa, _ultoa + .import _strlower, _strlen + + .macpack generic + +; ---------------------------------------------------------------------------- +; We will store variables into the register bank in the zeropage. Define +; equates for these variables. + +ArgList = regbank+0 ; Argument list pointer +Format = regbank+2 ; Format string +OutData = regbank+4 ; Function parameters + +; ---------------------------------------------------------------------------- +; Other zero page cells + +Base = ptr1 +FSave = ptr1 +FCount = ptr2 + +.code + +; ---------------------------------------------------------------------------- +; Get one character from the format string, and increment the pointer. Will +; return zero in .Y. + +GetFormatChar: + ldy #0 + lda (Format),y +IncFormatPtr: + inc Format + bne @L1 + inc Format+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Output a pad character: outfunc (d, &padchar, 1) + +OutputPadChar: + lda PadChar + +; ---------------------------------------------------------------------------- +; Call the output function with one character in .A + +Output1: + sta CharArg + jsr PushOutData + lda #CharArg + jsr pushax + jsr push1 + jmp CallOutFunc ; fout (OutData, &CharArg, 1) + +; ---------------------------------------------------------------------------- +; Decrement the argument list pointer by 2 + +DecArgList2: + lda ArgList + sub #2 + sta ArgList + bcs @L1 + dec ArgList+1 +@L1: rts + +; ---------------------------------------------------------------------------- +; Get an unsigned int or long argument depending on the IsLong flag. + +GetUnsignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axulong ; Convert to unsigned long + +; ---------------------------------------------------------------------------- +; Get an signed int or long argument depending on the IsLong flag. + +GetSignedArg: + lda IsLong ; Check flag + bne GetLongArg ; Long sets all + jsr GetIntArg ; Get an integer argument + jmp axlong ; Convert to long + +; ---------------------------------------------------------------------------- +; Get a long argument from the argument list. Returns 0 in .Y. + +GetLongArg: + jsr GetIntArg ; Get high word + sta sreg + stx sreg+1 + +; Run into GetIntArg fetching the low word + +; ---------------------------------------------------------------------------- +; Get an integer argument from the argument list. Returns 0 in .Y. + +GetIntArg: + jsr DecArgList2 + ldy #1 + lda (ArgList),y + tax + dey + lda (ArgList),y + rts + +; ---------------------------------------------------------------------------- +; Read an integer from the format string. Will return zero in .Y. + +ReadInt: + ldy #0 + sty ptr1 + sty ptr1+1 ; Start with zero +@Loop: lda (Format),y ; Get format string character + sub #'0' ; Make number from ascii digit + bcc @L9 ; Jump if done + cmp #9+1 + bcs @L9 ; Jump if done + +; Skip the digit character + + jsr IncFormatPtr + +; Add the digit to the value we have in ptr1 + + pha ; Save digit value + lda ptr1 + ldx ptr1+1 + asl ptr1 + rol ptr1+1 ; * 2 + asl ptr1 + rol ptr1+1 ; * 4, assume carry clear + adc ptr1 + sta ptr1 + txa + adc ptr1+1 + sta ptr1+1 ; * 5 + asl ptr1 + rol ptr1+1 ; * 10, assume carry clear + pla + adc ptr1 ; Add digit value + sta ptr1 + bcc @Loop + inc ptr1+1 + bcs @Loop ; Branch always + +; We're done converting + +@L9: lda ptr1 + ldx ptr1+1 ; Load result + rts + + +; ---------------------------------------------------------------------------- +; Put a character into the argument buffer and increment the buffer index + +PutBuf: ldy BufIdx + inc BufIdx + sta Buf,y + rts + +; ---------------------------------------------------------------------------- +; Get a pointer to the current buffer end and push it onto the stack + +PushBufPtr: + lda #Buf + add BufIdx + bcc @L1 + inx +@L1: jmp pushax + +; ---------------------------------------------------------------------------- +; Push OutData onto the software stack + +PushOutData: + lda OutData + ldx OutData+1 + jmp pushax + +; ---------------------------------------------------------------------------- +; Output Width pad characters +; + +PadLoop: + jsr OutputPadChar +OutputPadding: + inc Width + bne PadLoop + inc Width+1 + bne PadLoop + rts + +; ---------------------------------------------------------------------------- +; Output the argument itself: outfunc (d, str, arglen); +; + +OutputArg: + jsr PushOutData + lda Str + ldx Str+1 + jsr pushax + lda ArgLen + ldx ArgLen+1 + jsr pushax + jmp CallOutFunc + +; ---------------------------------------------------------------------------- +; ltoa: Wrapper for _ltoa that pushes all arguments + +ltoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ltoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; ultoa: Wrapper for _ultoa that pushes all arguments + +ultoa: sty Base ; Save base + jsr pusheax ; Push value + jsr PushBufPtr ; Push the buffer pointer... + lda Base ; Restore base + jmp _ultoa ; ultoa (l, s, base); + + +; ---------------------------------------------------------------------------- +; + +__printf: + +; Save the register bank variables into the save area + + pha ; Save low byte of ap + ldy #5 + +; The PC-Engine puts the zero-page at $2000. The indexed-by-.Y addressing mode +; doesn't allow zero-page addressing. Therefore, the operand must be redirected +; explicitly. + +Save: lda regbank+$2000,y + sta RegSave,y + dey + bpl Save + pla ; Restore low byte of ap + +; Get the parameters from the stack + + sta ArgList ; Argument list pointer + stx ArgList+1 + + jsr popax ; Format string + sta Format + stx Format+1 + + jsr popax ; Output descriptor + sta OutData + stx OutData+1 + +; Initialize the output counter in the output descriptor to zero + + lda #0 + tay + sta (OutData),y + iny + sta (OutData),y + +; Get the output function from the output descriptor and remember it + + iny + lda (OutData),y + sta CallOutFunc+1 + iny + lda (OutData),y + sta CallOutFunc+2 + +; Start parsing the format string + +MainLoop: + lda Format ; Remember current format pointer + sta FSave + lda Format+1 + sta FSave+1 + + ldy #0 ; Index +@L1: lda (Format),y ; Get next char + beq @L2 ; Jump on end of string + cmp #'%' ; Format spec? + beq @L2 + iny ; Bump pointer + bne @L1 + inc Format+1 ; Bump high byte of pointer + bne @L1 ; Branch always + +; Found a '%' character or end of string. Update the Format pointer so it is +; current (points to this character). + +@L2: tya ; Low byte of offset + add Format + sta Format + bcc @L3 + inc Format+1 + +; Calculate, how many characters must be output. Beware: This number may +; be zero. .A still contains the low byte of the pointer. + +@L3: sub FSave + sta FCount + lda Format+1 + sbc FSave+1 + sta FCount+1 + ora FCount ; Is the result zero? + beq @L4 ; Jump if yes + +; Output the characters that we have until now. To make the call to out +; faster, build the stack frame by hand (don't use pushax) + + jsr decsp6 ; 3 args + ldy #5 + lda OutData+1 + sta (sp),y + dey + lda OutData + sta (sp),y + dey + lda FSave+1 + sta (sp),y + dey + lda FSave + sta (sp),y + dey + lda FCount+1 + sta (sp),y + dey + lda FCount + sta (sp),y + jsr CallOutFunc ; Call the output function + +; We're back from out(), or we didn't call it. Check for end of string. + +@L4: jsr GetFormatChar ; Get one char, zero in .Y + tax ; End of format string reached? + bne NotDone ; End not reached + +; End of format string reached. Restore the zeropage registers and return. + + ldx #5 +Rest: lda RegSave,x + +; The indexed-by-.X addressing mode does allow zero-page addressing. +; Therefore, this operand doesn't need to be redirected explicitly. + + sta regbank,x + dex + bpl Rest + rts + +; Still a valid format character. Check for '%' and a '%%' sequence. Output +; anything that is not a format specifier. On intro, .Y is zero. + +NotDone: + cmp #'%' + bne @L1 + lda (Format),y ; Check for "%%" + cmp #'%' + bne FormatSpec ; Jump if really a format specifier + jsr IncFormatPtr ; Skip the second '%' +@L1: jsr Output1 ; Output the character... + jmp MainLoop ; ...and continue + +; We have a real format specifier +; Format is: %[flags][width][.precision][mod]type +; .Y is zero on entry. + +FormatSpec: + +; Initialize the flags + + lda #0 + ldx #FormatVarSize-1 +@L1: sta FormatVars,x + dex + bpl @L1 + +; Start with reading the flags if there are any. .X is $FF which is used +; for "true" + +ReadFlags: + lda (Format),y ; Get next char... + cmp #'-' + bne @L1 + stx LeftJust + beq @L4 + +@L1: cmp #'+' + bne @L2 + stx AddSign + beq @L4 + +@L2: cmp #' ' + bne @L3 + stx AddBlank + beq @L4 + +@L3: cmp #'#' + bne ReadPadding + stx AltForm + +@L4: jsr IncFormatPtr + jmp ReadFlags ; ...and start over + +; Done with flags, read the pad char. .Y is still zero if we come here. + +ReadPadding: + ldx #' ' ; PadChar + cmp #'0' + bne @L1 + tax ; PadChar is '0' + jsr IncFormatPtr + lda (Format),y ; Read current for later +@L1: stx PadChar + +; Read the width. Even here, .Y is still zero. .A contains the current character +; from the format string. + +ReadWidth: + cmp #'*' + bne @L1 + jsr IncFormatPtr + jsr GetIntArg ; Width is an additional argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string... +@L2: sta Width + stx Width+1 ; ...and remember in Width + +; Read the precision. Even here, .Y is still zero. + + sty Prec ; Assume Precision is zero + sty Prec+1 + lda (Format),y ; Load next format string char + cmp #'.' ; Precision given? + bne ReadMod ; Branch if no precision given + +ReadPrec: + jsr IncFormatPtr ; Skip the '.' + lda (Format),y + cmp #'*' ; Variable precision? + bne @L1 + jsr IncFormatPtr ; Skip the '*' + jsr GetIntArg ; Get integer argument + jmp @L2 + +@L1: jsr ReadInt ; Read integer from format string +@L2: sta Prec + stx Prec+1 + +; Read the modifiers. .Y is still zero. + +ReadMod: + lda (Format),y + cmp #'z' ; size_t - same as unsigned + beq @L2 + cmp #'h' ; short - same as int + beq @L2 + cmp #'t' ; ptrdiff_t - same as int + beq @L2 + cmp #'j' ; intmax_t/uintmax_t - same as long + beq @L1 + cmp #'L' ; long double + beq @L1 + cmp #'l' ; long int + bne DoFormat +@L1: lda #$FF + sta IsLong +@L2: jsr IncFormatPtr + jmp ReadMod + +; Initialize the argument buffer pointers. We use a static buffer (ArgBuf) to +; assemble strings. A zero page index (BufIdx) is used to keep the current +; write position. A pointer to the buffer (Str) is used to point to the +; argument in case we will not use the buffer but a user-supplied string. +; .Y is zero when we come here. + +DoFormat: + sty BufIdx ; Clear BufIdx + ldx #Buf + stx Str+1 + +; Skip the current format character, then check it (current char in .A) + + jsr IncFormatPtr + +; Is it a character? + + cmp #'c' + bne CheckInt + +; It is a character + + jsr GetIntArg ; Get the argument (promoted to int) + sta Buf ; Place it as zero terminated string... + lda #0 + sta Buf+1 ; ...into the buffer + jmp HaveArg ; Done + +; Is it an integer? + +CheckInt: + cmp #'d' + beq @L1 + cmp #'i' + bne CheckCount + +; It is an integer + +@L1: ldx #0 + lda AddBlank ; Add a blank for positives? + beq @L2 ; Jump if no + ldx #' ' +@L2: lda AddSign ; Add a plus for positives (precedence)? + beq @L3 + ldx #'+' +@L3: stx Leader + +; Integer argument + + jsr GetSignedArg ; Get argument as a long + ldy sreg+1 ; Check sign + bmi @Int1 + ldy Leader + beq @Int1 + sty Buf + inc BufIdx + +@Int1: ldy #10 ; Base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Is it a count pseudo format? + +CheckCount: + cmp #'n' + bne CheckOctal + +; It is a count pseudo argument + + jsr GetIntArg + sta ptr1 + stx ptr1+1 ; Get user supplied pointer + ldy #0 + lda (OutData),y ; Low byte of OutData->ccount + sta (ptr1),y + iny + lda (OutData),y ; High byte of OutData->ccount + sta (ptr1),y + jmp MainLoop ; Done + +; Check for an octal digit + +CheckOctal: + cmp #'o' + bne CheckPointer + +; Integer in octal representation + + jsr GetSignedArg ; Get argument as a long + ldy AltForm ; Alternative form? + beq @Oct1 ; Jump if no + pha ; Save low byte of value + stx tmp1 + ora tmp1 + ora sreg + ora sreg+1 + ora Prec + ora Prec+1 ; Check if value or Prec != 0 + beq @Oct1 + lda #'0' + jsr PutBuf + pla ; Restore low byte + +@Oct1: ldy #8 ; Load base + jsr ltoa ; Push arguments, call _ltoa + jmp HaveArg + +; Check for a pointer specifier (%p) + +CheckPointer: + cmp #'p' + bne CheckString + +; It's a pointer. Use %#x conversion + + ldx #0 + stx IsLong ; IsLong = 0; + inx + stx AltForm ; AltForm = 1; + lda #'x' + bne IsHex ; Branch always + +; Check for a string specifier (%s) + +CheckString: + cmp #'s' + bne CheckUnsigned + +; It's a string + + jsr GetIntArg ; Get 16bit argument + sta Str + stx Str+1 + jmp HaveArg + +; Check for an unsigned integer (%u) + +CheckUnsigned: + cmp #'u' + bne CheckHex + +; It's an unsigned integer + + jsr GetUnsignedArg ; Get argument as unsigned long + ldy #10 ; Load base + jsr ultoa ; Push arguments, call _ultoa + jmp HaveArg + +; Check for a hexadecimal integer (%x) + +CheckHex: + cmp #'x' + beq IsHex + cmp #'X' + bne UnknownFormat + +; Hexadecimal integer + +IsHex: pha ; Save the format spec + lda AltForm + beq @L1 + lda #'0' + jsr PutBuf + lda #'X' + jsr PutBuf + +@L1: jsr GetUnsignedArg ; Get argument as an unsigned long + ldy #16 ; Load base + jsr ultoa ; Push arguments, call _ultoa + + pla ; Get the format spec + cmp #'x' ; Lower case? + bne @L2 + lda Str + ldx Str+1 + jsr _strlower ; Make characters lower case +@L2: jmp HaveArg + +; Unknown format character, skip it + +UnknownFormat: + jmp MainLoop + +; We have the argument, do argument string formatting + +HaveArg: + +; ArgLen = strlen (Str); + + lda Str + ldx Str+1 + jsr _strlen ; Get length of argument + sta ArgLen + stx ArgLen+1 + +; if (Prec && Prec < ArgLen) ArgLen = Prec; + + lda Prec + ora Prec+1 + beq @L1 + ldx Prec + cpx ArgLen + lda Prec+1 + tay + sbc ArgLen+1 + bcs @L1 + stx ArgLen + sty ArgLen+1 + +; if (Width > ArgLen) { +; Width -= ArgLen; /* padcount */ +; } else { +; Width = 0; +; } +; Since width is used as a counter below, calculate -(width+1) + +@L1: sec + lda Width + sbc ArgLen + tax + lda Width+1 + sbc ArgLen+1 + bcs @L2 + lda #0 + tax +@L2: eor #$FF + sta Width+1 + txa + eor #$FF + sta Width + +; /* Do padding on the left side if needed */ +; if (!leftjust) { +; /* argument right justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + bne @L3 + jsr OutputPadding + +; Output the argument itself + +@L3: jsr OutputArg + +; /* Output right padding bytes if needed */ +; if (leftjust) { +; /* argument left justified */ +; while (width) { +; fout (d, &padchar, 1); +; --width; +; } +; } + + lda LeftJust + beq @L4 + jsr OutputPadding + +; Done, parse next chars from format string + +@L4: jmp MainLoop + + +; ---------------------------------------------------------------------------- +; Local data (all static) + +.bss + +; Save area for the zero page registers +RegSave: .res regbanksize + +; One character argument for OutFunc +CharArg: .byte 0 + +; Format variables +FormatVars: +LeftJust: .byte 0 +AddSign: .byte 0 +AddBlank: .byte 0 +AltForm: .byte 0 +PadChar: .byte 0 +Width: .word 0 +Prec: .word 0 +IsLong: .byte 0 +Leader: .byte 0 +BufIdx: .byte 0 ; Argument string pointer +FormatVarSize = * - FormatVars + +; Argument buffer and pointer +Buf: .res 20 +Str: .word 0 +ArgLen: .res 2 + +.data + +; Stuff from OutData. Is used as a vector +CallOutFunc: jmp $0000 diff --git a/src/.gitignore b/src/.gitignore index a2c8bb5d4..3b4d0f7ad 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +.vs/ ipch/ *.suo *.sdf diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index a57bec813..27d12dadc 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -13,66 +13,39 @@ {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} Win32Proj - ar65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ar65/error.c b/src/ar65/error.c index 47ee90aa5..7f1e0f611 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ar65/error.h b/src/ar65/error.h index 4052ee3eb..b311287a1 100644 --- a/src/ar65/error.h +++ b/src/ar65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index df246a59f..3cc6019f2 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -13,66 +13,39 @@ {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} Win32Proj - ca65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - true - common + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - true - common + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ca65/ea.h b/src/ca65/ea.h index 9a038047c..d861e9a6c 100644 --- a/src/ca65/ea.h +++ b/src/ca65/ea.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/ea65.h b/src/ca65/ea65.h index 066d9b0cc..c5b139572 100644 --- a/src/ca65/ea65.h +++ b/src/ca65/ea65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/easw16.h b/src/ca65/easw16.h index 81dfd0fa2..b8b06d466 100644 --- a/src/ca65/easw16.h +++ b/src/ca65/easw16.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/enum.h b/src/ca65/enum.h index 7d73a97b8..b954588dd 100644 --- a/src/ca65/enum.h +++ b/src/ca65/enum.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 988493976..34d87e65f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -491,6 +491,23 @@ void MacDef (unsigned Style) */ while (1) { + /* Check for include */ + if (CurTok.Tok == TOK_INCLUDE) { + /* Include another file */ + NextTok (); + /* Name must follow */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + } else { + SB_Terminate (&CurTok.SVal); + if (NewInputFile (SB_GetConstBuf (&CurTok.SVal)) == 0) { + /* Error opening the file, skip remainder of line */ + SkipUntilSep (); + } + } + NextTok (); + } + /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 26d01cbf1..843f5b9d2 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -566,8 +566,8 @@ static void DoBss (void) -static void DoByte (void) -/* Define bytes */ +static void DoByteBase (int EnableTranslation) +/* Define bytes or literals */ { /* Element type for the generated array */ static const char EType[1] = { GT_BYTE }; @@ -579,8 +579,12 @@ static void DoByte (void) /* Parse arguments */ while (1) { if (CurTok.Tok == TOK_STRCON) { - /* A string, translate into target charset and emit */ - TgtTranslateStrBuf (&CurTok.SVal); + /* A string, translate into target charset + if appropriate */ + if (EnableTranslation) { + TgtTranslateStrBuf (&CurTok.SVal); + } + /* Emit */ EmitStrBuf (&CurTok.SVal); NextTok (); } else { @@ -613,6 +617,14 @@ static void DoByte (void) +static void DoByte (void) +/* Define bytes with translation */ +{ + DoByteBase (1); +} + + + static void DoCase (void) /* Switch the IgnoreCase option */ { @@ -1415,6 +1427,14 @@ static void DoList (void) +static void DoLiteral (void) +/* Define bytes without translation */ +{ + DoByteBase (0); +} + + + static void DoLoBytes (void) /* Define bytes, extracting the lo byte from each expression in the list */ { @@ -1568,6 +1588,19 @@ static void DoPageLength (void) +static void DoPopCharmap (void) +/* Restore a charmap */ +{ + if (TgtTranslateStackIsEmpty ()) { + ErrorSkip ("Charmap stack is empty"); + return; + } + + TgtTranslatePop (); +} + + + static void DoPopCPU (void) /* Pop an old CPU setting from the CPU stack */ { @@ -1657,6 +1690,16 @@ static void DoPSC02 (void) +static void DoPushCharmap (void) +/* Save the current charmap */ +{ + if (!TgtTranslatePush ()) { + ErrorSkip ("Charmap stack overflow"); + } +} + + + static void DoPushCPU (void) /* Push the current CPU setting onto the CPU stack */ { @@ -1687,6 +1730,17 @@ static void DoPushSeg (void) +static void DoReferTo (void) +/* Mark given symbol as referenced */ +{ + SymEntry* Sym = ParseAnySymName (SYM_ALLOC_NEW); + if (Sym) { + SymRef (Sym); + } +} + + + static void DoReloc (void) /* Enter relocatable mode */ { @@ -2080,6 +2134,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoLineCont }, { ccNone, DoList }, { ccNone, DoListBytes }, + { ccNone, DoLiteral }, { ccNone, DoUnexpected }, /* .LOBYTE */ { ccNone, DoLoBytes }, { ccNone, DoUnexpected }, /* .LOCAL */ @@ -2101,13 +2156,16 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .PARAMCOUNT */ { ccNone, DoPC02 }, { ccNone, DoPDTV }, + { ccNone, DoPopCharmap }, { ccNone, DoPopCPU }, { ccNone, DoPopSeg }, { ccNone, DoProc }, { ccNone, DoPSC02 }, + { ccNone, DoPushCharmap }, { ccNone, DoPushCPU }, { ccNone, DoPushSeg }, { ccNone, DoUnexpected }, /* .REFERENCED */ + { ccNone, DoReferTo }, /* .REFERTO */ { ccNone, DoReloc }, { ccNone, DoRepeat }, { ccNone, DoRes }, @@ -2183,4 +2241,7 @@ void CheckPseudo (void) if (!IS_IsEmpty (&CPUStack)) { Warning (1, "CPU stack is not empty"); } + if (!TgtTranslateStackIsEmpty ()) { + Warning (1, "Charmap stack is not empty"); + } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index fb9905809..bf0a85183 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -234,6 +234,7 @@ struct DotKeyword { { ".LINECONT", TOK_LINECONT }, { ".LIST", TOK_LIST }, { ".LISTBYTES", TOK_LISTBYTES }, + { ".LITERAL", TOK_LITERAL }, { ".LOBYTE", TOK_LOBYTE }, { ".LOBYTES", TOK_LOBYTES }, { ".LOCAL", TOK_LOCAL }, @@ -260,14 +261,18 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, + { ".REFERTO", TOK_REFERTO }, + { ".REFTO", TOK_REFERTO }, { ".RELOC", TOK_RELOC }, { ".REPEAT", TOK_REPEAT }, { ".RES", TOK_RES }, diff --git a/src/ca65/struct.h b/src/ca65/struct.h index 1fdaf9d60..e927c477c 100644 --- a/src/ca65/struct.h +++ b/src/ca65/struct.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ca65/token.h b/src/ca65/token.h index ab36028fd..b8bbb6d6e 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -210,6 +210,7 @@ typedef enum token_t { TOK_LINECONT, TOK_LIST, TOK_LISTBYTES, + TOK_LITERAL, TOK_LOBYTE, TOK_LOBYTES, TOK_LOCAL, @@ -231,13 +232,16 @@ typedef enum token_t { TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, TOK_REFERENCED, + TOK_REFERTO, TOK_RELOC, TOK_REPEAT, TOK_RES, diff --git a/src/cc65.props b/src/cc65.props new file mode 100644 index 000000000..ef5a37fea --- /dev/null +++ b/src/cc65.props @@ -0,0 +1,62 @@ + + + + + + v141 + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + v142 + 10.0 + $(SolutionDir)..\wrk\$(MSBuildProjectName)\$(Configuration)\ + $(SolutionDir)..\bin\ + $(IntDir) + + + + NotUsing + Level3 + true + _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0601;WINVER=0x0601;NTDDI_VERSION=0x06010000;%(PreprocessorDefinitions) + common + + + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + true + + + + MultiThreadedDebugDLL + true + + + true + + + + + false + true + + + + MultiThreaded + true + MaxSpeed + false + false + + + false + true + true + UseLinkTimeCodeGeneration + + + diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 0f63a1022..14500296d 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -13,66 +13,39 @@ {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} Win32Proj - cc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - true - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - Level3 - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index c642b4ce9..7ebd2c4e1 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,7 +136,7 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - Type* ltype = Expr->Type; + const Type* ltype = Expr->Type; ExprDesc Expr2; ED_Init (&Expr2); diff --git a/src/cc65/assignment.h b/src/cc65/assignment.h index 278c5ef72..b2cc1548b 100644 --- a/src/cc65/assignment.h +++ b/src/cc65/assignment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index d81f46001..46a7d76c6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "funcdesc.h" #include "global.h" #include "reginfo.h" #include "symtab.h" diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 0626f3d18..e621147ab 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -282,6 +282,8 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) char Reg; CodeEntry* E; CodeLabel* Label; + const char* ArgBase = Arg; + int IsLabel = 0; /* Read the first token and skip white space after it */ L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo))); @@ -448,32 +450,44 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) } - /* If the instruction is a branch, check for the label and generate it - ** if it does not exist. This may lead to unused labels (if the label + /* We do now have the addressing mode in AM. Allocate a new CodeEntry + ** structure and half-initialize it. We'll set the argument and the label + ** later. + */ + E = NewCodeEntry (OPC->OPC, AM, Arg, 0, LI); + + /* If the instruction is a branch or accessing memory data, check if for + ** the argument could refer to a label. If it does but the label does not + ** exist yet, generate it. This may lead to unused labels (if the label ** is actually an external one) which are removed by the CS_MergeLabels ** function later. */ - Label = 0; - if (AM == AM65_BRA) { + if ((E->Info & OF_CALL) == 0 && + (E->ArgInfo & AIF_HAS_NAME) != 0) { + ArgBase = E->ArgBase; + IsLabel = (E->ArgInfo & AIF_LOCAL) != 0; + } + + if (AM == AM65_BRA || IsLabel) { /* Generate the hash over the label, then search for the label */ - unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE; - Label = CS_FindLabel (S, Arg, Hash); + unsigned Hash = HashStr (ArgBase) % CS_LABEL_HASH_SIZE; + Label = CS_FindLabel (S, ArgBase, Hash); /* If we don't have the label, it's a forward ref - create it unless ** it's an external function. */ - if (Label == 0 && (OPC->OPC != OP65_JMP || IsLocalLabelName (Arg)) ) { + if (Label == 0 && (OPC->OPC != OP65_JMP || IsLabel)) { /* Generate a new label */ - Label = CS_NewCodeLabel (S, Arg, Hash); + Label = CS_NewCodeLabel (S, ArgBase, Hash); + } + + if (Label != 0) { + /* Assign the jump */ + CL_AddRef (Label, E); } } - /* We do now have the addressing mode in AM. Allocate a new CodeEntry - ** structure and initialize it. - */ - E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI); - /* Return the new code entry */ return E; } @@ -1084,8 +1098,13 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L) /* Be sure that code entry references a label */ PRECONDITION (OldLabel != 0); - /* Remove the reference to our label */ - CS_RemoveLabelRef (S, E); + /* Delete the entry from the label */ + CollDeleteItem (&OldLabel->JumpFrom, E); + + /* If there are no more references, delete the label */ + if (CollCount (&OldLabel->JumpFrom) == 0) { + CS_DelLabel (S, OldLabel); + } /* Use the new label */ CL_AddRef (L, E); diff --git a/src/cc65/compile.c b/src/cc65/compile.c index d93de96b4..f970edef7 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -53,6 +53,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "function.h" #include "global.h" #include "input.h" diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 07bd2bf98..bc67f7a74 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/coptsub.c b/src/cc65/coptsub.c index 3d75c1f72..08e65fe1d 100644 --- a/src/cc65/coptsub.c +++ b/src/cc65/coptsub.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2006, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index d29a0d807..9e52027ce 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -59,18 +59,24 @@ /* Predefined type strings */ -Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; -Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; -Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; -Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; -Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; -Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; -Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; -Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; -Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; -Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; -Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; +const Type type_char[] = { TYPE(T_CHAR), TYPE(T_END) }; +const Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) }; +const Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) }; +const Type type_int[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) }; +const Type type_long[] = { TYPE(T_LONG), TYPE(T_END) }; +const Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) }; +const Type type_bool[] = { TYPE(T_INT), TYPE(T_END) }; +const Type type_void[] = { TYPE(T_VOID), TYPE(T_END) }; +const Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) }; +const Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) }; +const Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) }; + +/* More predefined type strings */ +const Type type_char_p[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; +const Type type_c_char_p[] = { TYPE(T_PTR), TYPE(T_C_CHAR), TYPE(T_END) }; +const Type type_void_p[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; +const Type type_c_void_p[] = { TYPE(T_PTR), TYPE(T_C_VOID), TYPE(T_END) }; @@ -468,7 +474,7 @@ Type* GetImplicitFuncType (void) /* Fill the type string */ T[0].C = T_FUNC | CodeAddrSizeQualifier (); - T[0].A.P = F; + T[0].A.F = F; T[1].C = T_INT; T[2].C = T_END; @@ -559,7 +565,8 @@ static unsigned TypeOfBySize (const Type* Type) } -Type* PointerTo (const Type* T) + +Type* NewPointerTo (const Type* T) /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -590,7 +597,7 @@ void PrintType (FILE* F, const Type* T) -void PrintFuncSig (FILE* F, const char* Name, Type* T) +void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Print a function signature */ { StrBuf Buf = AUTO_STRBUF_INITIALIZER; @@ -685,13 +692,13 @@ const Type* GetUnderlyingType (const Type* Type) return IS_Get (&SignedChars) ? type_schar : type_uchar; } else if (IsTypeEnum (Type)) { /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* If incomplete enum type is used, just return its raw type */ - if (((SymEntry*)Type->A.P)->V.E.Type != 0) { - return ((SymEntry*)Type->A.P)->V.E.Type; + if (Type->A.S->V.E.Type != 0) { + return Type->A.S->V.E.Type; } } @@ -713,18 +720,17 @@ TypeCode GetUnderlyingTypeCode (const Type* Type) return IS_Get (&SignedChars) ? T_SCHAR : T_UCHAR; } else if (IsTypeEnum (Type)) { - /* This should not happen, but just in case */ - if (Type->A.P == 0) { + if (Type->A.S == 0) { Internal ("Enum tag type error in GetUnderlyingTypeCode"); } /* Inspect the underlying type of the enum */ - if (((SymEntry*)Type->A.P)->V.E.Type == 0) { + if (Type->A.S->V.E.Type == 0) { /* Incomplete enum type is used */ return Underlying; } - TCode = UnqualifiedType (((SymEntry*)Type->A.P)->V.E.Type->C); + TCode = UnqualifiedType (Type->A.S->V.E.Type->C); /* Replace the type code with integer */ Underlying = (TCode & ~T_MASK_TYPE); @@ -792,7 +798,7 @@ unsigned SizeOf (const Type* T) case T_STRUCT: case T_UNION: - return ((SymEntry*) T->A.P)->V.S.Size; + return T->A.S->V.S.Size; case T_ARRAY: if (T->A.L == UNSPECIFIED) { @@ -925,7 +931,7 @@ unsigned FuncTypeOf (const Type* T) /* Get the code generator flag for calling the function */ { if (GetUnderlyingTypeCode (T) == T_FUNC) { - return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; + return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); return 0; @@ -934,7 +940,7 @@ unsigned FuncTypeOf (const Type* T) -Type* Indirect (Type* T) +const Type* Indirect (const Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -948,7 +954,7 @@ Type* Indirect (Type* T) -const Type* IndirectConst (const Type* T) +Type* IndirectModifiable (Type* T) /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ @@ -962,11 +968,11 @@ const Type* IndirectConst (const Type* T) -Type* ArrayToPtr (Type* T) +Type* ArrayToPtr (const Type* T) /* Convert an array to a pointer to it's first element */ { /* Return pointer to first element */ - return PointerTo (GetElementType (T)); + return NewPointerTo (GetElementType (T)); } @@ -1121,7 +1127,7 @@ FuncDesc* GetFuncDesc (const Type* T) CHECK (IsClassFunc (T)); /* Get the function descriptor from the type attributes */ - return T->A.P; + return T->A.F; } @@ -1138,12 +1144,12 @@ void SetFuncDesc (Type* T, FuncDesc* F) CHECK (IsClassFunc (T)); /* Set the function descriptor */ - T->A.P = F; + T->A.F = F; } -Type* GetFuncReturn (Type* T) +const Type* GetFuncReturn (const Type* T) /* Return a pointer to the return type of a function or pointer-to-function type */ { if (UnqualifiedType (T->C) == T_PTR) { @@ -1160,10 +1166,27 @@ Type* GetFuncReturn (Type* T) -FuncDesc* GetFuncDefinitionDesc (Type* T) +Type* GetFuncReturnModifiable (Type* T) +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T->C) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (IsClassFunc (T)); + + /* Return a pointer to the return type */ + return T + 1; +} + + + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) /* Get the function descriptor of the function definition */ { - FuncDesc* D; + const FuncDesc* D; /* Be sure it's a function type */ CHECK (IsClassFunc (T)); @@ -1196,7 +1219,7 @@ void SetElementCount (Type* T, long Count) -Type* GetElementType (Type* T) +const Type* GetElementType (const Type* T) /* Return the element type of the given array type. */ { CHECK (IsTypeArray (T)); @@ -1205,7 +1228,7 @@ Type* GetElementType (Type* T) -Type* GetBaseElementType (Type* T) +const Type* GetBaseElementType (const Type* T) /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -1226,7 +1249,7 @@ SymEntry* GetESUSymEntry (const Type* T) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Return the attribute */ - return T->A.P; + return T->A.S; } @@ -1238,12 +1261,12 @@ void SetESUSymEntry (Type* T, SymEntry* S) CHECK (IsClassStruct (T) || IsTypeEnum (T)); /* Set the attribute */ - T->A.P = S; + T->A.S = S; } -Type* IntPromotion (Type* T) +const Type* IntPromotion (const Type* T) /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ @@ -1282,14 +1305,14 @@ Type* IntPromotion (Type* T) -Type* PtrConversion (Type* T) +const Type* PtrConversion (const Type* T) /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. */ { if (IsTypeFunc (T)) { - return PointerTo (T); + return NewPointerTo (T); } else if (IsTypeArray (T)) { return ArrayToPtr (T); } else { diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index e6ff9b7ce..1140ee498 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -45,8 +45,16 @@ #include "inline.h" #include "mmodel.h" -/* cc65 */ -#include "funcdesc.h" + + +/*****************************************************************************/ +/* Forward declarations */ +/*****************************************************************************/ + + + +typedef struct FuncDesc FuncDesc; +typedef struct SymEntry SymEntry; @@ -56,7 +64,6 @@ - /* Basic data types */ enum { T_END = 0x000000, @@ -139,6 +146,10 @@ enum { T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE, T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE, + /* More types for convenience */ + T_C_CHAR = T_CHAR | T_QUAL_CONST, + T_C_VOID = T_VOID | T_QUAL_CONST, + /* Aliases */ T_SIZE_T = T_UINT, }; @@ -153,7 +164,8 @@ typedef struct Type Type; struct Type { TypeCode C; /* Code for this entry */ union { - void* P; /* Arbitrary attribute pointer */ + FuncDesc* F; /* Function description pointer */ + SymEntry* S; /* Enum/struct/union tag symbol entry pointer */ long L; /* Numeric attribute value */ unsigned long U; /* Dito, unsigned */ } A; /* Type attribute if necessary */ @@ -190,18 +202,24 @@ struct Type { #define PTR_BITS (8 * SIZEOF_PTR) /* Predefined type strings */ -extern Type type_char[]; -extern Type type_schar[]; -extern Type type_uchar[]; -extern Type type_int[]; -extern Type type_uint[]; -extern Type type_long[]; -extern Type type_ulong[]; -extern Type type_bool[]; -extern Type type_void[]; -extern Type type_size_t[]; -extern Type type_float[]; -extern Type type_double[]; +extern const Type type_char[]; +extern const Type type_schar[]; +extern const Type type_uchar[]; +extern const Type type_int[]; +extern const Type type_uint[]; +extern const Type type_long[]; +extern const Type type_ulong[]; +extern const Type type_bool[]; +extern const Type type_void[]; +extern const Type type_size_t[]; +extern const Type type_float[]; +extern const Type type_double[]; + +/* More predefined type strings */ +extern const Type type_char_p[]; +extern const Type type_c_char_p[]; +extern const Type type_void_p[]; +extern const Type type_c_void_p[]; /* Forward for the SymEntry struct */ struct SymEntry; @@ -272,7 +290,7 @@ unsigned long GetIntegerTypeMax (const Type* Type); ** The type must have a known size. */ -Type* PointerTo (const Type* T); +Type* NewPointerTo (const Type* T); /* Return a type string that is "pointer to T". The type string is allocated ** on the heap and may be freed after use. */ @@ -280,7 +298,7 @@ Type* PointerTo (const Type* T); void PrintType (FILE* F, const Type* T); /* Print fulle name of the type */ -void PrintFuncSig (FILE* F, const char* Name, Type* T); +void PrintFuncSig (FILE* F, const char* Name, const Type* T); /* Print a function signature */ void PrintRawType (FILE* F, const Type* T); @@ -340,17 +358,17 @@ unsigned TypeOf (const Type* T); unsigned FuncTypeOf (const Type* T); /* Get the code generator flag for calling the function */ -Type* Indirect (Type* T); +const Type* Indirect (const Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -const Type* IndirectConst (const Type* T); +Type* IndirectModifiable (Type* T); /* Do one indirection for the given type, that is, return the type where the ** given type points to. */ -Type* ArrayToPtr (Type* T); +Type* ArrayToPtr (const Type* T); /* Convert an array to a pointer to it's first element */ #if defined(HAVE_INLINE) @@ -842,10 +860,13 @@ FuncDesc* GetFuncDesc (const Type* T) attribute ((const)); void SetFuncDesc (Type* T, FuncDesc* F); /* Set the FuncDesc pointer in a function or pointer-to-function type */ -Type* GetFuncReturn (Type* T) attribute ((const)); +const Type* GetFuncReturn (const Type* T) attribute ((const)); /* Return a pointer to the return type of a function or pointer-to-function type */ -FuncDesc* GetFuncDefinitionDesc (struct Type* T); +Type* GetFuncReturnModifiable (Type* T) attribute ((const)); +/* Return a non-const pointer to the return type of a function or pointer-to-function type */ + +const FuncDesc* GetFuncDefinitionDesc (const Type* T) attribute ((const)); /* Get the function descriptor of the function definition */ long GetElementCount (const Type* T); @@ -858,10 +879,10 @@ void SetElementCount (Type* T, long Count); ** array type). */ -Type* GetElementType (Type* T); +const Type* GetElementType (const Type* T); /* Return the element type of the given array type. */ -Type* GetBaseElementType (Type* T); +const Type* GetBaseElementType (const Type* T); /* Return the base element type of a given type. If T is not an array, this ** will return. Otherwise it will return the base element type, which means ** the element type that is not an array. @@ -873,12 +894,12 @@ struct SymEntry* GetESUSymEntry (const Type* T) attribute ((const)); void SetESUSymEntry (Type* T, struct SymEntry* S); /* Set the SymEntry pointer for an enum/struct/union type */ -Type* IntPromotion (Type* T); +const Type* IntPromotion (const Type* T); /* Apply the integer promotions to T and return the result. The returned type ** string may be T if there is no need to change it. */ -Type* PtrConversion (Type* T); +const Type* PtrConversion (const Type* T); /* If the type is a function, convert it to pointer to function. If the ** expression is an array, convert it to pointer to first element. Otherwise ** return T. diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 0c00f56d4..0868c2082 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1510,7 +1510,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers, -static Type* ParamTypeCvt (Type* T) +static const Type* ParamTypeCvt (Type* T) /* If T is an array or a function, convert it to a pointer else do nothing. ** Return the resulting type. */ @@ -1520,7 +1520,7 @@ static Type* ParamTypeCvt (Type* T) if (IsTypeArray (T)) { Tmp = ArrayToPtr (T); } else if (IsTypeFunc (T)) { - Tmp = PointerTo (T); + Tmp = NewPointerTo (T); } if (Tmp != 0) { @@ -1891,7 +1891,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode) /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.P = F; + D->Type[D->Index].A.F = F; ++D->Index; /* Qualifiers now used */ @@ -2017,7 +2017,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode) if (IsTypeFunc (D->Type) || IsTypeFuncPtr (D->Type)) { /* A function. Check the return type */ - Type* RetType = GetFuncReturn (D->Type); + Type* RetType = GetFuncReturnModifiable (D->Type); /* Functions may not return functions or arrays */ if (IsTypeFunc (RetType)) { @@ -2343,7 +2343,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers) int HasCurly = 0; /* Get the array data */ - Type* ElementType = GetElementType (T); + Type* ElementType = IndirectModifiable (T); unsigned ElementSize = SizeOf (ElementType); long ElementCount = GetElementCount (T); diff --git a/src/cc65/error.c b/src/cc65/error.c index ec665b319..b1529d0b5 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -71,12 +71,14 @@ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnPointerSign = INTSTACK(1); /* - pointer conversion to pointer differing in signedness */ IntStack WarnPointerTypes = INTSTACK(1); /* - pointer conversion to incompatible pointer type */ IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */ +IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ IntStack WarnStructParam = INTSTACK(0); /* - structs passed by val */ IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */ +IntStack WarnUnreachableCode= INTSTACK(1); /* - unreachable code */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ -IntStack WarnReturnType = INTSTACK(1); /* - control reaches end of non-void function */ +IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */ /* Map the name of a warning to the intstack that holds its state */ typedef struct WarnMapEntry WarnMapEntry; @@ -92,12 +94,14 @@ static WarnMapEntry WarnMap[] = { { &WarnPointerSign, "pointer-sign" }, { &WarnPointerTypes, "pointer-types" }, { &WarnRemapZero, "remap-zero" }, + { &WarnReturnType, "return-type" }, { &WarnStructParam, "struct-param" }, { &WarnUnknownPragma, "unknown-pragma" }, + { &WarnUnreachableCode, "unreachable-code" }, + { &WarnUnusedFunc, "unused-func" }, { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnReturnType, "return-type" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/error.h b/src/cc65/error.h index a7592b366..c4420c434 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -68,12 +68,14 @@ extern IntStack WarnPointerSign; /* - pointer conversion to pointer diffe extern IntStack WarnPointerTypes; /* - pointer conversion to incompatible pointer type */ extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnRemapZero; /* - remapping character code zero */ +extern IntStack WarnReturnType; /* - control reaches end of non-void function */ extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnUnknownPragma; /* - unknown #pragmas */ +extern IntStack WarnUnreachableCode; /* - unreachable code */ extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedVar; /* - unused variables */ -extern IntStack WarnReturnType; /* - control reaches end of non-void function */ +extern IntStack WarnUnusedFunc; /* - unused functions */ /* Forward */ struct StrBuf; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 9e08faeeb..bc277f13b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -150,7 +150,7 @@ void MarkedExprWithCheck (void (*Func) (ExprDesc*), ExprDesc* Expr) -static Type* ArithmeticConvert (Type* lhst, Type* rhst) +static const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) /* Perform the usual arithmetic conversions for binary operators. */ { /* https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5 @@ -209,7 +209,7 @@ static Type* ArithmeticConvert (Type* lhst, Type* rhst) -static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) +static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) /* Adjust the two values for a binary operation. lhs is expected on stack or ** to be constant, rhs is expected to be in the primary register or constant. ** The function will put the type of the result into lhs and return the @@ -223,8 +223,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush) unsigned flags; /* Get the type strings */ - Type* lhst = lhs->Type; - Type* rhst = rhs->Type; + const Type* lhst = lhs->Type; + const Type* rhst = rhs->Type; /* Generate type adjustment code if needed */ ltype = TypeOf (lhst); @@ -865,7 +865,7 @@ static void FunctionCall (ExprDesc* Expr) int PtrOffs = 0; /* Offset of function pointer on stack */ int IsFastcall = 0; /* True if we are fast-calling the function */ int PtrOnStack = 0; /* True if a pointer copy is on stack */ - Type* ReturnType; + const Type* ReturnType; /* Skip the left paren */ NextToken (); @@ -1121,7 +1121,7 @@ static void Primary (ExprDesc* E) /* output its label */ E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF; E->Name = Entry->V.L.Label; - E->Type = PointerTo (type_void); + E->Type = NewPointerTo (type_void); NextToken (); } else { Error ("Computed gotos are a C extension, not supported with this --standard"); @@ -1340,7 +1340,6 @@ static void Primary (ExprDesc* E) static void StructRef (ExprDesc* Expr) /* Process struct/union field after . or ->. */ { - ident Ident; Type* FinalType; TypeCode Q; @@ -1354,42 +1353,42 @@ static void StructRef (ExprDesc* Expr) } /* Get the symbol table entry and check for a struct/union field */ - strcpy (Ident, CurTok.Ident); NextToken (); - const SymEntry Field = FindStructField (Expr->Type, Ident); + const SymEntry Field = FindStructField (Expr->Type, CurTok.Ident); if (Field.Type == 0) { - Error ("No field named '%s' found in '%s'", Ident, GetFullTypeName (Expr->Type)); + Error ("No field named '%s' found in '%s'", CurTok.Ident, GetFullTypeName (Expr->Type)); /* Make the expression an integer at address zero */ ED_MakeConstAbs (Expr, 0, type_int); return; } - /* A struct/union is usually an lvalue. If not, it is a struct/union passed - ** in the primary register, which is usually the result returned from a - ** function. However, it is possible that this rvalue is the result of - ** certain kind of operations on an lvalue such as assignment, and there - ** are no reasons to disallow such use cases. So we just rely on the check - ** upon function returns to catch the unsupported cases and dereference the - ** rvalue address of the struct/union here all the time. - */ - if (IsTypePtr (Expr->Type) || - (ED_IsRVal (Expr) && - ED_IsLocPrimary (Expr) && - Expr->Type == GetStructReplacementType (Expr->Type))) { + if (IsTypePtr (Expr->Type)) { - if (!ED_IsConst (Expr) && !ED_IsLocPrimary (Expr)) { + /* pointer->field */ + if (!ED_IsQuasiConst (Expr) && !ED_IsLocPrimary (Expr)) { /* If we have a non-const struct/union pointer that is not in the - ** primary yet, load its content now. + ** primary yet, load its content now to get the base address. */ LoadExpr (CF_NONE, Expr); - - /* Clear the offset */ - Expr->IVal = 0; + ED_FinalizeRValLoad (Expr); } - /* Dereference the address expression */ ED_IndExpr (Expr); + } else if (ED_IsRVal (Expr) && + ED_IsLocPrimary (Expr) && + Expr->Type == GetStructReplacementType (Expr->Type)) { + + /* A struct/union is usually an lvalue. If not, it is a struct/union + ** passed in the primary register, which is usually the result returned + ** from a function. However, it is possible that this rvalue is the + ** result of certain kind of operations on an lvalue such as assignment, + ** and there are no reasons to disallow such use cases. So we just rely + ** on the check upon function returns to catch the unsupported cases and + ** dereference the rvalue address of the struct/union here all the time. + */ + ED_IndExpr (Expr); + } else if (!ED_IsLocQuasiConst (Expr) && !ED_IsLocPrimaryOrExpr (Expr)) { /* Load the base address into the primary (and use it as a reference ** later) if it's not quasi-const or in the primary already. @@ -2053,7 +2052,7 @@ void hie10 (ExprDesc* Expr) /* The & operator yields an rvalue address */ ED_AddrExpr (Expr); } - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); break; case TOK_SIZEOF: @@ -2381,7 +2380,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If lhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr->Type)) { - Expr->Type = PointerTo (Expr->Type); + Expr->Type = NewPointerTo (Expr->Type); } /* Get the lhs on stack */ @@ -2403,7 +2402,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ /* If rhs is a function, convert it to pointer to function */ if (IsTypeFunc (Expr2.Type)) { - Expr2.Type = PointerTo (Expr2.Type); + Expr2.Type = NewPointerTo (Expr2.Type); } /* Check for a numeric constant expression */ @@ -2793,8 +2792,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) ExprDesc Expr2; unsigned flags; /* Operation flags */ CodeMark Mark; /* Remember code position */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ int lscale; int rscale; int AddDone; /* No need to generate runtime code */ @@ -3133,44 +3132,28 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef) /* Deal with array ref */ if (DoArrayRef) { - TypeCode Qualifiers = T_QUAL_NONE; - Type* ElementType; - /* Check the types of array and subscript */ if (IsClassPtr (lhst)) { if (!IsClassInt (rhst)) { Error ("Array subscript is not an integer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (lhst)) { - Qualifiers = GetQualifier (lhst); } } else if (IsClassInt (lhst)) { if (!IsClassPtr (rhst)) { Error ("Subscripted value is neither array nor pointer"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); - } else if (IsTypeArray (rhst)) { - Qualifiers = GetQualifier (rhst); } } else { Error ("Cannot subscript"); ED_MakeConstAbs (Expr, 0, GetCharArrayType (1)); } - /* The element type has the combined qualifiers from itself and the array, - ** it is a member of (if any). - */ - ElementType = Indirect (Expr->Type); - if (GetQualifier (ElementType) != (GetQualifier (ElementType) | Qualifiers)) { - ElementType = TypeDup (ElementType); - ElementType->C |= Qualifiers; - } - /* The final result is usually an lvalue expression of element type ** referenced in the primary, unless it is once again an array. We can just ** assume the usual case first, and change it later if necessary. */ ED_IndExpr (Expr); - Expr->Type = ElementType; + Expr->Type = Indirect (Expr->Type); /* An array element is actually a variable. So the rules for variables with ** respect to the reference type apply: If it's an array, it is virtually @@ -3206,8 +3189,8 @@ static void parsesub (ExprDesc* Expr) { ExprDesc Expr2; unsigned flags; /* Operation flags */ - Type* lhst; /* Type of left hand side */ - Type* rhst; /* Type of right hand side */ + const Type* lhst; /* Type of left hand side */ + const Type* rhst; /* Type of right hand side */ CodeMark Mark1; /* Save position of output queue */ CodeMark Mark2; /* Another position in the queue */ int rscale; /* Scale factor for pointer arithmetics */ @@ -3251,6 +3234,20 @@ static void parsesub (ExprDesc* Expr) /* Get the rhs type */ rhst = Expr2.Type; + if (IsClassPtr (lhst)) { + /* We'll have to scale the result */ + rscale = PSizeOf (lhst); + /* We cannot scale by 0-size or unknown-size */ + if (rscale == 0 && (IsClassPtr (rhst) || IsClassInt (rhst))) { + TypeCompatibilityDiagnostic (lhst, rhst, + 1, "Invalid pointer types in subtraction: '%s' and '%s'"); + /* Avoid further errors */ + rscale = 1; + } + /* Generate code for pointer subtraction */ + flags = CF_PTR; + } + /* We can only do constant expressions for: ** - integer subtraction: ** - numeric - numeric @@ -3267,24 +3264,14 @@ static void parsesub (ExprDesc* Expr) */ if (IsClassPtr (lhst) && IsClassPtr (rhst)) { - /* Pointer diff */ - if (TypeCmp (lhst, rhst).C >= TC_STRICT_COMPATIBLE) { - /* We'll have to scale the result */ - rscale = PSizeOf (lhst); - /* We cannot scale by 0-size or unknown-size */ - if (rscale == 0) { - TypeCompatibilityDiagnostic (lhst, rhst, - 1, "Invalid pointer types in subtraction: '%s' and '%s'"); - /* Avoid further errors */ - rscale = 1; - } - } else { + /* Pointer Diff. We've got the scale factor and flags above */ + typecmp_t Cmp = TypeCmp (lhst, rhst); + if (Cmp.C < TC_STRICT_COMPATIBLE) { TypeCompatibilityDiagnostic (lhst, rhst, 1, "Incompatible pointer types in subtraction: '%s' and '%s'"); } /* Operate on pointers, result type is an integer */ - flags = CF_PTR; Expr->Type = type_int; /* Check for a constant rhs expression */ @@ -3339,10 +3326,7 @@ static void parsesub (ExprDesc* Expr) /* Both sides are constant. Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - rscale = CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3384,7 +3368,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3392,6 +3376,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3403,10 +3388,7 @@ static void parsesub (ExprDesc* Expr) /* Left hand side is not constant, right hand side is */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { - /* Left is pointer, right is int, must scale rhs */ - Expr2.IVal *= CheckedPSizeOf (lhst); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + /* Pointer subtraction. We've got the scale factor and flags above */ } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Integer subtraction. We'll adjust the types later */ } else { @@ -3423,7 +3405,7 @@ static void parsesub (ExprDesc* Expr) flags = typeadjust (Expr, &Expr2, 1); } /* Do the subtraction */ - g_dec (flags | CF_CONST, Expr2.IVal); + g_dec (flags | CF_CONST, Expr2.IVal * rscale); } else { if (IsClassInt (lhst)) { /* Adjust the types */ @@ -3431,6 +3413,7 @@ static void parsesub (ExprDesc* Expr) } /* Load rhs into the primary */ LoadExpr (CF_NONE, &Expr2); + g_scale (TypeOf (rhst), rscale); /* Generate code for the sub (the & is a hack here) */ g_sub (flags & ~CF_CONST, 0); } @@ -3450,9 +3433,7 @@ static void parsesub (ExprDesc* Expr) /* Check for pointer arithmetic */ if (IsClassPtr (lhst) && IsClassInt (rhst)) { /* Left is pointer, right is int, must scale rhs */ - g_scale (CF_INT, CheckedPSizeOf (lhst)); - /* Operate on pointers, result type is a pointer */ - flags = CF_PTR; + g_scale (CF_INT, rscale); } else if (IsClassInt (lhst) && IsClassInt (rhst)) { /* Adjust operand types */ flags = typeadjust (Expr, &Expr2, 0); @@ -3776,7 +3757,6 @@ static void hieOr (ExprDesc *Expr) unsigned Flags = Expr->Flags & E_MASK_KEEP_SUBEXPR; int AndOp; /* Did we have a && operation? */ unsigned TrueLab; /* Jump to this label if true */ - unsigned DoneLab; int HasTrueJump = 0; CodeMark Start; @@ -3903,19 +3883,23 @@ static void hieOr (ExprDesc *Expr) /* If we really had boolean ops, generate the end sequence if necessary */ if (HasTrueJump) { - /* False case needs to jump over true case */ - DoneLab = GetLocalLabel (); if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { + /* False case needs to jump over true case */ + unsigned DoneLab = GetLocalLabel (); /* Load false only if the result is not true */ g_getimmed (CF_INT | CF_CONST, 0, 0); /* Load FALSE */ g_falsejump (CF_NONE, DoneLab); + + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ + g_defcodelabel (DoneLab); + } else { + /* Load the true value */ + g_defcodelabel (TrueLab); + g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ } - /* Load the true value */ - g_defcodelabel (TrueLab); - g_getimmed (CF_INT | CF_CONST, 1, 0); /* Load TRUE */ - g_defcodelabel (DoneLab); - /* The result is an rvalue in primary */ ED_FinalizeRValLoad (Expr); /* Condition codes are set */ @@ -4097,7 +4081,7 @@ static void hieQuest (ExprDesc* Expr) /* Get common type */ - ResultType = ArithmeticConvert (Expr2.Type, Expr3.Type); + ResultType = TypeDup (ArithmeticConvert (Expr2.Type, Expr3.Type)); /* Convert the third expression to this type if needed */ TypeConversion (&Expr3, ResultType); @@ -4121,10 +4105,10 @@ static void hieQuest (ExprDesc* Expr) ** appropriately qualified void. */ if (IsTypeVoid (Indirect (Expr2.Type))) { - ResultType = PointerTo (Indirect (Expr2.Type)); + ResultType = NewPointerTo (Indirect (Expr2.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } else if (IsTypeVoid (Indirect (Expr3.Type))) { - ResultType = PointerTo (Indirect (Expr3.Type)); + ResultType = NewPointerTo (Indirect (Expr3.Type)); ResultType[1].C |= GetQualifier (Indirect (Expr2.Type)); } else { /* Must point to compatible types */ @@ -4132,7 +4116,7 @@ static void hieQuest (ExprDesc* Expr) TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible pointer types in ternary: '%s' and '%s'"); /* Avoid further errors */ - ResultType = PointerTo (type_void); + ResultType = NewPointerTo (type_void); } else { /* Result has the composite type */ ResultType = TypeDup (Expr2.Type); @@ -4141,22 +4125,22 @@ static void hieQuest (ExprDesc* Expr) } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { /* Result type is pointer, no cast needed */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else if (Expr2IsNULL && IsClassPtr (Expr3.Type)) { /* Result type is pointer, no cast needed */ - ResultType = Expr3.Type; + ResultType = TypeDup (Expr3.Type); } else if (IsTypeVoid (Expr2.Type) && IsTypeVoid (Expr3.Type)) { /* Result type is void */ - ResultType = type_void; + ResultType = TypeDup (type_void); } else { if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) && TypeCmp (Expr2.Type, Expr3.Type).C == TC_IDENTICAL) { /* Result type is struct/union */ - ResultType = Expr2.Type; + ResultType = TypeDup (Expr2.Type); } else { TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, "Incompatible types in ternary '%s' with '%s'"); - ResultType = Expr2.Type; /* Doesn't matter here */ + ResultType = TypeDup (Expr2.Type); /* Doesn't matter here */ } } diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index d1113d9a5..1d4fd6872 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -228,7 +228,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs) -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type) +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type) /* Replace Expr with an absolute const with the given value and type */ { Expr->Sym = 0; @@ -595,10 +595,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E) -Type* ReplaceType (ExprDesc* Expr, const Type* NewType) +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { - Type* OldType = Expr->Type; + const Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index a4f5eb848..a46685b59 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -199,7 +199,7 @@ struct Literal; typedef struct ExprDesc ExprDesc; struct ExprDesc { struct SymEntry* Sym; /* Symbol table entry if known */ - Type* Type; /* Type array of expression */ + const Type* Type; /* Type array of expression */ unsigned Flags; uintptr_t Name; /* Name pointer or label number */ long IVal; /* Integer value if expression constant */ @@ -544,7 +544,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs); ** an additional offset in Offs. */ -ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type); +ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type); /* Replace Expr with an absolute const with the given value and type */ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value); @@ -685,7 +685,7 @@ int ED_IsBool (const ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr); /* Print an ExprDesc */ -Type* ReplaceType (ExprDesc* Expr, const Type* NewType); +const Type* ReplaceType (ExprDesc* Expr, const Type* NewType); /* Replace the type of Expr by a copy of Newtype and return the old type string */ diff --git a/src/cc65/function.c b/src/cc65/function.c index cad1df629..4e61cc1d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -191,7 +191,7 @@ unsigned F_GetParamSize (const Function* F) -Type* F_GetReturnType (Function* F) +const Type* F_GetReturnType (Function* F) /* Get the return type for the function */ { return F->ReturnType; diff --git a/src/cc65/function.h b/src/cc65/function.h index 825257a60..f7f83cdc8 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -54,7 +54,7 @@ typedef enum { /* Structure that holds all data needed for function activation */ struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ - Type* ReturnType; /* Function return type */ + const Type* ReturnType; /* Function return type */ FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ @@ -96,7 +96,7 @@ unsigned F_GetParamCount (const Function* F); unsigned F_GetParamSize (const Function* F); /* Return the parameter size for the current function */ -Type* F_GetReturnType (Function* F); +const Type* F_GetReturnType (Function* F); /* Get the return type for the function */ int F_HasVoidReturn (const Function* F); diff --git a/src/cc65/loadexpr.h b/src/cc65/loadexpr.h index 3f13311f1..c9e70e1f6 100644 --- a/src/cc65/loadexpr.h +++ b/src/cc65/loadexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.c b/src/cc65/loop.c index f6c53ddc4..cc8ccdec9 100644 --- a/src/cc65/loop.c +++ b/src/cc65/loop.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/loop.h b/src/cc65/loop.h index fa2859f61..1174443b4 100644 --- a/src/cc65/loop.h +++ b/src/cc65/loop.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 2dd923cf1..f0f7ed36f 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -46,6 +46,7 @@ #include "codegen.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "global.h" #include "litpool.h" #include "scanner.h" diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 1487179f4..78a91a590 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 1c95b3d33..e6a362bf3 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -205,7 +205,7 @@ struct Token { struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ LineInfo* LI; /* Source line where the token comes from */ - Type* Type; /* Type if integer or float constant */ + const Type* Type; /* Type if integer or float constant */ }; extern Token CurTok; /* The current token */ diff --git a/src/cc65/shiftexpr.c b/src/cc65/shiftexpr.c index d7b43dde2..168574a1b 100644 --- a/src/cc65/shiftexpr.c +++ b/src/cc65/shiftexpr.c @@ -64,8 +64,8 @@ void ShiftExpr (struct ExprDesc* Expr) CodeMark Mark1; CodeMark Mark2; token_t Tok; /* The operator token */ - Type* EffType; /* Effective lhs type */ - Type* ResultType; /* Type of the result */ + const Type* EffType; /* Effective lhs type */ + const Type* ResultType; /* Type of the result */ unsigned ExprBits; /* Bits of the lhs operand */ unsigned GenFlags; /* Generator flags */ unsigned ltype; @@ -193,7 +193,7 @@ void ShiftExpr (struct ExprDesc* Expr) ED_IsLocQuasiConst (Expr) && Expr2.IVal >= 8) { - Type* OldType; + const Type* OldType; /* Increase the address by one and decrease the shift count */ ++Expr->IVal; diff --git a/src/cc65/shiftexpr.h b/src/cc65/shiftexpr.h index 2a000fd58..1f1a8c283 100644 --- a/src/cc65/shiftexpr.h +++ b/src/cc65/shiftexpr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.c b/src/cc65/stackptr.c index 1f10e8500..1381d68b4 100644 --- a/src/cc65/stackptr.c +++ b/src/cc65/stackptr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stackptr.h b/src/cc65/stackptr.h index 4f90f8dcc..4e5ea732e 100644 --- a/src/cc65/stackptr.h +++ b/src/cc65/stackptr.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index c1fb6c735..bdc7be006 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) +static void ParseArg (ArgDesc* Arg, const Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -212,9 +212,9 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { /* Argument types: (void*, const void*, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_c_void_p; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; @@ -556,9 +556,9 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memset function */ { /* Argument types: (void*, int, size_t) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; - static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; + static const Type* Arg1Type = type_void_p; + static const Type* Arg2Type = type_int; + static const Type* Arg3Type = type_size_t; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ @@ -782,8 +782,8 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcmp function */ { /* Argument types: (const char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_c_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; @@ -792,10 +792,6 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int IsArray; int Offs; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR | T_QUAL_CONST; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -987,18 +983,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { /* Argument types: (char*, const char*) */ - static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; - static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* Arg1Type = type_char_p; + static const Type* Arg2Type = type_c_char_p; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; - /* Setup the argument type string */ - Arg1Type[1].C = T_CHAR; - Arg2Type[1].C = T_CHAR | T_QUAL_CONST; - /* Argument #1 */ ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); @@ -1188,7 +1180,7 @@ ExitPoint: static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static const Type* ArgType = type_c_char_p; ExprDesc Arg; int IsArray; int IsPtr; @@ -1199,9 +1191,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ED_Init (&Arg); Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; - /* Setup the argument type string */ - ArgType[1].C = T_CHAR | T_QUAL_CONST; - /* Evaluate the parameter */ hie1 (&Arg); diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 9890c5467..ccb113978 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -187,7 +187,7 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE) { + if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { Warning ("Unreachable code"); } diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index ea08a860c..cc790c931 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -284,7 +284,7 @@ SymEntry* GetSymType (const Type* T) */ { if ((IsClassStruct (T) || IsTypeEnum (T))) { - return T->A.P; + return T->A.S; } return 0; } @@ -311,7 +311,7 @@ const char* GetSymTypeName (const Type* T) -void ChangeSymType (SymEntry* Entry, Type* T) +void ChangeSymType (SymEntry* Entry, const Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 0224507ac..56d884bb6 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -325,7 +325,7 @@ const char* GetSymTypeName (const Type* T); ** Note: This may use a static buffer that could be overwritten by other calls. */ -void ChangeSymType (SymEntry* Entry, Type* T); +void ChangeSymType (SymEntry* Entry, const Type* T); /* Change the type of the given symbol */ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6ec255497..4073a38bc 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -173,6 +173,10 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } + } else if (Flags & SC_FUNC) { + if (IS_Get (&WarnUnusedFunc)) { + Warning ("Function '%s' is defined but never used", Entry->Name); + } } else { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 243f3ebf9..bad8b95f1 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index 58f41d3ca..8c9da3445 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -37,6 +37,7 @@ /* cc65 */ #include "error.h" +#include "funcdesc.h" #include "global.h" #include "symtab.h" #include "typecmp.h" @@ -66,8 +67,8 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 8bdef8d03..16f173cc4 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -42,6 +42,7 @@ #include "declare.h" #include "error.h" #include "expr.h" +#include "funcdesc.h" #include "loadexpr.h" #include "typecmp.h" #include "typeconv.h" @@ -57,9 +58,9 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { - Type* OldType; - unsigned OldBits; - unsigned NewBits; + const Type* OldType; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -370,8 +371,8 @@ static void ComposeFuncParamList (const FuncDesc* F1, const FuncDesc* F2) while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) { /* Get the symbol types */ - Type* Type1 = Sym1->Type; - Type* Type2 = Sym2->Type; + const Type* Type1 = Sym1->Type; + const Type* Type2 = Sym2->Type; /* If either of both functions is old style, apply the default ** promotions to the parameter type. diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 351f6077e..1e5c753b5 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -13,66 +13,39 @@ {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} Win32Proj - chrcvt65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index dab77e196..67b7eb087 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -13,66 +13,39 @@ {F657912F-050A-488B-B203-50ED5715CDD7} Win32Proj - cl65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/cl65/error.h b/src/cl65/error.h index b1ff30660..fdf55c758 100644 --- a/src/cl65/error.h +++ b/src/cl65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9b4f18786..9f5959d89 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -13,66 +13,39 @@ {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} Win32Proj - co65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/co65/convert.h b/src/co65/convert.h index 22ef25424..8c7782ff3 100644 --- a/src/co65/convert.h +++ b/src/co65/convert.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.c b/src/co65/error.c index 1c1625207..1fa099c94 100644 --- a/src/co65/error.c +++ b/src/co65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/error.h b/src/co65/error.h index 4fb9d370d..23901e52e 100644 --- a/src/co65/error.h +++ b/src/co65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.c b/src/co65/fileio.c index 9241797c6..18813d5e4 100644 --- a/src/co65/fileio.c +++ b/src/co65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/fileio.h b/src/co65/fileio.h index c5e9a003c..150c4fca7 100644 --- a/src/co65/fileio.h +++ b/src/co65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.c b/src/co65/global.c index bc9b0099b..405cda7d5 100644 --- a/src/co65/global.c +++ b/src/co65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/co65/global.h b/src/co65/global.h index 29c17ca29..8f1e0c4f8 100644 --- a/src/co65/global.h +++ b/src/co65/global.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common.vcxproj b/src/common.vcxproj index eb0dffd66..f7929df2b 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -10,6 +10,40 @@ Win32 + + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + Win32Proj + + + + + + + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + + + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + @@ -106,80 +140,6 @@ - - {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} - Win32Proj - common - 10.0.16299.0 - - - - StaticLibrary - true - v141 - - - false - true - StaticLibrary - v141 - - - - - - - - - - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;_DEBUG - true - - - Windows - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - - - - Level3 - - - true - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_LIB;NDEBUG - true - - - Windows - true - true - true - - - - $(IntDir)$(TargetName)$(TargetExt) - - diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h index c3e589cb2..80dcad491 100644 --- a/src/common/fragdefs.h +++ b/src/common/fragdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/inline.h b/src/common/inline.h index b90b3d1f4..2453547ac 100644 --- a/src/common/inline.h +++ b/src/common/inline.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2001-2005 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/optdefs.h b/src/common/optdefs.h index fae517667..95af8ebba 100644 --- a/src/common/optdefs.h +++ b/src/common/optdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.c b/src/common/segnames.c index bb9aac351..ea8a0125a 100644 --- a/src/common/segnames.c +++ b/src/common/segnames.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/segnames.h b/src/common/segnames.h index 0d57d6ac3..c4401a302 100644 --- a/src/common/segnames.h +++ b/src/common/segnames.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.c b/src/common/strstack.c index 508af178e..29dd10426 100644 --- a/src/common/strstack.c +++ b/src/common/strstack.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/strstack.h b/src/common/strstack.h index d29a47993..b0ff22bfb 100644 --- a/src/common/strstack.h +++ b/src/common/strstack.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index bd2056505..3310eab81 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -39,6 +39,8 @@ #include "check.h" #include "target.h" #include "tgttrans.h" +#include "coll.h" +#include "xmalloc.h" @@ -68,6 +70,9 @@ static unsigned char Tab[256] = { 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, }; +#define MAX_CHARMAP_STACK 16 +static Collection CharmapStack = STATIC_COLLECTION_INITIALIZER; + /*****************************************************************************/ @@ -127,3 +132,52 @@ void TgtTranslateSet (unsigned Index, unsigned char C) CHECK (Index < sizeof (Tab)); Tab[Index] = C; } + + + +int TgtTranslatePush (void) +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) >= MAX_CHARMAP_STACK) { + return 0; + } + + TempTab = xmalloc (sizeof (Tab)); + memcpy (TempTab, Tab, sizeof (Tab)); + + CollAppend (&CharmapStack, TempTab); + return 1; +} + + + +int TgtTranslatePop (void) +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ +{ + unsigned char* TempTab; + + if (CollCount (&CharmapStack) == 0) { + return 0; + } + + TempTab = CollPop (&CharmapStack); + + memcpy (Tab, TempTab, sizeof (Tab)); + + xfree (TempTab); + return 1; +} + + + +int TgtTranslateStackIsEmpty (void) +/* Returns 1 if the internal stack is empty */ +{ + return CollCount (&CharmapStack) == 0; +} diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 46981ec0f..a86d126db 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -70,6 +70,19 @@ void TgtTranslateStrBuf (StrBuf* Buf); void TgtTranslateSet (unsigned Index, unsigned char C); /* Set the translation code for the given character */ +int TgtTranslatePush (void); +/* Pushes the current translation table to the internal stack +** Returns 1 on success, 0 on stack full +*/ + +int TgtTranslatePop (void); +/* Pops a translation table from the internal stack into the current table +** Returns 1 on success, 0 on stack empty +*/ + +int TgtTranslateStackIsEmpty (void); +/* Returns 1 if the internal stack is empty */ + /* End of tgttrans.h */ diff --git a/src/common/va_copy.h b/src/common/va_copy.h index 2f56efa1a..4aa2428db 100644 --- a/src/common/va_copy.h +++ b/src/common/va_copy.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.c b/src/common/xmalloc.c index 327d378fe..192e8fadd 100644 --- a/src/common/xmalloc.c +++ b/src/common/xmalloc.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/common/xmalloc.h b/src/common/xmalloc.h index eb196b6a1..fc919a16f 100644 --- a/src/common/xmalloc.h +++ b/src/common/xmalloc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstraße 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 090c3030f..a40daf1d6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -13,66 +13,39 @@ {0BCFB793-2B25-40E2-B265-75848824AC4C} Win32Proj - da65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/da65/asminc.h b/src/da65/asminc.h index bf48710e9..6d58cd155 100644 --- a/src/da65/asminc.h +++ b/src/da65/asminc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/code.h b/src/da65/code.h index 0d21e61e1..50e68ebdf 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.c b/src/da65/comments.c index 64b64ca28..cf0b9d4e9 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/comments.h b/src/da65/comments.h index 1b8bc1771..1d95111a9 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/error.h b/src/da65/error.h index d0221bcc4..8027b3c1f 100644 --- a/src/da65/error.h +++ b/src/da65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/global.c b/src/da65/global.c index 7df1bd977..e258aecdd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2006 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/infofile.h b/src/da65/infofile.h index b8b3f53a8..49ddfcd5d 100644 --- a/src/da65/infofile.h +++ b/src/da65/infofile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc4510.h b/src/da65/opc4510.h index 10735952c..a87254cd1 100644 --- a/src/da65/opc4510.h +++ b/src/da65/opc4510.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc6502.h b/src/da65/opc6502.h index c890e241b..f9d03c085 100644 --- a/src/da65/opc6502.h +++ b/src/da65/opc6502.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65816.h b/src/da65/opc65816.h index 12ffc4a37..341fbf085 100644 --- a/src/da65/opc65816.h +++ b/src/da65/opc65816.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65c02.h b/src/da65/opc65c02.h index 38138aa51..aa2fa9756 100644 --- a/src/da65/opc65c02.h +++ b/src/da65/opc65c02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opc65sc02.h b/src/da65/opc65sc02.h index 391f425ea..c00a8e91f 100644 --- a/src/da65/opc65sc02.h +++ b/src/da65/opc65sc02.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opcdesc.h b/src/da65/opcdesc.h index 7913131cd..399a0962d 100644 --- a/src/da65/opcdesc.h +++ b/src/da65/opcdesc.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/da65/opctable.h b/src/da65/opctable.h index d5c81b216..69a64db9c 100644 --- a/src/da65/opctable.h +++ b/src/da65/opctable.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2000-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index 841ec635a..fbd44fa3e 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -13,66 +13,39 @@ {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} Win32Proj - grc65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index a78f3128b..9e4b08621 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -13,66 +13,39 @@ {26C749A0-814C-47A2-9D36-AE92AE932FE4} Win32Proj - ld65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/ld65/dbgfile.h b/src/ld65/dbgfile.h index b8e1a534f..cabb60f8a 100644 --- a/src/ld65/dbgfile.h +++ b/src/ld65/dbgfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/error.h b/src/ld65/error.h index b49d8919c..75b8e0bc1 100644 --- a/src/ld65/error.h +++ b/src/ld65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/ld65/o65.h b/src/ld65/o65.h index 2112537ff..68ed94ba7 100644 --- a/src/ld65/o65.h +++ b/src/ld65/o65.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1999-2005 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 03ea41fce..1a1527067 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -13,66 +13,39 @@ {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} Win32Proj - od65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/od65/error.h b/src/od65/error.h index 8e1469a34..8a3ac0652 100644 --- a/src/od65/error.h +++ b/src/od65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 068c4d9a3..af5559f6b 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 9dc61e53f..97fc3855a 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -13,67 +13,39 @@ {002A366E-2863-46A8-BDDE-DDF534AAEC73} Win32Proj - sim65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/src/sim65/error.c b/src/sim65/error.c index 30d90c700..441b07d2a 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/error.h b/src/sim65/error.h index cbb785875..ea54fa048 100644 --- a/src/sim65/error.h +++ b/src/sim65/error.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 603a07e9a..e73bd3400 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 99c28fa02..bfa38e047 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 2013-2013 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 3b770ec57..1b7a18427 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -13,66 +13,39 @@ {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} Win32Proj - sp65 - 10.0.16299.0 + + + true - v141 false - true - v141 - - - - - - - true - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\bin\ - $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ - - - Level3 - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG - common - true + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) Console - true - $(IntDir)..\..\common\$(Configuration)\common.lib - Level3 - - - _CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG - common - true + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) Console - false - $(IntDir)..\..\common\$(Configuration)\common.lib diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 5761abcfd..000000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.o diff --git a/test/todo/bug1462.c b/test/todo/bug1462.c new file mode 100644 index 000000000..aec990cde --- /dev/null +++ b/test/todo/bug1462.c @@ -0,0 +1,67 @@ + +/* issue #1462 - Bit-fields are still broken */ + +#include + +typedef struct { + signed int a : 3; + signed int b : 3; + signed int c : 3; +} T; + +int failures = 0; + +void test() +{ + T a = {2, 5, -1}; + T b = {1, 4, -1}; + T m[1] = {{6, 3, -1}}; + T *p = &a; + + a.c += b.a; + p->c += b.b; + m->c += b.c; + + if (a.c != -4) { + ++failures; + } + printf("%d\n", a.c); + + if (p->c != -4) { + ++failures; + } + printf("%d\n", p->c); + + if (m->c != -2) { + ++failures; + } + printf("%d\n", m->c); + + ++a.a; + p->b++; + m->c--; + + if (a.a != 3) { + ++failures; + } + printf("%d\n", a.a); + + if (p->b != -2) { + ++failures; + } + printf("%d\n", p->b); + + if (m->c != -3) { + ++failures; + } + printf("%d\n", m->c); + + printf("Failures: %d\n", failures); +} + +int main(void) +{ + test(); + return failures; +} + diff --git a/test/misc/bug1209-ind-goto-rev.c b/test/val/bug1209-ind-goto-rev.c similarity index 100% rename from test/misc/bug1209-ind-goto-rev.c rename to test/val/bug1209-ind-goto-rev.c diff --git a/test/val/bug1451.c b/test/val/bug1451.c new file mode 100644 index 000000000..c00f19903 --- /dev/null +++ b/test/val/bug1451.c @@ -0,0 +1,39 @@ +/* Bug #1451 - local struct field access via the address of the struct */ + +#include + +typedef struct { + int a; + int b; +} S; + +int failures = 0; + +int main(void) +{ + S a = {2, 5}; + S b = {1, 4}; + S m[1] = {{6, 3}}; + S *p = &a; + + (&a)->a += b.a; + p->b += b.b; + m->a += b.a; + + if ((&a)->a != 3) { + ++failures; + printf("Expected 3, got %d\n", (&a)->a); + } + + if (p->b != 9) { + ++failures; + printf("Expected 9, got %d\n", p->b); + } + + if (m->a != 7) { + ++failures; + printf("Expected 7, got %d\n", m->a); + } + + return failures; +} diff --git a/test/val/pr1461.c b/test/val/pr1461.c new file mode 100644 index 000000000..dae6b2999 --- /dev/null +++ b/test/val/pr1461.c @@ -0,0 +1,53 @@ + +/* pr#1461 Fixed pointer subtraction in certain very rare cases */ + +#include +#include + +static int err = 0; + +static int a[1], *p; +static unsigned int i1, i2; + +int test1(void) +{ + p = a - (int)a; + printf("a: %p - (int)a: 0x%x = p: %p\n", a, (int)a, p); + printf("i1: 0x%x - i2: 0x%x = p: %p\n", i1, i2, i1 - i2); + if ((int)p != (i1 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int test2(void) +{ + p = p - (int)a; + printf("p: %p - (int)a: 0x%x = p: %p\n", p, (int)a, p); + printf("p: %p - i2: 0x%x = p: %p\n", p, i2, 0x1234 - i2); + if ((int)p != (0x1234 - i2)) { + printf("-> failed\n"); + return 1; + } + return 0; +} + +int main(void) +{ + a[0] = 0x4711; + i1 = (int)a; + i2 = i1 << 1; + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test1(); + + p = (int*)0x1234; + printf("p: %p &a[0]: %p a: %p (int)a: 0x%x i1: 0x%x i2: 0x%x\n", p, &a[0], a, (int)a, i1, i2); + + err += test2(); + + return err; +}