Merge branch 'master' into c_sp
This commit is contained in:
4
.github/checks/sorted.sh
vendored
4
.github/checks/sorted.sh
vendored
@@ -13,8 +13,8 @@ function checkarray_quoted_name
|
||||
START="\\/\\* BEGIN SORTED.SH \\*\\/"
|
||||
END="\\/\\* END SORTED.SH \\*\\/"
|
||||
|
||||
awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \
|
||||
sed -e 's:\(.*\) ##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp
|
||||
awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \
|
||||
sed -e 's:\(.*\)##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp
|
||||
|
||||
if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then
|
||||
echo "error: "$1" table is empty"
|
||||
|
||||
4
.github/checks/sorted_codeopt.sh
vendored
4
.github/checks/sorted_codeopt.sh
vendored
@@ -13,7 +13,7 @@ function checkarray
|
||||
START="\\/\\* BEGIN DECL SORTED_CODEOPT.SH \\*\\/"
|
||||
END="\\/\\* END DECL SORTED_CODEOPT.SH \\*\\/"
|
||||
|
||||
awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \
|
||||
awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \
|
||||
sed -e 's:\(.*##\).*"\(.*\)",.*:\1\2:g' > .a.tmp
|
||||
|
||||
if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then
|
||||
@@ -33,7 +33,7 @@ function checkarray
|
||||
START="\\/\\* BEGIN SORTED_CODEOPT.SH \\*\\/"
|
||||
END="\\/\\* END SORTED_CODEOPT.SH \\*\\/"
|
||||
|
||||
awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \
|
||||
awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \
|
||||
sed -e 's:\(.*##\).*&D\(.*\),.*:\1\2:g' > .b.tmp
|
||||
|
||||
if [[ -z $(grep '[^[:space:]]' .b.tmp) ]] ; then
|
||||
|
||||
4
.github/checks/sorted_opcodes.sh
vendored
4
.github/checks/sorted_opcodes.sh
vendored
@@ -13,10 +13,10 @@ function checkarray_quoted_name
|
||||
START="\\/\\* BEGIN SORTED_OPCODES.SH \\*\\/"
|
||||
END="\\/\\* END SORTED_OPCODES.SH \\*\\/"
|
||||
|
||||
awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \
|
||||
awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \
|
||||
sed 's:/\*.*::g' | \
|
||||
grep '".*",' | \
|
||||
sed -e 's:\(.*\) ##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp
|
||||
sed -e 's:\(.*\)##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp
|
||||
|
||||
if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then
|
||||
echo "error: "$1" table is empty"
|
||||
|
||||
@@ -24,6 +24,8 @@ DOSWARM := $03D0 ; DOS warmstart vector
|
||||
BRKVec := $03F0 ; Break vector
|
||||
SOFTEV := $03F2 ; Vector for warm start
|
||||
PWREDUP := $03F4 ; This must be = EOR #$A5 of SOFTEV+1
|
||||
ROM_RST := $FFFC ; 6502 reset vector
|
||||
ROM_IRQ := $FFFE ; 6502 IRQ vector
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; 80 column firmware
|
||||
|
||||
56
cfg/plus4-hires.cfg
Normal file
56
cfg/plus4-hires.cfg
Normal file
@@ -0,0 +1,56 @@
|
||||
# Linker configuration that allows for a hi-res bitmap at $C000-$DF3F, but
|
||||
# puts the stack (and a "HIBSS" segment) in the remaining RAM at $DF40-$FD00.
|
||||
|
||||
FEATURES {
|
||||
STARTADDRESS: default = $1001;
|
||||
}
|
||||
SYMBOLS {
|
||||
__LOADADDR__: type = import;
|
||||
__EXEHDR__: type = import;
|
||||
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
||||
__HIMEM__: type = weak, value = $FD00;
|
||||
}
|
||||
MEMORY {
|
||||
# Reserve 8000 bytes at $C000 for 320x200 bitmap
|
||||
RESERVED: file = "", define = yes, start = $C000, size = 8000;
|
||||
|
||||
ZP: file = "", define = yes, start = $0002, size = $001A;
|
||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
||||
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __RESERVED_START__ - __MAIN_START__;
|
||||
|
||||
# Space between bitmap and top of memory
|
||||
HIRAM: file = "", define = yes, start = __RESERVED_LAST__, size = __HIMEM__ - __HIRAM_START__ - __STACKSIZE__;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
STARTUP: load = MAIN, type = ro;
|
||||
LOWCODE: load = MAIN, type = ro, optional = yes;
|
||||
CODE: load = MAIN, type = ro;
|
||||
ONCE: load = MAIN, type = ro, optional = yes;
|
||||
RODATA: load = MAIN, type = ro;
|
||||
DATA: load = MAIN, type = rw;
|
||||
INIT: load = MAIN, type = bss;
|
||||
BSS: load = MAIN, type = bss, define = yes;
|
||||
|
||||
# Allow data between bitmap and top of memory to be used as a second BSS
|
||||
# space. Define symbols for it so that it can be supplied to _heapadd().
|
||||
HIBSS: load = HIRAM, type = bss, optional = yes, define = yes;
|
||||
}
|
||||
FEATURES {
|
||||
CONDES: type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__,
|
||||
segment = ONCE;
|
||||
CONDES: type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__,
|
||||
segment = RODATA;
|
||||
CONDES: type = interruptor,
|
||||
label = __INTERRUPTOR_TABLE__,
|
||||
count = __INTERRUPTOR_COUNT__,
|
||||
segment = RODATA,
|
||||
import = __CALLIRQ__;
|
||||
}
|
||||
@@ -87,7 +87,7 @@ several useful settings:
|
||||
exit then a plain vanilla ProDOS 8 doesn't make use of the Language Card bank
|
||||
2 at all.
|
||||
|
||||
<tag>LC address: $D000, LC size: $3000</tag>
|
||||
<tag>LC address: $D000, LC size: $2FFC</tag>
|
||||
For plain vanilla DOS 3.3 which doesn't make use of the Language Card at all.
|
||||
|
||||
</descrip><p>
|
||||
|
||||
@@ -88,7 +88,7 @@ several useful settings:
|
||||
exit then a plain vanilla ProDOS 8 doesn't make use of the Language Card bank
|
||||
2 at all.
|
||||
|
||||
<tag>LC address: $D000, LC size: $3000</tag>
|
||||
<tag>LC address: $D000, LC size: $2FFC</tag>
|
||||
For plain vanilla DOS 3.3 which doesn't make use of the Language Card at all.
|
||||
|
||||
</descrip><p>
|
||||
|
||||
@@ -3234,6 +3234,12 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
|
||||
(see <tt><ref id=".P02" name=".P02"></tt> command).
|
||||
|
||||
|
||||
<sect1><tt>.IFP02X</tt><label id=".IFP02X"><p>
|
||||
|
||||
Conditional assembly: Check if the assembler is currently in 6502X mode
|
||||
(see <tt><ref id=".P02X" name=".P02X"></tt> command).
|
||||
|
||||
|
||||
<sect1><tt>.IFP4510</tt><label id=".IFP4510"><p>
|
||||
|
||||
Conditional assembly: Check if the assembler is currently in 4510 mode
|
||||
@@ -3621,6 +3627,16 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE"
|
||||
<tt><ref id=".P4510" name=".P4510"></tt>
|
||||
|
||||
|
||||
<sect1><tt>.P02X</tt><label id=".P02X"><p>
|
||||
|
||||
Enable the 6502X instruction set, disable 65SC02, 65C02 and 65816
|
||||
instructions.
|
||||
|
||||
See: <tt><ref id=".PC02" name=".PC02"></tt>, <tt><ref id=".PSC02"
|
||||
name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt> and
|
||||
<tt><ref id=".P4510" name=".P4510"></tt>
|
||||
|
||||
|
||||
<sect1><tt>.P4510</tt><label id=".P4510"><p>
|
||||
|
||||
Enable the 4510 instruction set. This is a superset of the 65C02 and
|
||||
@@ -4016,11 +4032,13 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE"
|
||||
|
||||
See: <tt><ref id=".CPU" name=".CPU"></tt>,
|
||||
<tt><ref id=".IFP02" name=".IFP02"></tt>,
|
||||
<tt><ref id=".IFP02X" name=".IFP02X"></tt>,
|
||||
<tt><ref id=".IFPDTV" name=".IFPDTV"></tt>,
|
||||
<tt><ref id=".IFP816" name=".IFP816"></tt>,
|
||||
<tt><ref id=".IFPC02" name=".IFPC02"></tt>,
|
||||
<tt><ref id=".IFPSC02" name=".IFPSC02"></tt>,
|
||||
<tt><ref id=".P02" name=".P02"></tt>,
|
||||
<tt><ref id=".P02X" name=".P02X"></tt>,
|
||||
<tt><ref id=".P816" name=".P816"></tt>,
|
||||
<tt><ref id=".P4510" name=".P4510"></tt>,
|
||||
<tt><ref id=".PC02" name=".PC02"></tt>,
|
||||
|
||||
@@ -63,6 +63,8 @@ Short options:
|
||||
-V Print the compiler version number
|
||||
-W [-+]warning[,...] Control warnings ('-' disables, '+' enables)
|
||||
-d Debug mode
|
||||
-dM Output all user macros (needs -E)
|
||||
-dP Output all predefined macros (needs -E)
|
||||
-g Add debug info to object file
|
||||
-h Help (this text)
|
||||
-j Default characters are signed
|
||||
@@ -199,6 +201,28 @@ Here is a description of all the command line options:
|
||||
Enables debug mode, for debugging the behavior of cc65.
|
||||
|
||||
|
||||
|
||||
<label id="option-dM">
|
||||
<tag><tt>-dM</tt></tag>
|
||||
|
||||
When used with -E, will output <tt>#define</tt> directives for all the user
|
||||
macros defined during execution of the preprocessor. This does not include
|
||||
macros defined by the compiler.
|
||||
|
||||
Note: Can be combined with <tt/<ref id="option-dP" name="-dP">/ by using
|
||||
<tt/-dMP/.
|
||||
|
||||
|
||||
<label id="option-dP">
|
||||
<tag><tt>-dP</tt></tag>
|
||||
|
||||
When used with -E, will output <tt>#define</tt> directives for all the macros
|
||||
defined by the compiler itself. This does not include any user defined macros.
|
||||
|
||||
Note: Can be combined with <tt/<ref id="option-dM" name="-dM">/ by using
|
||||
<tt/-dMP/.
|
||||
|
||||
|
||||
<tag><tt>--debug-tables name</tt></tag>
|
||||
|
||||
Writes symbol table information to a file, which includes details on structs, unions
|
||||
|
||||
@@ -165,8 +165,26 @@ The names in the parentheses denote the symbols to be used for static linking of
|
||||
|
||||
<sect1>Graphics drivers<p>
|
||||
|
||||
No graphics drivers are currently available for the Plus/4.
|
||||
<descrip>
|
||||
<tag><tt/ted-hi.tgi (ted_hi_tgi)/</tag>
|
||||
This driver features a resolution of 320*200 with two colors and an
|
||||
adjustable palette (that means that the two colors can be chosen out of a
|
||||
palette of the 121 TED colors).
|
||||
|
||||
Note that the text-mode character matrix and color data are destroyed by this
|
||||
driver. The driver calls the Kernal <tt/CLRSCR/ routine to return the text
|
||||
screen to a usable (if empty) state on <tt/tgi_done()/.
|
||||
|
||||
This driver places the bitmap at $C000-$E000. Programs using
|
||||
this driver must either be linked with the option <tt/-D
|
||||
__HIMEM__=$C000/, or use the <tt/plus4-hires.cfg/ linker configuration.
|
||||
|
||||
The <tt/plus4-hires.cfg/ is preferable, as it allows the stack to remain at
|
||||
$FCFF, and exposes the remaining high memory from the end of the bitmap
|
||||
to the stack top as a <tt/HIBSS/ segment that can be used by the programmer,
|
||||
or given to <tt/_heapadd()/ (using the symbols <tt/_HIBSS_START__/ and
|
||||
<tt/_HIBSS_SIZE__/).
|
||||
</descrip><p>
|
||||
|
||||
<sect1>Extended memory drivers<p>
|
||||
|
||||
|
||||
@@ -110,7 +110,23 @@
|
||||
#define COLOR_LIGHTBLUE (BCOLOR_LIGHTBLUE | CATTR_LUMA7)
|
||||
#define COLOR_GRAY3 (BCOLOR_WHITE | CATTR_LUMA5)
|
||||
|
||||
|
||||
/* TGI color defines */
|
||||
#define TGI_COLOR_BLACK (BCOLOR_BLACK)
|
||||
#define TGI_COLOR_WHITE (BCOLOR_WHITE | CATTR_LUMA7)
|
||||
#define TGI_COLOR_RED (BCOLOR_RED | CATTR_LUMA4)
|
||||
#define TGI_COLOR_CYAN (BCOLOR_CYAN | CATTR_LUMA7)
|
||||
#define TGI_COLOR_PURPLE (BCOLOR_LIGHTVIOLET | CATTR_LUMA7)
|
||||
#define TGI_COLOR_GREEN (BCOLOR_GREEN | CATTR_LUMA7)
|
||||
#define TGI_COLOR_BLUE (BCOLOR_BLUE | CATTR_LUMA7)
|
||||
#define TGI_COLOR_YELLOW (BCOLOR_YELLOW | CATTR_LUMA7)
|
||||
#define TGI_COLOR_ORANGE (BCOLOR_ORANGE | CATTR_LUMA7)
|
||||
#define TGI_COLOR_BROWN (BCOLOR_BROWN | CATTR_LUMA7)
|
||||
#define TGI_COLOR_LIGHTRED (BCOLOR_RED | CATTR_LUMA7)
|
||||
#define TGI_COLOR_GRAY1 (BCOLOR_WHITE | CATTR_LUMA1)
|
||||
#define TGI_COLOR_GRAY2 (BCOLOR_WHITE | CATTR_LUMA3)
|
||||
#define TGI_COLOR_LIGHTGREEN (BCOLOR_LIGHTGREEN | CATTR_LUMA7)
|
||||
#define TGI_COLOR_LIGHTBLUE (BCOLOR_LIGHTBLUE | CATTR_LUMA7)
|
||||
#define TGI_COLOR_GRAY3 (BCOLOR_WHITE | CATTR_LUMA5)
|
||||
|
||||
/* Masks for joy_read */
|
||||
#define JOY_UP_MASK 0x01
|
||||
|
||||
@@ -57,8 +57,7 @@
|
||||
/* The addresses of the static drivers */
|
||||
extern void plus4_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */
|
||||
extern void plus4_stdser_ser[]; /* Referred to by ser_static_stddrv[] */
|
||||
|
||||
|
||||
extern void ted_hi_tgi[];
|
||||
|
||||
/* End of plus4.h */
|
||||
#endif
|
||||
|
||||
@@ -58,6 +58,7 @@ init: ldx #zpspace-1
|
||||
; Check for ProDOS.
|
||||
ldy $BF00 ; MLI call entry point
|
||||
cpy #$4C ; Is MLI present? (JMP opcode)
|
||||
php ; Remember whether we're running ProDOS
|
||||
bne basic
|
||||
|
||||
; Check the ProDOS system bit map.
|
||||
@@ -99,7 +100,20 @@ basic: lda HIMEM
|
||||
bit $C081
|
||||
bit $C081
|
||||
|
||||
; Set the source start address.
|
||||
plp ; Are we running ProDOS?
|
||||
beq :+ ; Yes, no need to patch vectors
|
||||
|
||||
lda #<reset_6502
|
||||
ldx #>reset_6502
|
||||
sta ROM_RST
|
||||
stx ROM_RST+1
|
||||
|
||||
lda #<irq_6502
|
||||
ldx #>irq_6502
|
||||
sta ROM_IRQ
|
||||
stx ROM_IRQ+1
|
||||
|
||||
: ; Set the source start address.
|
||||
; Aka __LC_LOAD__ iff segment LC exists.
|
||||
lda #<(__ONCE_LOAD__ + __ONCE_SIZE__)
|
||||
ldy #>(__ONCE_LOAD__ + __ONCE_SIZE__)
|
||||
@@ -144,6 +158,14 @@ quit: jsr $BF00 ; MLI call entry point
|
||||
.byte $65 ; Quit
|
||||
.word q_param
|
||||
|
||||
reset_6502: ; Used with DOS3.3 programs
|
||||
bit $C082 ; Switch in ROM
|
||||
jmp (ROM_RST) ; Jump to ROM's RESET vector
|
||||
|
||||
irq_6502: ; Used with DOS3.3 programs
|
||||
bit $C082 ; Switch in ROM
|
||||
jmp (ROM_IRQ) ; Jump to ROM's IRQ/BRK vector
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.rodata
|
||||
|
||||
@@ -18,11 +18,16 @@ _cgetc: lda KEY_COUNT ; Get number of characters
|
||||
ora FKEY_COUNT ; Or with number of function key chars
|
||||
bne L2 ; Jump if there are already chars waiting
|
||||
|
||||
lda #%00100000
|
||||
bit $FF06
|
||||
bne L2 ; always disable cursor if in bitmap mode
|
||||
|
||||
; Switch on the cursor if needed
|
||||
|
||||
ldy CURS_X
|
||||
lda (CRAM_PTR),y ; Get current char
|
||||
pha ; And save it
|
||||
|
||||
lda CHARCOLOR
|
||||
sta (CRAM_PTR),y
|
||||
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
.import callirq_y, initlib, donelib
|
||||
.import callmain, zerobss
|
||||
.import __INTERRUPTOR_COUNT__
|
||||
.import __MAIN_START__, __MAIN_SIZE__ ; Linker generated
|
||||
.import __STACKSIZE__ ; Linker generated
|
||||
.import __HIMEM__ ; Linker generated
|
||||
.importzp ST
|
||||
|
||||
.include "zeropage.inc"
|
||||
@@ -52,19 +51,28 @@ L1: lda c_sp,x
|
||||
tsx
|
||||
stx spsave ; Save system stk ptr
|
||||
|
||||
lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
|
||||
ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
|
||||
lda #<__HIMEM__
|
||||
ldx #>__HIMEM__
|
||||
sta c_sp
|
||||
stx c_sp+1
|
||||
|
||||
; Set up the IRQ vector in the banked RAM; and, switch off the ROM.
|
||||
|
||||
ldx #<IRQ
|
||||
ldy #>IRQ
|
||||
lda #<IRQ
|
||||
ldx #>IRQ
|
||||
sei ; No ints, handler not yet in place
|
||||
sta ENABLE_RAM
|
||||
stx $FFFE ; Install interrupt handler
|
||||
sty $FFFF
|
||||
sta $FFFE ; Install interrupt handler
|
||||
stx $FFFF
|
||||
lda IRQVec
|
||||
ldx IRQVec+1
|
||||
sta IRQInd+1
|
||||
stx IRQInd+2
|
||||
lda #<IRQStub
|
||||
ldx #>IRQStub
|
||||
sta IRQVec
|
||||
stx IRQVec+1
|
||||
|
||||
cli ; Allow interrupts
|
||||
|
||||
; Clear the BSS data.
|
||||
@@ -95,6 +103,13 @@ _exit: pha ; Save the return code
|
||||
lda #0
|
||||
sta irqcount ; Disable custom IRQ handlers
|
||||
|
||||
sei
|
||||
ldx IRQInd+1
|
||||
ldy IRQInd+2
|
||||
stx IRQVec
|
||||
sty IRQVec+1
|
||||
cli
|
||||
|
||||
; Copy back the zero-page stuff.
|
||||
|
||||
ldx #zpspace-1
|
||||
@@ -122,9 +137,13 @@ L2: lda zpsave,x
|
||||
; IRQ handler. The handler in the ROM enables the Kernal, and jumps to
|
||||
; $CE00, where the ROM code checks for a BRK or IRQ, and branches via the
|
||||
; indirect vectors at $314/$316.
|
||||
; To make our stub as fast as possible, we skip the whole part of the ROM
|
||||
; handler, and jump to the indirect vectors directly. We do also call our
|
||||
; own interrupt handlers if we have any; so, they need not use $314.
|
||||
;
|
||||
; When RAM is banked in, we skip the whole part of the ROM handler, and jump to
|
||||
; the indirect vectors directly, after calling our own interrupt handlers.
|
||||
;
|
||||
; When ROM is banked in, a stub installed in the $314 indirect vector ensures
|
||||
; that our interrupt handlers are still called (otherwise, interrupts that are
|
||||
; not serviced by the ROM handler may cause a deadlock).
|
||||
|
||||
.segment "LOWCODE"
|
||||
|
||||
@@ -139,15 +158,6 @@ IRQ: cld ; Just to be sure
|
||||
and #$10 ; Test for BRK bit
|
||||
bne dobreak
|
||||
|
||||
; It's an IRQ; and, RAM is enabled. If we have handlers, call them. We will use
|
||||
; a flag here instead of loading __INTERRUPTOR_COUNT__ directly, since the
|
||||
; condes function is not reentrant. The irqcount flag will be set/reset from
|
||||
; the main code, to avoid races.
|
||||
|
||||
ldy irqcount
|
||||
beq @L1
|
||||
jsr callirq_y ; Call the IRQ functions
|
||||
|
||||
; Since the ROM handler will end with an RTI, we have to fake an IRQ return
|
||||
; on the stack, so that we get control of the CPU after the ROM handler,
|
||||
; and can switch back to RAM.
|
||||
@@ -161,7 +171,7 @@ IRQ: cld ; Just to be sure
|
||||
pha ; Push faked X register
|
||||
pha ; Push faked Y register
|
||||
sta ENABLE_ROM ; Switch to ROM
|
||||
jmp (IRQVec) ; Jump indirect to Kernal IRQ handler
|
||||
jmp (IRQVec) ; Jump indirect to IRQ stub
|
||||
|
||||
irq_ret:
|
||||
sta ENABLE_RAM ; Switch back to RAM
|
||||
@@ -183,6 +193,22 @@ nohandler:
|
||||
sta ENABLE_ROM
|
||||
jmp (BRKVec) ; Jump indirect to the break vector
|
||||
|
||||
|
||||
; IRQ stub installed at $314, called by our handler above if RAM is banked in,
|
||||
; or the Kernal IRQ handler if ROM is banked in.
|
||||
|
||||
; If we have handlers, call them. We will use a flag here instead of loading
|
||||
; __INTERRUPTOR_COUNT__ directly, since the condes function is not reentrant.
|
||||
; The irqcount flag will be set/reset from the main code, to avoid races.
|
||||
IRQStub:
|
||||
cld ; Just to be sure
|
||||
sta ENABLE_RAM
|
||||
ldy irqcount
|
||||
beq @L1
|
||||
jsr callirq_y ; Call the IRQ functions
|
||||
@L1: sta ENABLE_ROM
|
||||
jmp (IRQInd+1) ; Jump to the saved IRQ vector
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
; Oliver Schmidt, 2013-05-31
|
||||
;
|
||||
|
||||
.export joy_libref, ser_libref
|
||||
.export joy_libref, ser_libref, tgi_libref
|
||||
.import _exit
|
||||
|
||||
joy_libref := _exit
|
||||
ser_libref := _exit
|
||||
tgi_libref := _exit
|
||||
|
||||
@@ -64,15 +64,15 @@ ACIA_STATUS := ACIA+1 ; Status register
|
||||
ACIA_CMD := ACIA+2 ; Command register
|
||||
ACIA_CTRL := ACIA+3 ; Control register
|
||||
|
||||
RecvHead := $07D1 ; Head of receive buffer
|
||||
RecvTail := $07D2 ; Tail of receive buffer
|
||||
RecvFreeCnt := $07D3 ; Number of bytes in receive buffer
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
; Global variables
|
||||
;
|
||||
|
||||
.bss
|
||||
RecvHead: .res 1 ; Head of receive buffer
|
||||
RecvTail: .res 1 ; Tail of receive buffer
|
||||
RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
|
||||
SendHead: .res 1 ; Head of send buffer
|
||||
SendTail: .res 1 ; Tail of send buffer
|
||||
SendFreeCnt: .res 1 ; Number of bytes in send buffer
|
||||
@@ -88,7 +88,7 @@ SendBuf: .res 256
|
||||
|
||||
; Tables used to translate RS232 params into register values
|
||||
|
||||
BaudTable: ; bit7 = 1 means setting is invalid
|
||||
BaudTable: ; Bit7 = 1 means setting is invalid
|
||||
.byte $FF ; SER_BAUD_45_5
|
||||
.byte $01 ; SER_BAUD_50
|
||||
.byte $02 ; SER_BAUD_75
|
||||
@@ -354,26 +354,27 @@ SER_IOCTL:
|
||||
;
|
||||
|
||||
SER_IRQ:
|
||||
lda ACIA_STATUS ; Check ACIA status for receive interrupt
|
||||
and #$08
|
||||
beq @L9 ; Jump if no ACIA interrupt (carry still clear)
|
||||
lda ACIA_DATA ; Get byte from ACIA
|
||||
ldx RecvFreeCnt ; Check if we have free space left
|
||||
beq @L1 ; Jump if no space in receive buffer
|
||||
ldy RecvTail ; Load buffer pointer
|
||||
sta RecvBuf,y ; Store received byte in buffer
|
||||
inc RecvTail ; Increment buffer pointer
|
||||
dec RecvFreeCnt ; Decrement free space counter
|
||||
cpx #33 ; Check for buffer space low
|
||||
bcc @L1 ; Assert flow control if buffer space low
|
||||
lda ACIA_STATUS ; (4) Check for byte received
|
||||
and #$08 ; (2)
|
||||
beq @L9 ; (2*)
|
||||
|
||||
lda ACIA_DATA ; (4) Get byte and put into receive buffer
|
||||
ldy RecvTail ; (4)
|
||||
ldx RecvFreeCnt ; (4)
|
||||
beq @L3 ; (2*) Jump if no space in receive buffer
|
||||
sta RecvBuf,y ; (5)
|
||||
inc RecvTail ; (6)
|
||||
dec RecvFreeCnt ; (6)
|
||||
cpx #33 ; (2) Check for buffer space low
|
||||
bcc @L2 ; (2*)
|
||||
rts ; Return with carry set (interrupt handled)
|
||||
|
||||
; Assert flow control if buffer space too low
|
||||
|
||||
@L1: lda RtsOff
|
||||
sta ACIA_CMD
|
||||
sta Stopped
|
||||
sec ; Interrupt handled
|
||||
@L2: lda RtsOff ; (3)
|
||||
sta ACIA_CMD ; (4)
|
||||
sta Stopped ; (3)
|
||||
@L3: sec ; Interrupt handled
|
||||
@L9: rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
860
libsrc/plus4/tgi/ted-hi.s
Normal file
860
libsrc/plus4/tgi/ted-hi.s
Normal file
@@ -0,0 +1,860 @@
|
||||
;
|
||||
; Graphics driver for the 320x200x2 mode on Commodore Plus/4 systems.
|
||||
;
|
||||
; Luminance/Chrominance matrices at $800/$C00, overwriting text-mode character
|
||||
; and color data. Bitmap is at $C000-$DF3F. Programs using this driver should
|
||||
; either be linked with the option '-D __HIMEM__=0xC000'.
|
||||
;
|
||||
; Based on the c64-hi TGI driver, which in turn was based on Stephen L. Judd's
|
||||
; GRLIB code.
|
||||
;
|
||||
; 2017-01-13, Greg King
|
||||
; 2018-03-13, Sven Klose
|
||||
; 2019-10-23, Richard Halkyard
|
||||
;
|
||||
.include "zeropage.inc"
|
||||
|
||||
.include "tgi-kernel.inc"
|
||||
.include "tgi-error.inc"
|
||||
|
||||
.include "cbm_kernal.inc"
|
||||
.include "plus4.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table and constants.
|
||||
|
||||
module_header _ted_hi_tgi
|
||||
|
||||
; First part of the header is a structure that has a magic and defines the
|
||||
; capabilities of the driver
|
||||
|
||||
.byte $74, $67, $69 ; "tgi"
|
||||
.byte TGI_API_VERSION ; TGI API version number
|
||||
.addr $0000 ; Library reference
|
||||
.word 320 ; X resolution
|
||||
.word 200 ; Y resolution
|
||||
.byte 2 ; Number of drawing colors
|
||||
.byte 1 ; Number of screens available
|
||||
.byte 8 ; System font X size
|
||||
.byte 8 ; System font Y size
|
||||
.word $00D4 ; Aspect ratio (based on 4/3 display)
|
||||
.byte 0 ; TGI driver flags
|
||||
|
||||
; Next comes the jump table. With the exception of IRQ, all entries must be
|
||||
; valid and may point to an RTS for test versions (function not implemented).
|
||||
|
||||
.addr INSTALL
|
||||
.addr UNINSTALL
|
||||
.addr INIT
|
||||
.addr DONE
|
||||
.addr GETERROR
|
||||
.addr CONTROL
|
||||
.addr CLEAR
|
||||
.addr SETVIEWPAGE
|
||||
.addr SETDRAWPAGE
|
||||
.addr SETCOLOR
|
||||
.addr SETPALETTE
|
||||
.addr GETPALETTE
|
||||
.addr GETDEFPALETTE
|
||||
.addr SETPIXEL
|
||||
.addr GETPIXEL
|
||||
.addr LINE
|
||||
.addr BAR
|
||||
.addr TEXTSTYLE
|
||||
.addr OUTTEXT
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Data.
|
||||
|
||||
; Variables mapped to the zero page segment variables. Some of these are
|
||||
; used for passing parameters to the driver.
|
||||
|
||||
X1 := ptr1
|
||||
Y1 := ptr2
|
||||
X2 := ptr3
|
||||
Y2 := ptr4
|
||||
TEXT := ptr3
|
||||
|
||||
TEMP := tmp4
|
||||
TEMP2 := sreg
|
||||
POINT := regsave
|
||||
|
||||
CHUNK := X2 ; Used in the line routine
|
||||
OLDCHUNK := X2+1 ; Dito
|
||||
|
||||
; Absolute variables used in the code
|
||||
|
||||
.bss
|
||||
|
||||
ERROR: .res 1 ; Error code
|
||||
PALETTE: .res 2 ; The current palette
|
||||
|
||||
BITMASK: .res 1 ; $00 = clear, $FF = set pixels
|
||||
|
||||
; Line routine stuff
|
||||
DX: .res 2
|
||||
DY: .res 2
|
||||
|
||||
; BAR variables
|
||||
X1SAVE: .res 2
|
||||
Y1SAVE: .res 2
|
||||
X2SAVE: .res 2
|
||||
Y2SAVE: .res 2
|
||||
|
||||
; Text output stuff
|
||||
TEXTMAGX: .res 1
|
||||
TEXTMAGY: .res 1
|
||||
TEXTDIR: .res 1
|
||||
|
||||
; Constants and tables
|
||||
|
||||
.rodata
|
||||
|
||||
DEFPALETTE: .byte $00, $71 ; White on black
|
||||
PALETTESIZE = * - DEFPALETTE
|
||||
|
||||
BITTAB: .byte $80,$40,$20,$10,$08,$04,$02,$01
|
||||
BITCHUNK: .byte $FF,$7F,$3F,$1F,$0F,$07,$03,$01
|
||||
|
||||
CHARROM := $D000 ; Character rom base address
|
||||
|
||||
; The TED uses the CPU's memory configuration to fetch color data! Although
|
||||
; we run with ROMs banked out, putting color data in banked RAM (above $8000)
|
||||
; will result in color artifacts appearing when we bank ROM back in for
|
||||
; interrupts and Kernal calls. Bitmap data is not affected by this limitation,
|
||||
; but since there is no way to access RAM under IO (FE00-FF40), we can't put the
|
||||
; bitmap at $E000 like we do on the C64, and have to use the next lowest
|
||||
; position at $C000.
|
||||
|
||||
LBASE := $0800 ; Luminance memory base address
|
||||
VBASE := $C000 ; Bitmap base address
|
||||
|
||||
CBASE := LBASE + $400 ; Chrominance memory base address (fixed relative to LBASE)
|
||||
CHRBASE := $0800 ; Base address of text mode data
|
||||
|
||||
.assert LBASE .mod $0800 = 0, error, "Luma/Chroma memory base address must be a multiple of 2K"
|
||||
.assert VBASE .mod $2000 = 0, error, "Bitmap base address must be a multiple of 8K"
|
||||
.assert LBASE + $800 < $8000, warning, "Luma/Chroma memory overlaps ROM. This will produce color artifacts."
|
||||
.assert VBASE + $2000 < $FE00, error, "Bitmap overlaps IO space"
|
||||
|
||||
.code
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; INSTALL routine. Is called after the driver is loaded into memory. May
|
||||
; initialize anything that has to be done just once. Is probably empty
|
||||
; most of the time.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
;
|
||||
|
||||
INSTALL:
|
||||
; rts ; Fall through
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; UNINSTALL routine. Is called before the driver is removed from memory. May
|
||||
; clean up anything done by INSTALL but is probably empty most of the time.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
;
|
||||
|
||||
UNINSTALL:
|
||||
rts
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; INIT: Changes an already installed device from text mode to graphics
|
||||
; mode.
|
||||
; Note that INIT/DONE may be called multiple times while the driver
|
||||
; is loaded, while INSTALL is only called once, so any code that is needed
|
||||
; to initializes variables and so on must go here. Setting palette and
|
||||
; clearing the screen is not needed because this is called by the graphics
|
||||
; kernel later.
|
||||
; The graphics kernel will never call INIT when a graphics mode is already
|
||||
; active, so there is no need to protect against that.
|
||||
;
|
||||
; Must set an error code: YES
|
||||
;
|
||||
|
||||
INIT:
|
||||
|
||||
; Initialize variables
|
||||
|
||||
ldx #$FF
|
||||
stx BITMASK
|
||||
|
||||
; Switch into graphics mode
|
||||
lda $FF12 ; Set bitmap address and enable fetch from RAM
|
||||
and #%00000011
|
||||
ora #(>VBASE >> 2)
|
||||
sta $FF12
|
||||
|
||||
.if LBASE <> CHRBASE
|
||||
lda #>LBASE ; Set color memory address
|
||||
sta $FF14
|
||||
.endif
|
||||
|
||||
lda $FF06 ; Enable bitmap mode
|
||||
ora #%00100000
|
||||
sta $FF06
|
||||
|
||||
; Done, reset the error code
|
||||
|
||||
lda #TGI_ERR_OK
|
||||
sta ERROR
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; DONE: Will be called to switch the graphics device back into text mode.
|
||||
; The graphics kernel will never call DONE when no graphics mode is active,
|
||||
; so there is no need to protect against that.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
;
|
||||
|
||||
DONE: lda $FF12
|
||||
ora #%00000100 ; Fetch from ROM
|
||||
sta $FF12
|
||||
|
||||
.if LBASE <> CHRBASE
|
||||
lda #>CHRBASE ; Reset character/color matrix address
|
||||
sta $FF14
|
||||
.else
|
||||
sta ENABLE_ROM ; Clear text display since we clobbered it
|
||||
jsr CLRSCR
|
||||
sta ENABLE_RAM
|
||||
.endif
|
||||
|
||||
lda $FF06
|
||||
and #%11011111 ; Exit bitmap mode
|
||||
sta $FF06
|
||||
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; GETERROR: Return the error code in A and clear it.
|
||||
|
||||
GETERROR:
|
||||
ldx #TGI_ERR_OK
|
||||
lda ERROR
|
||||
stx ERROR
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; CONTROL: Platform/driver specific entry point.
|
||||
;
|
||||
; Must set an error code: YES
|
||||
;
|
||||
|
||||
CONTROL:
|
||||
lda #TGI_ERR_INV_FUNC
|
||||
sta ERROR
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; CLEAR: Clears the screen.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
;
|
||||
|
||||
CLEAR: ldy #$00
|
||||
tya
|
||||
@L1: sta VBASE+$0000,y
|
||||
sta VBASE+$0100,y
|
||||
sta VBASE+$0200,y
|
||||
sta VBASE+$0300,y
|
||||
sta VBASE+$0400,y
|
||||
sta VBASE+$0500,y
|
||||
sta VBASE+$0600,y
|
||||
sta VBASE+$0700,y
|
||||
sta VBASE+$0800,y
|
||||
sta VBASE+$0900,y
|
||||
sta VBASE+$0A00,y
|
||||
sta VBASE+$0B00,y
|
||||
sta VBASE+$0C00,y
|
||||
sta VBASE+$0D00,y
|
||||
sta VBASE+$0E00,y
|
||||
sta VBASE+$0F00,y
|
||||
sta VBASE+$1000,y
|
||||
sta VBASE+$1100,y
|
||||
sta VBASE+$1200,y
|
||||
sta VBASE+$1300,y
|
||||
sta VBASE+$1400,y
|
||||
sta VBASE+$1500,y
|
||||
sta VBASE+$1600,y
|
||||
sta VBASE+$1700,y
|
||||
sta VBASE+$1800,y
|
||||
sta VBASE+$1900,y
|
||||
sta VBASE+$1A00,y
|
||||
sta VBASE+$1B00,y
|
||||
sta VBASE+$1C00,y
|
||||
sta VBASE+$1D00,y
|
||||
sta VBASE+$1E00,y
|
||||
sta VBASE+$1E40,y
|
||||
iny
|
||||
bne @L1
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
|
||||
; The page number is already checked to be valid by the graphics kernel.
|
||||
;
|
||||
; Must set an error code: NO (will only be called if page ok)
|
||||
;
|
||||
|
||||
SETVIEWPAGE:
|
||||
; rts ; Fall through
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
|
||||
; The page number is already checked to be valid by the graphics kernel.
|
||||
;
|
||||
; Must set an error code: NO (will only be called if page ok)
|
||||
;
|
||||
|
||||
SETDRAWPAGE:
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; SETCOLOR: Set the drawing color (in A). The new color is already checked
|
||||
; to be in a valid range (0..maxcolor-1).
|
||||
;
|
||||
; Must set an error code: NO (will only be called if color ok)
|
||||
;
|
||||
|
||||
SETCOLOR:
|
||||
tax
|
||||
beq @L1
|
||||
lda #$FF
|
||||
@L1: sta BITMASK
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; SETPALETTE: Set the palette (not available with all drivers/hardware).
|
||||
; A pointer to the palette is passed in ptr1. Must set an error if palettes
|
||||
; are not supported
|
||||
;
|
||||
; Must set an error code: YES
|
||||
;
|
||||
|
||||
SETPALETTE:
|
||||
ldy #PALETTESIZE - 1
|
||||
@L1: lda (ptr1),y ; Copy the palette
|
||||
sta PALETTE,y
|
||||
dey
|
||||
bpl @L1
|
||||
|
||||
; Get luma values from the high nybble of the palette entries
|
||||
lda PALETTE+1 ; Foreground luma
|
||||
lsr a
|
||||
lsr a
|
||||
lsr a
|
||||
lsr a
|
||||
sta TEMP ; Foreground -> low nybble
|
||||
lda PALETTE ; Background luma
|
||||
and #$F0
|
||||
ora TEMP ; Background -> high nybble
|
||||
|
||||
; Initialize the luma map with the new luma values
|
||||
ldy #0
|
||||
@L2: sta LBASE+$0000,y
|
||||
sta LBASE+$0100,y
|
||||
sta LBASE+$0200,y
|
||||
sta LBASE+$02e8,y
|
||||
iny
|
||||
bne @L2
|
||||
|
||||
|
||||
; Get chroma values from the low nybble of the palette entries
|
||||
lda PALETTE+1 ; Foreground chroma
|
||||
and #$0F
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
sta TEMP ; Foreground -> high nybble
|
||||
lda PALETTE ; Background chroma
|
||||
and #$0F
|
||||
ora TEMP ; Background -> low nybble
|
||||
|
||||
; Initialize the chroma map with the new chroma values
|
||||
ldy #0
|
||||
@L3: sta CBASE+$0000,y
|
||||
sta CBASE+$0100,y
|
||||
sta CBASE+$0200,y
|
||||
sta CBASE+$02e8,y
|
||||
iny
|
||||
bne @L3
|
||||
|
||||
; Done, reset the error code
|
||||
lda #TGI_ERR_OK
|
||||
sta ERROR
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
|
||||
; set the palette should return the default palette here, so there's no
|
||||
; way for this function to fail.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
;
|
||||
|
||||
GETPALETTE:
|
||||
lda #<PALETTE
|
||||
ldx #>PALETTE
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; GETDEFPALETTE: Return the default palette for the driver in A/X. All
|
||||
; drivers should return something reasonable here, even drivers that don't
|
||||
; support palettes, otherwise the caller has no way to determine the colors
|
||||
; of the (not changeable) palette.
|
||||
;
|
||||
; Must set an error code: NO (all drivers must have a default palette)
|
||||
;
|
||||
|
||||
GETDEFPALETTE:
|
||||
lda #<DEFPALETTE
|
||||
ldx #>DEFPALETTE
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
|
||||
; color. The coordinates passed to this function are never outside the
|
||||
; visible screen area, so there is no need for clipping inside this function.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
;
|
||||
|
||||
SETPIXEL:
|
||||
jsr CALC ; Calculate coordinates
|
||||
|
||||
lda (POINT),Y
|
||||
eor BITMASK
|
||||
and BITTAB,X
|
||||
eor (POINT),Y
|
||||
sta (POINT),Y
|
||||
|
||||
@L9: rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; GETPIXEL: Read the color value of a pixel and return it in A/X. The
|
||||
; coordinates passed to this function are never outside the visible screen
|
||||
; area, so there is no need for clipping inside this function.
|
||||
|
||||
|
||||
GETPIXEL:
|
||||
jsr CALC ; Calculate coordinates
|
||||
|
||||
lda (POINT),Y
|
||||
ldy #$00
|
||||
and BITTAB,X
|
||||
beq @L1
|
||||
iny
|
||||
|
||||
@L1:
|
||||
tya ; Get color value into A
|
||||
ldx #$00 ; Clear high byte
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
|
||||
; X2/Y2 = ptr3/ptr4 using the current drawing color.
|
||||
;
|
||||
; X1,X2 etc. are set up above (x2=LINNUM in particular)
|
||||
; Format is LINE x2,y2,x1,y1
|
||||
;
|
||||
; Must set an error code: NO
|
||||
;
|
||||
|
||||
LINE:
|
||||
|
||||
@CHECK: lda X2 ; Make sure x1<x2
|
||||
sec
|
||||
sbc X1
|
||||
tax
|
||||
lda X2+1
|
||||
sbc X1+1
|
||||
bpl @CONT
|
||||
lda Y2 ; If not, swap P1 and P2
|
||||
ldy Y1
|
||||
sta Y1
|
||||
sty Y2
|
||||
lda Y2+1
|
||||
ldy Y1+1
|
||||
sta Y1+1
|
||||
sty Y2+1
|
||||
lda X1
|
||||
ldy X2
|
||||
sty X1
|
||||
sta X2
|
||||
lda X2+1
|
||||
ldy X1+1
|
||||
sta X1+1
|
||||
sty X2+1
|
||||
bcc @CHECK
|
||||
|
||||
@CONT: sta DX+1
|
||||
stx DX
|
||||
|
||||
ldx #$C8 ; INY
|
||||
lda Y2 ; Calculate dy
|
||||
sec
|
||||
sbc Y1
|
||||
tay
|
||||
lda Y2+1
|
||||
sbc Y1+1
|
||||
bpl @DYPOS ; Is y2>=y1?
|
||||
lda Y1 ; Otherwise dy=y1-y2
|
||||
sec
|
||||
sbc Y2
|
||||
tay
|
||||
ldx #$88 ; DEY
|
||||
|
||||
@DYPOS: sty DY ; 8-bit DY -- FIX ME?
|
||||
stx YINCDEC
|
||||
stx XINCDEC
|
||||
|
||||
jsr CALC ; Set up .X, .Y, and POINT
|
||||
lda BITCHUNK,X
|
||||
sta OLDCHUNK
|
||||
sta CHUNK
|
||||
|
||||
ldx DY
|
||||
cpx DX ; Who's bigger: dy or dx?
|
||||
bcc STEPINX ; If dx, then...
|
||||
lda DX+1
|
||||
bne STEPINX
|
||||
|
||||
;
|
||||
; Big steps in Y
|
||||
;
|
||||
; To simplify my life, just use PLOT to plot points.
|
||||
;
|
||||
; No more!
|
||||
; Added special plotting routine -- cool!
|
||||
;
|
||||
; X is now counter, Y is y-coordinate
|
||||
;
|
||||
; On entry, X=DY=number of loop iterations, and Y=
|
||||
; Y1 AND #$07
|
||||
STEPINY:
|
||||
lda #00
|
||||
sta OLDCHUNK ; So plotting routine will work right
|
||||
lda CHUNK
|
||||
lsr ; Strip the bit
|
||||
eor CHUNK
|
||||
sta CHUNK
|
||||
txa
|
||||
beq YCONT2 ; If dy=0, it's just a point
|
||||
@CONT: lsr ; Init counter to dy/2
|
||||
;
|
||||
; Main loop
|
||||
;
|
||||
YLOOP: sta TEMP
|
||||
|
||||
lda (POINT),y
|
||||
eor BITMASK
|
||||
and CHUNK
|
||||
eor (POINT),y
|
||||
sta (POINT),y
|
||||
YINCDEC:
|
||||
iny ; Advance Y coordinate
|
||||
cpy #8
|
||||
bcc @CONT ; No prob if Y=0..7
|
||||
jsr FIXY
|
||||
@CONT: lda TEMP ; Restore A
|
||||
sec
|
||||
sbc DX
|
||||
bcc YFIXX
|
||||
YCONT: dex ; X is counter
|
||||
bne YLOOP
|
||||
YCONT2: lda (POINT),y ; Plot endpoint
|
||||
eor BITMASK
|
||||
and CHUNK
|
||||
eor (POINT),y
|
||||
sta (POINT),y
|
||||
rts
|
||||
|
||||
YFIXX: ; X=x+1
|
||||
adc DY
|
||||
lsr CHUNK
|
||||
bne YCONT ; If we pass a column boundary...
|
||||
ror CHUNK ; Then reset CHUNK to $80
|
||||
sta TEMP2
|
||||
lda POINT ; And add 8 to POINT
|
||||
adc #8
|
||||
sta POINT
|
||||
bcc @CONT
|
||||
inc POINT+1
|
||||
@CONT: lda TEMP2
|
||||
dex
|
||||
bne YLOOP
|
||||
beq YCONT2
|
||||
|
||||
;
|
||||
; Big steps in X direction
|
||||
;
|
||||
; On entry, X=DY=number of loop iterations, and Y=
|
||||
; Y1 AND #$07
|
||||
|
||||
.bss
|
||||
COUNTHI:
|
||||
.byte $00 ; Temporary counter, only used once.
|
||||
.code
|
||||
STEPINX:
|
||||
ldx DX
|
||||
lda DX+1
|
||||
sta COUNTHI
|
||||
cmp #$80
|
||||
ror ; Need bit for initialization
|
||||
sta Y1 ; High byte of counter
|
||||
txa
|
||||
bne @CONT ; Could be $100
|
||||
dec COUNTHI
|
||||
@CONT: ror
|
||||
;
|
||||
; Main loop
|
||||
;
|
||||
XLOOP: lsr CHUNK
|
||||
beq XFIXC ; If we pass a column boundary...
|
||||
XCONT1: sbc DY
|
||||
bcc XFIXY ; Time to step in Y?
|
||||
XCONT2: dex
|
||||
bne XLOOP
|
||||
dec COUNTHI ; High bits set?
|
||||
bpl XLOOP
|
||||
|
||||
lsr CHUNK ; Advance to last point
|
||||
jmp LINEPLOT ; Plot the last chunk
|
||||
;
|
||||
; CHUNK has passed a column, so plot and increment pointer
|
||||
; and fix up CHUNK, OLDCHUNK.
|
||||
;
|
||||
XFIXC: sta TEMP
|
||||
jsr LINEPLOT
|
||||
lda #$FF
|
||||
sta CHUNK
|
||||
sta OLDCHUNK
|
||||
lda POINT
|
||||
clc
|
||||
adc #8
|
||||
sta POINT
|
||||
lda TEMP
|
||||
bcc XCONT1
|
||||
inc POINT+1
|
||||
jmp XCONT1
|
||||
;
|
||||
; Check to make sure there isn't a high bit, plot chunk,
|
||||
; and update Y-coordinate.
|
||||
;
|
||||
XFIXY: dec Y1 ; Maybe high bit set
|
||||
bpl XCONT2
|
||||
adc DX
|
||||
sta TEMP
|
||||
lda DX+1
|
||||
adc #$FF ; Hi byte
|
||||
sta Y1
|
||||
|
||||
jsr LINEPLOT ; Plot chunk
|
||||
lda CHUNK
|
||||
sta OLDCHUNK
|
||||
|
||||
lda TEMP
|
||||
XINCDEC:
|
||||
iny ; Y-coord
|
||||
cpy #8 ; 0..7 is ok
|
||||
bcc XCONT2
|
||||
sta TEMP
|
||||
jsr FIXY
|
||||
lda TEMP
|
||||
jmp XCONT2
|
||||
|
||||
;
|
||||
; Subroutine to plot chunks/points (to save a little
|
||||
; room, gray hair, etc.)
|
||||
;
|
||||
LINEPLOT: ; Plot the line chunk
|
||||
lda (POINT),Y
|
||||
eor BITMASK
|
||||
ora CHUNK
|
||||
and OLDCHUNK
|
||||
eor CHUNK
|
||||
eor (POINT),Y
|
||||
sta (POINT),Y
|
||||
rts
|
||||
|
||||
;
|
||||
; Subroutine to fix up pointer when Y decreases through
|
||||
; zero or increases through 7.
|
||||
;
|
||||
FIXY: cpy #255 ; Y=255 or Y=8
|
||||
beq @DECPTR
|
||||
|
||||
@INCPTR: ; Add 320 to pointer
|
||||
ldy #0 ; Y increased through 7
|
||||
lda POINT
|
||||
adc #<320
|
||||
sta POINT
|
||||
lda POINT+1
|
||||
adc #>320
|
||||
sta POINT+1
|
||||
rts
|
||||
|
||||
@DECPTR: ; Okay, subtract 320 then
|
||||
ldy #7 ; Y decreased through 0
|
||||
lda POINT
|
||||
sec
|
||||
sbc #<320
|
||||
sta POINT
|
||||
lda POINT+1
|
||||
sbc #>320
|
||||
sta POINT+1
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
|
||||
; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
|
||||
; Contrary to most other functions, the graphics kernel will sort and clip
|
||||
; the coordinates before calling the driver, so on entry the following
|
||||
; conditions are valid:
|
||||
; X1 <= X2
|
||||
; Y1 <= Y2
|
||||
; (X1 >= 0) && (X1 < XRES)
|
||||
; (X2 >= 0) && (X2 < XRES)
|
||||
; (Y1 >= 0) && (Y1 < YRES)
|
||||
; (Y2 >= 0) && (Y2 < YRES)
|
||||
;
|
||||
; Must set an error code: NO
|
||||
;
|
||||
|
||||
; Note: This function needs optimization. It's just a cheap translation of
|
||||
; the original C wrapper and could be written much smaller (besides that,
|
||||
; calling LINE is not a good idea either).
|
||||
|
||||
BAR: lda Y2
|
||||
sta Y2SAVE
|
||||
lda Y2+1
|
||||
sta Y2SAVE+1
|
||||
|
||||
lda X2
|
||||
sta X2SAVE
|
||||
lda X2+1
|
||||
sta X2SAVE+1
|
||||
|
||||
lda Y1
|
||||
sta Y1SAVE
|
||||
lda Y1+1
|
||||
sta Y1SAVE+1
|
||||
|
||||
lda X1
|
||||
sta X1SAVE
|
||||
lda X1+1
|
||||
sta X1SAVE+1
|
||||
|
||||
@L1: lda Y1
|
||||
sta Y2
|
||||
lda Y1+1
|
||||
sta Y2+1
|
||||
jsr LINE
|
||||
|
||||
lda Y1SAVE
|
||||
cmp Y2SAVE
|
||||
bne @L2
|
||||
lda Y1SAVE
|
||||
cmp Y2SAVE
|
||||
beq @L4
|
||||
|
||||
@L2: inc Y1SAVE
|
||||
bne @L3
|
||||
inc Y1SAVE+1
|
||||
|
||||
@L3: lda Y1SAVE
|
||||
sta Y1
|
||||
lda Y1SAVE+1
|
||||
sta Y1+1
|
||||
|
||||
lda X1SAVE
|
||||
sta X1
|
||||
lda X1SAVE+1
|
||||
sta X1+1
|
||||
|
||||
lda X2SAVE
|
||||
sta X2
|
||||
lda X2SAVE+1
|
||||
sta X2+1
|
||||
jmp @L1
|
||||
|
||||
@L4: rts
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
|
||||
; direction is passend in X/Y, the text direction is passed in A.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
;
|
||||
|
||||
TEXTSTYLE:
|
||||
stx TEXTMAGX
|
||||
sty TEXTMAGY
|
||||
sta TEXTDIR
|
||||
rts
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
|
||||
; current text style. The text to output is given as a zero terminated
|
||||
; string with address in ptr3.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
;
|
||||
|
||||
OUTTEXT:
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Calculate all variables to plot the pixel at X1/Y1.
|
||||
|
||||
CALC: lda Y1
|
||||
sta TEMP2
|
||||
and #7
|
||||
tay
|
||||
lda Y1+1
|
||||
lsr ; Neg is possible
|
||||
ror TEMP2
|
||||
lsr
|
||||
ror TEMP2
|
||||
lsr
|
||||
ror TEMP2
|
||||
|
||||
lda #00
|
||||
sta POINT
|
||||
lda TEMP2
|
||||
cmp #$80
|
||||
ror
|
||||
ror POINT
|
||||
cmp #$80
|
||||
ror
|
||||
ror POINT ; Row * 64
|
||||
adc TEMP2 ; + Row * 256
|
||||
clc
|
||||
adc #>VBASE ; + Bitmap base
|
||||
sta POINT+1
|
||||
|
||||
lda X1
|
||||
tax
|
||||
and #$F8
|
||||
clc
|
||||
adc POINT ; +(X AND #$F8)
|
||||
sta POINT
|
||||
lda X1+1
|
||||
adc POINT+1
|
||||
sta POINT+1
|
||||
txa
|
||||
and #7
|
||||
tax
|
||||
rts
|
||||
14
libsrc/plus4/tgi_stat_stddrv.s
Normal file
14
libsrc/plus4/tgi_stat_stddrv.s
Normal file
@@ -0,0 +1,14 @@
|
||||
;
|
||||
; Address of the static standard tgi driver
|
||||
;
|
||||
; Oliver Schmidt, 2012-11-01
|
||||
;
|
||||
; const void tgi_static_stddrv[];
|
||||
;
|
||||
|
||||
.export _tgi_static_stddrv
|
||||
.import _ted_hi_tgi
|
||||
|
||||
.rodata
|
||||
|
||||
_tgi_static_stddrv := _ted_hi_tgi
|
||||
13
libsrc/plus4/tgi_stddrv.s
Normal file
13
libsrc/plus4/tgi_stddrv.s
Normal file
@@ -0,0 +1,13 @@
|
||||
;
|
||||
; Name of the standard tgi driver
|
||||
;
|
||||
; Oliver Schmidt, 2011-05-02
|
||||
;
|
||||
; const char tgi_stddrv[];
|
||||
;
|
||||
|
||||
.export _tgi_stddrv
|
||||
|
||||
.rodata
|
||||
|
||||
_tgi_stddrv: .asciiz "ted-hi.tgi"
|
||||
@@ -99,6 +99,7 @@ DISK_apple2 = samples.dsk
|
||||
DISK_apple2enh = samples.dsk
|
||||
DISK_atari = samples.atr
|
||||
DISK_atarixl = samples.atr
|
||||
DISK_plus4 = samples.d64
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# System-dependent settings
|
||||
@@ -146,6 +147,8 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000
|
||||
.o:
|
||||
ifeq ($(SYS),vic20)
|
||||
$(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib
|
||||
else ifeq ($(SYS),plus4)
|
||||
$(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -C plus4-hires.cfg -m $@.map $^ $(SYS).lib
|
||||
else
|
||||
$(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib
|
||||
endif
|
||||
@@ -326,9 +329,11 @@ EXELIST_plus4 = \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
terminal \
|
||||
tinyshell \
|
||||
sieve
|
||||
sieve \
|
||||
tgidemo
|
||||
|
||||
EXELIST_sim6502 = \
|
||||
checkversion \
|
||||
@@ -451,7 +456,15 @@ multdemo: multidemo.o
|
||||
ovrldemo: overlaydemo.o
|
||||
$(LD) $(LDFLAGS) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(SYS).lib
|
||||
|
||||
OVERLAYLIST := $(foreach I,1 2 3,multdemo.$I ovrldemo.$I)
|
||||
OVERLAYLIST :=
|
||||
|
||||
ifneq ($(filter ovrldemo,$(EXELIST_$(SYS))),)
|
||||
OVERLAYLIST += $(foreach I,1 2 3,ovrldemo.$I)
|
||||
endif
|
||||
|
||||
ifneq ($(filter multdemo,$(EXELIST_$(SYS))),)
|
||||
OVERLAYLIST += $(foreach I,1 2 3,multdemo.$I)
|
||||
endif
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# TGI programs on the VIC-20 need a special ld65 configuration file.
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
|
||||
|
||||
#define DYN_BOX_DRAW
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
|
||||
|
||||
#define DYN_BOX_DRAW
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
# define DYN_DRV 1
|
||||
#endif
|
||||
|
||||
#define COLOR_BACK TGI_COLOR_BLACK
|
||||
#define COLOR_FORE TGI_COLOR_WHITE
|
||||
|
||||
/* Color values passed to TGI functions are indices into the default palette. */
|
||||
#define COLOR_BACK 0
|
||||
#define COLOR_FORE 1
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -65,17 +67,39 @@ static void DoWarning (void)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Note that everywhere else in the TGI API, colors are referred to via an index
|
||||
* to the current palette.
|
||||
*
|
||||
* TGI_COLOR_ values can be used (ONLY!) for setting the palette, using them
|
||||
* with other TGI functions only works by chance, on some targets.
|
||||
*/
|
||||
static void DoPalette (int n)
|
||||
{
|
||||
static const unsigned char Palette[4][2] = {
|
||||
/* FIXME: add some ifdefs with proper values for targets that need it */
|
||||
#if !defined(__APPLE2__)
|
||||
{ TGI_COLOR_BLACK, TGI_COLOR_BLUE },
|
||||
{ TGI_COLOR_WHITE, TGI_COLOR_BLACK },
|
||||
{ TGI_COLOR_RED, TGI_COLOR_BLACK },
|
||||
#else
|
||||
{ TGI_COLOR_WHITE, TGI_COLOR_BLACK },
|
||||
{ TGI_COLOR_BLACK, TGI_COLOR_WHITE },
|
||||
{ TGI_COLOR_WHITE, TGI_COLOR_BLACK },
|
||||
#endif
|
||||
};
|
||||
tgi_setpalette (Palette[n]);
|
||||
}
|
||||
|
||||
|
||||
static void DoCircles (void)
|
||||
{
|
||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLUE };
|
||||
unsigned char I;
|
||||
unsigned char Color = COLOR_BACK;
|
||||
const unsigned X = MaxX / 2;
|
||||
const unsigned Y = MaxY / 2;
|
||||
const unsigned Limit = (X < Y) ? Y : X;
|
||||
|
||||
tgi_setpalette (Palette);
|
||||
tgi_setcolor (COLOR_FORE);
|
||||
tgi_clear ();
|
||||
tgi_line (0, 0, MaxX, MaxY);
|
||||
@@ -87,7 +111,9 @@ static void DoCircles (void)
|
||||
tgi_ellipse (X, Y, I, tgi_imulround (I, AspectRatio));
|
||||
}
|
||||
}
|
||||
|
||||
while (kbhit ()) {
|
||||
cgetc ();
|
||||
}
|
||||
cgetc ();
|
||||
}
|
||||
|
||||
@@ -95,11 +121,9 @@ static void DoCircles (void)
|
||||
|
||||
static void DoCheckerboard (void)
|
||||
{
|
||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK };
|
||||
unsigned X, Y;
|
||||
unsigned char Color = COLOR_BACK;
|
||||
|
||||
tgi_setpalette (Palette);
|
||||
tgi_clear ();
|
||||
|
||||
while (1) {
|
||||
@@ -123,13 +147,11 @@ static void DoCheckerboard (void)
|
||||
|
||||
static void DoDiagram (void)
|
||||
{
|
||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK };
|
||||
int XOrigin, YOrigin;
|
||||
int Amp;
|
||||
int X, Y;
|
||||
unsigned I;
|
||||
|
||||
tgi_setpalette (Palette);
|
||||
tgi_setcolor (COLOR_FORE);
|
||||
tgi_clear ();
|
||||
|
||||
@@ -160,6 +182,9 @@ static void DoDiagram (void)
|
||||
tgi_lineto (XOrigin + X, YOrigin + Y);
|
||||
}
|
||||
|
||||
while (kbhit ()) {
|
||||
cgetc ();
|
||||
}
|
||||
cgetc ();
|
||||
}
|
||||
|
||||
@@ -167,11 +192,9 @@ static void DoDiagram (void)
|
||||
|
||||
static void DoLines (void)
|
||||
{
|
||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK };
|
||||
unsigned X;
|
||||
const unsigned Min = (MaxX < MaxY) ? MaxX : MaxY;
|
||||
|
||||
tgi_setpalette (Palette);
|
||||
tgi_setcolor (COLOR_FORE);
|
||||
tgi_clear ();
|
||||
|
||||
@@ -182,6 +205,9 @@ static void DoLines (void)
|
||||
tgi_line (Min, Min, Min-X, 0);
|
||||
}
|
||||
|
||||
while (kbhit ()) {
|
||||
cgetc ();
|
||||
}
|
||||
cgetc ();
|
||||
}
|
||||
|
||||
@@ -216,10 +242,11 @@ int main (void)
|
||||
Border = bordercolor (COLOR_BLACK);
|
||||
|
||||
/* Do graphics stuff */
|
||||
DoCircles ();
|
||||
DoCheckerboard ();
|
||||
DoDiagram ();
|
||||
DoLines ();
|
||||
|
||||
/* use default palette */ DoCircles ();
|
||||
DoPalette (0); DoCheckerboard ();
|
||||
DoPalette (1); DoDiagram ();
|
||||
DoPalette (2); DoLines ();
|
||||
|
||||
#if DYN_DRV
|
||||
/* Unload the driver */
|
||||
|
||||
@@ -394,6 +394,16 @@ void DoConditionals (void)
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
|
||||
case TOK_IFP02X:
|
||||
D = AllocIf (".IFP02X", 1);
|
||||
NextTok ();
|
||||
if (IfCond) {
|
||||
SetIfCond (D, GetCPU() == CPU_6502X);
|
||||
}
|
||||
ExpectSep ();
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
|
||||
case TOK_IFP4510:
|
||||
D = AllocIf (".IFP4510", 1);
|
||||
NextTok ();
|
||||
@@ -485,6 +495,7 @@ int CheckConditionals (void)
|
||||
case TOK_IFNDEF:
|
||||
case TOK_IFNREF:
|
||||
case TOK_IFP02:
|
||||
case TOK_IFP02X:
|
||||
case TOK_IFP4510:
|
||||
case TOK_IFP816:
|
||||
case TOK_IFPC02:
|
||||
|
||||
@@ -1562,6 +1562,14 @@ static void DoP02 (void)
|
||||
|
||||
|
||||
|
||||
static void DoP02X (void)
|
||||
/* Switch to 6502 CPU */
|
||||
{
|
||||
SetCPU (CPU_6502X);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void DoPC02 (void)
|
||||
/* Switch to 65C02 CPU */
|
||||
{
|
||||
@@ -2057,70 +2065,72 @@ struct CtrlDesc {
|
||||
void (*Handler) (void); /* Command handler */
|
||||
};
|
||||
|
||||
/* NOTE: .AND, .BITAND, .BITNOT, .BITOR, .BITXOR, .MOD, .NOT, .OR, .SHL, .SHR
|
||||
and .XOR do NOT go into this table */
|
||||
#define PSEUDO_COUNT (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0]))
|
||||
static CtrlDesc CtrlCmdTab [] = {
|
||||
{ ccNone, DoA16 },
|
||||
{ ccNone, DoA8 },
|
||||
{ ccNone, DoA16 }, /* .A16 */
|
||||
{ ccNone, DoA8 }, /* .A8 */
|
||||
{ ccNone, DoAddr }, /* .ADDR */
|
||||
{ ccNone, DoUnexpected }, /* .ADDRSIZE */
|
||||
{ ccNone, DoAlign },
|
||||
{ ccNone, DoASCIIZ },
|
||||
{ ccNone, DoAlign }, /* .ALIGN */
|
||||
{ ccNone, DoASCIIZ }, /* .ASCIIZ */
|
||||
{ ccNone, DoUnexpected }, /* .ASIZE */
|
||||
{ ccNone, DoAssert },
|
||||
{ ccNone, DoAutoImport },
|
||||
{ ccNone, DoAssert }, /* .ASSERT */
|
||||
{ ccNone, DoAutoImport }, /* .AUTOIMPORT */
|
||||
{ ccNone, DoUnexpected }, /* .BANK */
|
||||
{ ccNone, DoUnexpected }, /* .BANKBYTE */
|
||||
{ ccNone, DoBankBytes },
|
||||
{ ccNone, DoBankBytes }, /* .BANKBYTES */
|
||||
{ ccNone, DoUnexpected }, /* .BLANK */
|
||||
{ ccNone, DoBss },
|
||||
{ ccNone, DoByte },
|
||||
{ ccNone, DoCase },
|
||||
{ ccNone, DoCharMap },
|
||||
{ ccNone, DoCode },
|
||||
{ ccNone, DoBss }, /* .BSS */
|
||||
{ ccNone, DoByte }, /* .BYT, .BYTE */
|
||||
{ ccNone, DoCase }, /* .CASE */
|
||||
{ ccNone, DoCharMap }, /* .CHARMAP */
|
||||
{ ccNone, DoCode }, /* .CODE */
|
||||
{ ccNone, DoUnexpected, }, /* .CONCAT */
|
||||
{ ccNone, DoConDes },
|
||||
{ ccNone, DoConDes }, /* .CONDES */
|
||||
{ ccNone, DoUnexpected }, /* .CONST */
|
||||
{ ccNone, DoConstructor },
|
||||
{ ccNone, DoConstructor }, /* .CONSTRUCTOR */
|
||||
{ ccNone, DoUnexpected }, /* .CPU */
|
||||
{ ccNone, DoData },
|
||||
{ ccNone, DoDbg, },
|
||||
{ ccNone, DoDByt },
|
||||
{ ccNone, DoDebugInfo },
|
||||
{ ccKeepToken, DoDefine },
|
||||
{ ccNone, DoData }, /* .DATA */
|
||||
{ ccNone, DoDbg, }, /* .DBG */
|
||||
{ ccNone, DoDByt }, /* .DBYT */
|
||||
{ ccNone, DoDebugInfo }, /* .DEBUGINFO */
|
||||
{ ccKeepToken, DoDefine }, /* .DEF, .DEFINE */
|
||||
{ ccNone, DoUnexpected }, /* .DEFINED */
|
||||
{ ccNone, DoUnexpected }, /* .DEFINEDMACRO */
|
||||
{ ccNone, DoDelMac },
|
||||
{ ccNone, DoDestructor },
|
||||
{ ccNone, DoDWord },
|
||||
{ ccNone, DoDelMac }, /* .DELMAC, .DELMACRO */
|
||||
{ ccNone, DoDestructor }, /* .DESTRUCTOR */
|
||||
{ ccNone, DoDWord }, /* .DWORD */
|
||||
{ ccKeepToken, DoConditionals }, /* .ELSE */
|
||||
{ ccKeepToken, DoConditionals }, /* .ELSEIF */
|
||||
{ ccKeepToken, DoEnd },
|
||||
{ ccKeepToken, DoEnd }, /* .END */
|
||||
{ ccNone, DoUnexpected }, /* .ENDENUM */
|
||||
{ ccKeepToken, DoConditionals }, /* .ENDIF */
|
||||
{ ccNone, DoUnexpected }, /* .ENDMACRO */
|
||||
{ ccNone, DoEndProc },
|
||||
{ ccNone, DoUnexpected }, /* .ENDREPEAT */
|
||||
{ ccNone, DoEndScope },
|
||||
{ ccNone, DoUnexpected }, /* .ENDMAC, .ENDMACRO */
|
||||
{ ccNone, DoEndProc }, /* .ENDPROC */
|
||||
{ ccNone, DoUnexpected }, /* .ENDREP, .ENDREPEAT */
|
||||
{ ccNone, DoEndScope }, /* .ENDSCOPE */
|
||||
{ ccNone, DoUnexpected }, /* .ENDSTRUCT */
|
||||
{ ccNone, DoUnexpected }, /* .ENDUNION */
|
||||
{ ccNone, DoEnum },
|
||||
{ ccNone, DoError },
|
||||
{ ccNone, DoExitMacro },
|
||||
{ ccNone, DoExport },
|
||||
{ ccNone, DoExportZP },
|
||||
{ ccNone, DoFarAddr },
|
||||
{ ccNone, DoFatal },
|
||||
{ ccNone, DoFeature },
|
||||
{ ccNone, DoFileOpt },
|
||||
{ ccNone, DoForceImport },
|
||||
{ ccNone, DoEnum }, /* .ENUM */
|
||||
{ ccNone, DoError }, /* .ERROR */
|
||||
{ ccNone, DoExitMacro }, /* .EXITMAC, .EXITMACRO */
|
||||
{ ccNone, DoExport }, /* .EXPORT */
|
||||
{ ccNone, DoExportZP }, /* .EXPORTZP */
|
||||
{ ccNone, DoFarAddr }, /* .FARADDR */
|
||||
{ ccNone, DoFatal }, /* .FATAL */
|
||||
{ ccNone, DoFeature }, /* .FEATURE */
|
||||
{ ccNone, DoFileOpt }, /* .FOPT, .FILEOPT */
|
||||
{ ccNone, DoForceImport }, /* .FORCEIMPORT */
|
||||
{ ccNone, DoUnexpected }, /* .FORCEWORD */
|
||||
{ ccNone, DoGlobal },
|
||||
{ ccNone, DoGlobalZP },
|
||||
{ ccNone, DoGlobal }, /* .GLOBAL */
|
||||
{ ccNone, DoGlobalZP }, /* .GLOBALZP */
|
||||
{ ccNone, DoUnexpected }, /* .HIBYTE */
|
||||
{ ccNone, DoHiBytes },
|
||||
{ ccNone, DoHiBytes }, /* .HIBYTES */
|
||||
{ ccNone, DoUnexpected }, /* .HIWORD */
|
||||
{ ccNone, DoI16 },
|
||||
{ ccNone, DoI8 },
|
||||
{ ccNone, DoI16 }, /* .I16 */
|
||||
{ ccNone, DoI8 }, /* .I8 */
|
||||
{ ccNone, DoUnexpected }, /* .IDENT */
|
||||
{ ccKeepToken, DoConditionals }, /* .IF */
|
||||
{ ccKeepToken, DoConditionals }, /* .IFBLANK */
|
||||
@@ -2131,81 +2141,83 @@ static CtrlDesc CtrlCmdTab [] = {
|
||||
{ ccKeepToken, DoConditionals }, /* .IFNDEF */
|
||||
{ ccKeepToken, DoConditionals }, /* .IFNREF */
|
||||
{ ccKeepToken, DoConditionals }, /* .IFP02 */
|
||||
{ ccKeepToken, DoConditionals }, /* .IFP02X */
|
||||
{ ccKeepToken, DoConditionals }, /* .IFP4510 */
|
||||
{ ccKeepToken, DoConditionals }, /* .IFP816 */
|
||||
{ ccKeepToken, DoConditionals }, /* .IFPC02 */
|
||||
{ ccKeepToken, DoConditionals }, /* .IFPDTV */
|
||||
{ ccKeepToken, DoConditionals }, /* .IFPSC02 */
|
||||
{ ccKeepToken, DoConditionals }, /* .IFREF */
|
||||
{ ccNone, DoImport },
|
||||
{ ccNone, DoImportZP },
|
||||
{ ccNone, DoIncBin },
|
||||
{ ccNone, DoInclude },
|
||||
{ ccNone, DoInterruptor },
|
||||
{ ccNone, DoImport }, /* .IMPORT */
|
||||
{ ccNone, DoImportZP }, /* .IMPORTZP */
|
||||
{ ccNone, DoIncBin }, /* .INCBIN */
|
||||
{ ccNone, DoInclude }, /* .INCLUDE */
|
||||
{ ccNone, DoInterruptor }, /* .INTERRUPTPOR */
|
||||
{ ccNone, DoUnexpected }, /* .ISIZE */
|
||||
{ ccNone, DoUnexpected }, /* .ISMNEMONIC */
|
||||
{ ccNone, DoInvalid }, /* .LEFT */
|
||||
{ ccNone, DoLineCont },
|
||||
{ ccNone, DoList },
|
||||
{ ccNone, DoListBytes },
|
||||
{ ccNone, DoLiteral },
|
||||
{ ccNone, DoLineCont }, /* .LINECONT */
|
||||
{ ccNone, DoList }, /* .LIST */
|
||||
{ ccNone, DoListBytes }, /* .LISTBYTES */
|
||||
{ ccNone, DoLiteral }, /* .LITERAL */
|
||||
{ ccNone, DoUnexpected }, /* .LOBYTE */
|
||||
{ ccNone, DoLoBytes },
|
||||
{ ccNone, DoLoBytes }, /* .LOBYTES */
|
||||
{ ccNone, DoUnexpected }, /* .LOCAL */
|
||||
{ ccNone, DoLocalChar },
|
||||
{ ccNone, DoLocalChar }, /* .LOCALCHAR */
|
||||
{ ccNone, DoUnexpected }, /* .LOWORD */
|
||||
{ ccNone, DoMacPack },
|
||||
{ ccNone, DoMacro },
|
||||
{ ccNone, DoMacPack }, /* .MACPACK */
|
||||
{ ccNone, DoMacro }, /* .MAC, .MACRO */
|
||||
{ ccNone, DoUnexpected }, /* .MATCH */
|
||||
{ ccNone, DoUnexpected }, /* .MAX */
|
||||
{ ccNone, DoInvalid }, /* .MID */
|
||||
{ ccNone, DoUnexpected }, /* .MIN */
|
||||
{ ccNone, DoNull },
|
||||
{ ccNone, DoOrg },
|
||||
{ ccNone, DoOut },
|
||||
{ ccNone, DoP02 },
|
||||
{ ccNone, DoP4510 },
|
||||
{ ccNone, DoP816 },
|
||||
{ ccNone, DoPageLength },
|
||||
{ ccNone, DoNull }, /* .NULL */
|
||||
{ ccNone, DoOrg }, /* .ORG */
|
||||
{ ccNone, DoOut }, /* .OUT */
|
||||
{ ccNone, DoP02 }, /* .P02 */
|
||||
{ ccNone, DoP02X }, /* .P02X */
|
||||
{ ccNone, DoP4510 }, /* .P4510 */
|
||||
{ ccNone, DoP816 }, /* .P816 */
|
||||
{ ccNone, DoPageLength }, /* .PAGELEN, .PAGELENGTH */
|
||||
{ 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 },
|
||||
{ ccNone, DoPC02 }, /* .PSC02 */
|
||||
{ ccNone, DoPDTV }, /* .PDTV */
|
||||
{ ccNone, DoPopCharmap }, /* .POPCHARMAP */
|
||||
{ ccNone, DoPopCPU }, /* .POPCPU */
|
||||
{ ccNone, DoPopSeg }, /* .POPSEG */
|
||||
{ ccNone, DoProc }, /* .PROC */
|
||||
{ ccNone, DoPSC02 }, /* .PSC02 */
|
||||
{ ccNone, DoPushCharmap }, /* .PUSHCHARMAP */
|
||||
{ ccNone, DoPushCPU }, /* .PUSHCPU */
|
||||
{ ccNone, DoPushSeg }, /* .PUSHSEG */
|
||||
{ ccNone, DoUnexpected }, /* .REF, .REFERENCED */
|
||||
{ ccNone, DoReferTo }, /* .REFTO, .REFERTO */
|
||||
{ ccNone, DoReloc }, /* .RELOC */
|
||||
{ ccNone, DoRepeat }, /* .REPEAT */
|
||||
{ ccNone, DoRes }, /* .RES */
|
||||
{ ccNone, DoInvalid }, /* .RIGHT */
|
||||
{ ccNone, DoROData },
|
||||
{ ccNone, DoScope },
|
||||
{ ccNone, DoSegment },
|
||||
{ ccNone, DoROData }, /* .RODATA */
|
||||
{ ccNone, DoScope }, /* .SCOPE */
|
||||
{ ccNone, DoSegment }, /* .SEGMENT */
|
||||
{ ccNone, DoUnexpected }, /* .SET */
|
||||
{ ccNone, DoSetCPU },
|
||||
{ ccNone, DoSetCPU }, /* .SETCPU */
|
||||
{ ccNone, DoUnexpected }, /* .SIZEOF */
|
||||
{ ccNone, DoSmart },
|
||||
{ ccNone, DoSmart }, /* .SMART */
|
||||
{ ccNone, DoUnexpected }, /* .SPRINTF */
|
||||
{ ccNone, DoUnexpected }, /* .STRAT */
|
||||
{ ccNone, DoUnexpected }, /* .STRING */
|
||||
{ ccNone, DoUnexpected }, /* .STRLEN */
|
||||
{ ccNone, DoStruct },
|
||||
{ ccNone, DoTag },
|
||||
{ ccNone, DoStruct }, /* .STRUCT */
|
||||
{ ccNone, DoTag }, /* .TAG */
|
||||
{ ccNone, DoUnexpected }, /* .TCOUNT */
|
||||
{ ccNone, DoUnexpected }, /* .TIME */
|
||||
{ ccKeepToken, DoUnDef },
|
||||
{ ccNone, DoUnion },
|
||||
{ ccKeepToken, DoUnDef }, /* .UNDEF, .UNDEFINE */
|
||||
{ ccNone, DoUnion }, /* .UNION */
|
||||
{ ccNone, DoUnexpected }, /* .VERSION */
|
||||
{ ccNone, DoWarning },
|
||||
{ ccNone, DoWord },
|
||||
{ ccNone, DoWarning }, /* .WARNING */
|
||||
{ ccNone, DoWord }, /* .WORD */
|
||||
{ ccNone, DoUnexpected }, /* .XMATCH */
|
||||
{ ccNone, DoZeropage },
|
||||
{ ccNone, DoZeropage }, /* .ZEROPAGE */
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -221,6 +221,7 @@ struct DotKeyword {
|
||||
{ ".IFNDEF", TOK_IFNDEF },
|
||||
{ ".IFNREF", TOK_IFNREF },
|
||||
{ ".IFP02", TOK_IFP02 },
|
||||
{ ".IFP02X", TOK_IFP02X },
|
||||
{ ".IFP4510", TOK_IFP4510 },
|
||||
{ ".IFP816", TOK_IFP816 },
|
||||
{ ".IFPC02", TOK_IFPC02 },
|
||||
@@ -259,6 +260,7 @@ struct DotKeyword {
|
||||
{ ".ORG", TOK_ORG },
|
||||
{ ".OUT", TOK_OUT },
|
||||
{ ".P02", TOK_P02 },
|
||||
{ ".P02X", TOK_P02X },
|
||||
{ ".P4510", TOK_P4510 },
|
||||
{ ".P816", TOK_P816 },
|
||||
{ ".PAGELEN", TOK_PAGELENGTH },
|
||||
|
||||
@@ -193,6 +193,7 @@ typedef enum token_t {
|
||||
TOK_IFNDEF,
|
||||
TOK_IFNREF,
|
||||
TOK_IFP02,
|
||||
TOK_IFP02X,
|
||||
TOK_IFP4510,
|
||||
TOK_IFP816,
|
||||
TOK_IFPC02,
|
||||
@@ -226,6 +227,7 @@ typedef enum token_t {
|
||||
TOK_ORG,
|
||||
TOK_OUT,
|
||||
TOK_P02,
|
||||
TOK_P02X,
|
||||
TOK_P4510,
|
||||
TOK_P816,
|
||||
TOK_PAGELENGTH,
|
||||
|
||||
@@ -496,6 +496,14 @@ void Compile (const char* FileName)
|
||||
while (PreprocessNextLine ())
|
||||
{ /* Nothing */ }
|
||||
|
||||
/* Output macros if requested by the user */
|
||||
if (DumpPredefMacros) {
|
||||
OutputPredefMacros ();
|
||||
}
|
||||
if (DumpUserMacros) {
|
||||
OutputUserMacros ();
|
||||
}
|
||||
|
||||
/* Close the output file */
|
||||
CloseOutputFile ();
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
/* common */
|
||||
#include "coll.h"
|
||||
#include "debugflag.h"
|
||||
#include "print.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
@@ -183,11 +184,15 @@ static unsigned GetDiagnosticLineNum (void)
|
||||
|
||||
|
||||
|
||||
void Fatal (const char* Format, ...)
|
||||
void Fatal_ (const char *file, int line, const char* Format, ...)
|
||||
/* Print a message about a fatal error and die */
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (Debug) {
|
||||
fprintf(stderr, "[%s:%d] ", file, line);
|
||||
}
|
||||
|
||||
fprintf (stderr, "%s:%u: Fatal: ", GetDiagnosticFileName (), GetDiagnosticLineNum ());
|
||||
|
||||
va_start (ap, Format);
|
||||
@@ -203,11 +208,15 @@ void Fatal (const char* Format, ...)
|
||||
|
||||
|
||||
|
||||
void Internal (const char* Format, ...)
|
||||
void Internal_ (const char *file, int line, const char* Format, ...)
|
||||
/* Print a message about an internal compiler error and die */
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (Debug) {
|
||||
fprintf(stderr, "[%s:%d] ", file, line);
|
||||
}
|
||||
|
||||
fprintf (stderr, "%s:%u: Internal compiler error:\n",
|
||||
GetDiagnosticFileName (), GetDiagnosticLineNum ());
|
||||
|
||||
@@ -270,10 +279,15 @@ static void IntError (errcat_t EC, LineInfo* LI, const char* Msg, va_list ap)
|
||||
|
||||
|
||||
|
||||
void LIError (errcat_t EC, LineInfo* LI, const char* Format, ...)
|
||||
void LIError_ (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...)
|
||||
/* Print an error message with the line info given explicitly */
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (Debug) {
|
||||
fprintf(stderr, "[%s:%d] ", file, line);
|
||||
}
|
||||
|
||||
va_start (ap, Format);
|
||||
IntError (EC, LI, Format, ap);
|
||||
va_end (ap);
|
||||
@@ -281,10 +295,15 @@ void LIError (errcat_t EC, LineInfo* LI, const char* Format, ...)
|
||||
|
||||
|
||||
|
||||
void Error (const char* Format, ...)
|
||||
void Error_ (const char *file, int line, const char* Format, ...)
|
||||
/* Print an error message */
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (Debug) {
|
||||
fprintf(stderr, "[%s:%d] ", file, line);
|
||||
}
|
||||
|
||||
va_start (ap, Format);
|
||||
IntError (EC_PARSER, GetDiagnosticLI (), Format, ap);
|
||||
va_end (ap);
|
||||
@@ -292,10 +311,15 @@ void Error (const char* Format, ...)
|
||||
|
||||
|
||||
|
||||
void PPError (const char* Format, ...)
|
||||
void PPError_ (const char *file, int line, const char* Format, ...)
|
||||
/* Print an error message. For use within the preprocessor */
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (Debug) {
|
||||
fprintf(stderr, "[%s:%d] ", file, line);
|
||||
}
|
||||
|
||||
va_start (ap, Format);
|
||||
IntError (EC_PP, GetCurLineInfo (), Format, ap);
|
||||
va_end (ap);
|
||||
@@ -346,10 +370,15 @@ static void IntWarning (errcat_t EC, LineInfo* LI, const char* Msg, va_list ap)
|
||||
|
||||
|
||||
|
||||
void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...)
|
||||
void LIWarning_ (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...)
|
||||
/* Print a warning message with the line info given explicitly */
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (Debug) {
|
||||
fprintf(stderr, "[%s:%d] ", file, line);
|
||||
}
|
||||
|
||||
va_start (ap, Format);
|
||||
IntWarning (EC, LI, Format, ap);
|
||||
va_end (ap);
|
||||
@@ -357,10 +386,15 @@ void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...)
|
||||
|
||||
|
||||
|
||||
void Warning (const char* Format, ...)
|
||||
void Warning_ (const char *file, int line, const char* Format, ...)
|
||||
/* Print a warning message */
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (Debug) {
|
||||
fprintf(stderr, "[%s:%d] ", file, line);
|
||||
}
|
||||
|
||||
va_start (ap, Format);
|
||||
IntWarning (EC_PARSER, GetDiagnosticLI (), Format, ap);
|
||||
va_end (ap);
|
||||
@@ -368,10 +402,15 @@ void Warning (const char* Format, ...)
|
||||
|
||||
|
||||
|
||||
void PPWarning (const char* Format, ...)
|
||||
void PPWarning_ (const char *file, int line, const char* Format, ...)
|
||||
/* Print a warning message. For use within the preprocessor */
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (Debug) {
|
||||
fprintf(stderr, "[%s:%d] ", file, line);
|
||||
}
|
||||
|
||||
va_start (ap, Format);
|
||||
IntWarning (EC_PP, GetCurLineInfo (), Format, ap);
|
||||
va_end (ap);
|
||||
@@ -436,10 +475,15 @@ static void IntNote (const LineInfo* LI, const char* Msg, va_list ap)
|
||||
|
||||
|
||||
|
||||
void LINote (const LineInfo* LI, const char* Format, ...)
|
||||
void LINote_ (const char *file, int line, const LineInfo* LI, const char* Format, ...)
|
||||
/* Print a note message with the line info given explicitly */
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (Debug) {
|
||||
fprintf(stderr, "[%s:%d] ", file, line);
|
||||
}
|
||||
|
||||
va_start (ap, Format);
|
||||
IntNote (LI, Format, ap);
|
||||
va_end (ap);
|
||||
@@ -447,10 +491,15 @@ void LINote (const LineInfo* LI, const char* Format, ...)
|
||||
|
||||
|
||||
|
||||
void Note (const char* Format, ...)
|
||||
void Note_ (const char *file, int line, const char* Format, ...)
|
||||
/* Print a note message */
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (Debug) {
|
||||
fprintf(stderr, "[%s:%d] ", file, line);
|
||||
}
|
||||
|
||||
va_start (ap, Format);
|
||||
IntNote (GetDiagnosticLI (), Format, ap);
|
||||
va_end (ap);
|
||||
@@ -458,10 +507,15 @@ void Note (const char* Format, ...)
|
||||
|
||||
|
||||
|
||||
void PPNote (const char* Format, ...)
|
||||
void PPNote_ (const char *file, int line, const char* Format, ...)
|
||||
/* Print a note message. For use within the preprocessor */
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (Debug) {
|
||||
fprintf(stderr, "[%s:%d] ", file, line);
|
||||
}
|
||||
|
||||
va_start (ap, Format);
|
||||
IntNote (GetDiagnosticLI (), Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
@@ -103,28 +103,36 @@ struct StrBuf;
|
||||
void PrintFileInclusionInfo (const LineInfo* LI);
|
||||
/* Print hierarchy of file inclusion */
|
||||
|
||||
void Fatal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2)));
|
||||
void Fatal_ (const char *file, int line, const char* Format, ...) attribute ((noreturn, format (printf, 3, 4)));
|
||||
#define Fatal(...) Fatal_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
/* Print a message about a fatal error and die */
|
||||
|
||||
void Internal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2)));
|
||||
void Internal_ (const char *file, int line, const char* Format, ...) attribute ((noreturn, format (printf, 3, 4)));
|
||||
#define Internal(...) Internal_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
/* Print a message about an internal compiler error and die */
|
||||
|
||||
void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||
void Error_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
||||
#define Error(...) Error_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
/* Print an error message */
|
||||
|
||||
void LIError (errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
||||
void LIError_ (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 5, 6)));
|
||||
#define LIError(...) LIError_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
/* Print an error message with the line info given explicitly */
|
||||
|
||||
void PPError (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||
void PPError_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
||||
#define PPError(...) PPError_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
/* Print an error message. For use within the preprocessor */
|
||||
|
||||
void Warning (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||
void Warning_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
||||
#define Warning(...) Warning_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
/* Print a warning message */
|
||||
|
||||
void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
||||
void LIWarning_ (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 5, 6)));
|
||||
#define LIWarning(...) LIWarning_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
/* Print a warning message with the line info given explicitly */
|
||||
|
||||
void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||
void PPWarning_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
||||
#define PPWarning(...) PPWarning_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
/* Print a warning message. For use within the preprocessor */
|
||||
|
||||
void UnreachableCodeWarning (void);
|
||||
@@ -140,13 +148,16 @@ IntStack* FindWarning (const char* Name);
|
||||
void ListWarnings (FILE* F);
|
||||
/* Print a list of warning types/names to the given file */
|
||||
|
||||
void Note (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||
void Note_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
||||
#define Note(...) Note_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
/* Print a note message */
|
||||
|
||||
void LINote (const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 2, 3)));
|
||||
void LINote_ (const char *file, int line, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 4, 5)));
|
||||
#define LINote(...) LINote_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
/* Print a note message with the line info given explicitly */
|
||||
|
||||
void PPNote (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||
void PPNote_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4)));
|
||||
#define PPNote(...) PPNote_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
/* Print a note message. For use within the preprocessor */
|
||||
|
||||
unsigned GetTotalErrors (void);
|
||||
|
||||
@@ -44,12 +44,14 @@
|
||||
|
||||
|
||||
unsigned char AddSource = 0; /* Add source lines as comments */
|
||||
unsigned char AllowNewComments = 0; /* Allow new style comments in C89 mode */
|
||||
unsigned char AutoCDecl = 0; /* Make functions default to __cdecl__ */
|
||||
unsigned char DebugInfo = 0; /* Add debug info to the obj */
|
||||
unsigned char DumpPredefMacros = 0; /* Output predefined macros */
|
||||
unsigned char DumpUserMacros = 0; /* Output user macros */
|
||||
unsigned char PreprocessOnly = 0; /* Just preprocess the input */
|
||||
unsigned char DebugOptOutput = 0; /* Output debug stuff */
|
||||
unsigned RegisterSpace = 6; /* Space available for register vars */
|
||||
unsigned AllowNewComments = 0; /* Allow new style comments in C89 mode */
|
||||
|
||||
/* Stackable options */
|
||||
IntStack WritableStrings = INTSTACK(0); /* Literal strings are r/w */
|
||||
|
||||
@@ -52,12 +52,14 @@
|
||||
|
||||
/* Options */
|
||||
extern unsigned char AddSource; /* Add source lines as comments */
|
||||
extern unsigned char AllowNewComments; /* Allow new style comments in C89 mode */
|
||||
extern unsigned char AutoCDecl; /* Make functions default to __cdecl__ */
|
||||
extern unsigned char DebugInfo; /* Add debug info to the obj */
|
||||
extern unsigned char DumpPredefMacros; /* Output predefined macros */
|
||||
extern unsigned char DumpUserMacros; /* Output user macros */
|
||||
extern unsigned char PreprocessOnly; /* Just preprocess the input */
|
||||
extern unsigned char DebugOptOutput; /* Output debug stuff */
|
||||
extern unsigned RegisterSpace; /* Space available for register vars */
|
||||
extern unsigned AllowNewComments; /* Allow new style comments in C89 mode */
|
||||
|
||||
/* Stackable options */
|
||||
extern IntStack WritableStrings; /* Literal strings are r/w */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*****************************************************************************/
|
||||
|
||||
/* */
|
||||
/* macrotab.h */
|
||||
/* */
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
/* cc65 */
|
||||
#include "error.h"
|
||||
#include "output.h"
|
||||
#include "preproc.h"
|
||||
#include "macrotab.h"
|
||||
|
||||
@@ -60,6 +61,70 @@ static Macro* MacroTab[MACRO_TAB_SIZE];
|
||||
/* The undefined macros list head */
|
||||
static Macro* UndefinedMacrosListHead;
|
||||
|
||||
/* Some defines for better readability when calling OutputMacros() */
|
||||
#define USER_MACROS 0
|
||||
#define PREDEF_MACROS 1
|
||||
#define NAME_ONLY 0
|
||||
#define FULL_DEFINITION 1
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* helpers */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
static void OutputMacro (const Macro* M, int Full)
|
||||
/* Output one macro. If Full is true, the replacement is also output. */
|
||||
{
|
||||
WriteOutput ("#define %s", M->Name);
|
||||
int ParamCount = M->ParamCount;
|
||||
if (M->ParamCount >= 0) {
|
||||
int I;
|
||||
if (M->Variadic) {
|
||||
CHECK (ParamCount > 0);
|
||||
--ParamCount;
|
||||
}
|
||||
WriteOutput ("(");
|
||||
for (I = 0; I < ParamCount; ++I) {
|
||||
const char* Name = CollConstAt (&M->Params, I);
|
||||
WriteOutput ("%s%s", (I == 0)? "" : ",", Name);
|
||||
}
|
||||
if (M->Variadic) {
|
||||
WriteOutput ("%s...", (ParamCount == 0)? "" : ",");
|
||||
}
|
||||
WriteOutput (")");
|
||||
}
|
||||
WriteOutput (" ");
|
||||
if (Full) {
|
||||
WriteOutput ("%.*s",
|
||||
SB_GetLen (&M->Replacement),
|
||||
SB_GetConstBuf (&M->Replacement));
|
||||
}
|
||||
WriteOutput ("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OutputMacros (int Predefined, int Full)
|
||||
/* Output macros to the output file depending on the flags given. */
|
||||
{
|
||||
/* Note: The Full flag is currently not used by any callers but is left in
|
||||
** place for possible future changes.
|
||||
*/
|
||||
unsigned I;
|
||||
for (I = 0; I < MACRO_TAB_SIZE; ++I) {
|
||||
const Macro* M = MacroTab [I];
|
||||
while (M) {
|
||||
if ((Predefined != 0) == (M->Predefined != 0)) {
|
||||
OutputMacro (M, Full);
|
||||
}
|
||||
M = M->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -68,7 +133,7 @@ static Macro* UndefinedMacrosListHead;
|
||||
|
||||
|
||||
|
||||
Macro* NewMacro (const char* Name)
|
||||
Macro* NewMacro (const char* Name, unsigned char Predefined)
|
||||
/* Allocate a macro structure with the given name. The structure is not
|
||||
** inserted into the macro table.
|
||||
*/
|
||||
@@ -84,6 +149,7 @@ Macro* NewMacro (const char* Name)
|
||||
M->ParamCount = -1; /* Flag: Not a function-like macro */
|
||||
InitCollection (&M->Params);
|
||||
SB_Init (&M->Replacement);
|
||||
M->Predefined = Predefined;
|
||||
M->Variadic = 0;
|
||||
memcpy (M->Name, Name, Len+1);
|
||||
|
||||
@@ -116,7 +182,7 @@ Macro* CloneMacro (const Macro* M)
|
||||
** Use FreeMacro for that.
|
||||
*/
|
||||
{
|
||||
Macro* New = NewMacro (M->Name);
|
||||
Macro* New = NewMacro (M->Name, M->Predefined);
|
||||
unsigned I;
|
||||
|
||||
for (I = 0; I < CollCount (&M->Params); ++I) {
|
||||
@@ -134,7 +200,7 @@ Macro* CloneMacro (const Macro* M)
|
||||
|
||||
|
||||
void DefineNumericMacro (const char* Name, long Val)
|
||||
/* Define a macro for a numeric constant */
|
||||
/* Define a predefined macro for a numeric constant */
|
||||
{
|
||||
char Buf[64];
|
||||
|
||||
@@ -148,10 +214,10 @@ void DefineNumericMacro (const char* Name, long Val)
|
||||
|
||||
|
||||
void DefineTextMacro (const char* Name, const char* Val)
|
||||
/* Define a macro for a textual constant */
|
||||
/* Define a predefined macro for a textual constant */
|
||||
{
|
||||
/* Create a new macro */
|
||||
Macro* M = NewMacro (Name);
|
||||
Macro* M = NewMacro (Name, 1);
|
||||
|
||||
/* Set the value as replacement text */
|
||||
SB_CopyStr (&M->Replacement, Val);
|
||||
@@ -350,3 +416,19 @@ void PrintMacroStats (FILE* F)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OutputPredefMacros (void)
|
||||
/* Output all predefined macros to the output file */
|
||||
{
|
||||
OutputMacros (PREDEF_MACROS, FULL_DEFINITION);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OutputUserMacros (void)
|
||||
/* Output all user defined macros to the output file */
|
||||
{
|
||||
OutputMacros (USER_MACROS, FULL_DEFINITION);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ struct Macro {
|
||||
int ParamCount; /* Number of parameters, -1 = no parens */
|
||||
Collection Params; /* Parameter list (char*) */
|
||||
StrBuf Replacement; /* Replacement text */
|
||||
unsigned char Predefined; /* True if this is a predefined macro */
|
||||
unsigned char Variadic; /* C99 variadic macro */
|
||||
char Name[1]; /* Name, dynamically allocated */
|
||||
};
|
||||
@@ -70,7 +71,7 @@ struct Macro {
|
||||
|
||||
|
||||
|
||||
Macro* NewMacro (const char* Name);
|
||||
Macro* NewMacro (const char* Name, unsigned char Predefined);
|
||||
/* Allocate a macro structure with the given name. The structure is not
|
||||
** inserted into the macro table.
|
||||
*/
|
||||
@@ -87,10 +88,10 @@ Macro* CloneMacro (const Macro* M);
|
||||
*/
|
||||
|
||||
void DefineNumericMacro (const char* Name, long Val);
|
||||
/* Define a macro for a numeric constant */
|
||||
/* Define a predefined macro for a numeric constant */
|
||||
|
||||
void DefineTextMacro (const char* Name, const char* Val);
|
||||
/* Define a macro for a textual constant */
|
||||
/* Define a predefined macro for a textual constant */
|
||||
|
||||
void InsertMacro (Macro* M);
|
||||
/* Insert the given macro into the macro table. */
|
||||
@@ -132,6 +133,12 @@ int MacroCmp (const Macro* M1, const Macro* M2);
|
||||
void PrintMacroStats (FILE* F);
|
||||
/* Print macro statistics to the given text file. */
|
||||
|
||||
void OutputPredefMacros (void);
|
||||
/* Output all predefined macros to the output file */
|
||||
|
||||
void OutputUserMacros (void);
|
||||
/* Output all user defined macros to the output file */
|
||||
|
||||
|
||||
|
||||
/* End of macrotab.h */
|
||||
|
||||
@@ -93,6 +93,8 @@ static void Usage (void)
|
||||
" -V\t\t\t\tPrint the compiler version number\n"
|
||||
" -W [-+]warning[,...]\t\tControl warnings ('-' disables, '+' enables)\n"
|
||||
" -d\t\t\t\tDebug mode\n"
|
||||
" -dM\t\t\t\tOutput all user macros (needs -E)\n"
|
||||
" -dP\t\t\t\tOutput all predefined macros (needs -E)\n"
|
||||
" -g\t\t\t\tAdd debug info to object file\n"
|
||||
" -h\t\t\t\tHelp (this text)\n"
|
||||
" -j\t\t\t\tDefault characters are signed\n"
|
||||
@@ -1026,7 +1028,25 @@ int main (int argc, char* argv[])
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
OptDebug (Arg, 0);
|
||||
P = Arg + 2;
|
||||
if (*P == '\0') {
|
||||
OptDebug (Arg, 0);
|
||||
} else {
|
||||
while (*P) {
|
||||
switch (*P) {
|
||||
case 'M':
|
||||
DumpUserMacros = 1;
|
||||
break;
|
||||
case 'P':
|
||||
DumpPredefMacros = 1;
|
||||
break;
|
||||
default:
|
||||
UnknownOption (Arg);
|
||||
break;
|
||||
}
|
||||
++P;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
@@ -1138,6 +1158,11 @@ int main (int argc, char* argv[])
|
||||
AbEnd ("No input files");
|
||||
}
|
||||
|
||||
/* The options to output macros can only be used with -E */
|
||||
if ((DumpPredefMacros || DumpUserMacros) && !PreprocessOnly) {
|
||||
AbEnd ("Preprocessor macro output can only be used together with -E");
|
||||
}
|
||||
|
||||
/* Add the default include search paths. */
|
||||
FinishIncludePaths ();
|
||||
|
||||
|
||||
@@ -2575,7 +2575,7 @@ static void DoDefine (void)
|
||||
CheckForBadIdent (Ident, Std, 0);
|
||||
|
||||
/* Create a new macro definition */
|
||||
M = NewMacro (Ident);
|
||||
M = NewMacro (Ident, 0);
|
||||
|
||||
/* Check if this is a function-like macro */
|
||||
if (CurC == '(') {
|
||||
|
||||
@@ -169,7 +169,7 @@ char* MakeTmpFilename (const char *Directory, const char *Origin, const char* Ex
|
||||
Len += strlen (Origin) + (strlen (".2147483648") * 2) + strlen (Ext) + 1;
|
||||
Out = xmalloc (Len);
|
||||
|
||||
snprintf (Out, Len, "%s%s.%u%u%s", (Directory != NULL ? Directory : ""),
|
||||
snprintf (Out, Len, "%s%s.%u.%u%s", (Directory != NULL ? Directory : ""),
|
||||
FindName(Origin), getpid(), Counter, Ext);
|
||||
Counter++;
|
||||
|
||||
|
||||
Binary file not shown.
@@ -8,6 +8,10 @@
|
||||
lda #$ea
|
||||
.endif
|
||||
|
||||
.ifp02x
|
||||
lax #$ea
|
||||
.endif
|
||||
|
||||
.ifpsc02
|
||||
jmp ($1234,x)
|
||||
.endif
|
||||
@@ -72,3 +76,13 @@
|
||||
.byte 0,"CPU_ISET_6502DTV"
|
||||
.endif
|
||||
|
||||
|
||||
; step 3: switch through all supported cpus to verify the pseudo-op is there
|
||||
|
||||
.p02
|
||||
.p02X
|
||||
.psc02
|
||||
.pc02
|
||||
.p816
|
||||
.p4510
|
||||
.pdtv
|
||||
|
||||
162
test/standard/null.c
Normal file
162
test/standard/null.c
Normal file
@@ -0,0 +1,162 @@
|
||||
|
||||
|
||||
/* test headers which should define NULL */
|
||||
|
||||
#include <locale.h>
|
||||
#ifndef NULL
|
||||
#error "NULL should be defined in locale.h"
|
||||
#endif
|
||||
#undef NULL
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifndef NULL
|
||||
#error "NULL should be defined in stdlib.h"
|
||||
#endif
|
||||
#undef NULL
|
||||
|
||||
#include <string.h>
|
||||
#ifndef NULL
|
||||
#error "NULL should be defined in string.h"
|
||||
#endif
|
||||
#undef NULL
|
||||
|
||||
#include <stddef.h>
|
||||
#ifndef NULL
|
||||
#error "NULL should be defined in stddef.h"
|
||||
#endif
|
||||
#undef NULL
|
||||
|
||||
#include <stdio.h>
|
||||
#ifndef NULL
|
||||
#error "NULL should be defined in stdio.h"
|
||||
#endif
|
||||
#undef NULL
|
||||
|
||||
#include <time.h>
|
||||
#ifndef NULL
|
||||
#error "NULL should be defined in time.h"
|
||||
#endif
|
||||
#undef NULL
|
||||
|
||||
/* does not exist in cc65 (yet)
|
||||
#include <wchar.h>
|
||||
#ifndef NULL
|
||||
#error "NULL should be defined in wchar.h"
|
||||
#endif */
|
||||
#undef NULL
|
||||
|
||||
|
||||
/* test headers which should NOT define NULL */
|
||||
|
||||
#include <assert.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in assert.h"
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
/* does not exist in cc65 (yet)
|
||||
#include <complex.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in complex.h"
|
||||
#undef NULL
|
||||
#endif */
|
||||
|
||||
#include <ctype.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in ctype.h"
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in errno.h"
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
/* does not exist in cc65 (yet)
|
||||
#include <fenv.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in fenv.h"
|
||||
#undef NULL
|
||||
#endif */
|
||||
|
||||
/* does not exist in cc65 (yet)
|
||||
#include <float.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in float.h"
|
||||
#undef NULL
|
||||
#endif */
|
||||
|
||||
#include <inttypes.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in inttypes.h"
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
#include <iso646.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in iso646.h"
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in limits.h"
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
/* does not exist in cc65 (yet)
|
||||
#include <math.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in math.h"
|
||||
#undef NULL
|
||||
#endif */
|
||||
|
||||
#include <setjmp.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in setjmp.h"
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in signal.h"
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in stdarg.h"
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in stdbool.h"
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in stdint.h"
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
/* does not exist in cc65 (yet)
|
||||
#include <tgmath.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in tgmath.h"
|
||||
#undef NULL
|
||||
#endif */
|
||||
|
||||
/* does not exist in cc65 (yet)
|
||||
#include <wctype.h>
|
||||
#ifdef NULL
|
||||
#error "NULL should NOT be defined in wctype.h"
|
||||
#undef NULL
|
||||
#endif */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
56
test/todo/bug2172_invalid_code.c
Normal file
56
test/todo/bug2172_invalid_code.c
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
// bug #2172 - Invalid code generated for switch statement
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// cc65 -o bug2172.s -Cl -Oirs -T -t c64 bug2172.c
|
||||
int func(int expr)
|
||||
{
|
||||
switch (expr) {
|
||||
int i;
|
||||
case 0:
|
||||
i = 17;
|
||||
return i;
|
||||
default:
|
||||
i = 16;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
int err = 0;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i = 0;
|
||||
int n = 42;
|
||||
for (i = -3; i < 0; i++) {
|
||||
n = func(i);
|
||||
if ((i < -3) || (i >= 0)) {
|
||||
goto stackerr;
|
||||
}
|
||||
printf("i:%d expect:16 got:%d\n", i, n);
|
||||
if (n != 16) {
|
||||
err++;
|
||||
}
|
||||
}
|
||||
n = func(0);
|
||||
printf("i:%d expect:17 got:%d\n", 0, n);
|
||||
if (n != 17) {
|
||||
err++;
|
||||
}
|
||||
for (i = 1; i < 4; i++) {
|
||||
n = func(i);
|
||||
if ((i < 1) || (i >= 4)) {
|
||||
goto stackerr;
|
||||
}
|
||||
printf("i:%d expect:16 got:%d\n", i, n);
|
||||
if (n != 16) {
|
||||
err++;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
stackerr:
|
||||
fputs("stack messed up?\n", stdout);
|
||||
return -1;
|
||||
}
|
||||
51
test/todo/bug2172b_invalid_code.c
Normal file
51
test/todo/bug2172b_invalid_code.c
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Just some arbitrary code, more fun with goto */
|
||||
int func(int m)
|
||||
{
|
||||
long x = -42; /* sp: -4 */
|
||||
switch (x) {
|
||||
/* return 0; // C99 only */
|
||||
int i = 42; /* sp: -6 */
|
||||
L0:
|
||||
--i;
|
||||
default:
|
||||
if (i != 0) {
|
||||
long j = 13; /* sp: -10 */
|
||||
goto L1;
|
||||
L1:
|
||||
case 0x7FFF01:
|
||||
m--;
|
||||
case 0x7EFF0001:
|
||||
case 0x7FFF0001:
|
||||
i++;
|
||||
} /* sp: -6 */
|
||||
case 0x7FFF00:
|
||||
case 0x7FFF0000:
|
||||
break;
|
||||
goto L0;
|
||||
{
|
||||
int skipped = 42; /* sp: -8 */
|
||||
case 0x7EFF00:
|
||||
case 0x7EFF0000:
|
||||
++skipped;
|
||||
} /* sp: -6 */
|
||||
} /* sp: -4 */
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
int err = 0;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int n = 42;
|
||||
n = func(7);
|
||||
if (n != 7) {
|
||||
err++;
|
||||
}
|
||||
printf("n:%d\n", n);
|
||||
return err;
|
||||
}
|
||||
Reference in New Issue
Block a user