Merge branch 'master' into sane_makefile_output
This commit is contained in:
13
.github/checks/Makefile
vendored
13
.github/checks/Makefile
vendored
@@ -5,14 +5,18 @@ endif
|
|||||||
|
|
||||||
ifdef CMD_EXE
|
ifdef CMD_EXE
|
||||||
|
|
||||||
.PHONY: checkstyle
|
.PHONY: checkstyle sorted
|
||||||
|
|
||||||
checkstyle:
|
checkstyle:
|
||||||
$(info INFO: style checks require bash.)
|
$(info INFO: style checks require bash.)
|
||||||
|
sorted:
|
||||||
|
$(info INFO: table checks require bash.)
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
.PHONY: checkstyle lineendings tabs lastline spaces noexec
|
.PHONY: checkstyle lineendings tabs lastline spaces noexec sorted
|
||||||
|
|
||||||
|
all: checkstyle sorted
|
||||||
|
|
||||||
checkstyle: lineendings tabs lastline spaces noexec
|
checkstyle: lineendings tabs lastline spaces noexec
|
||||||
|
|
||||||
@@ -31,4 +35,9 @@ spaces: spaces.sh
|
|||||||
noexec: noexec.sh
|
noexec: noexec.sh
|
||||||
@./noexec.sh
|
@./noexec.sh
|
||||||
|
|
||||||
|
sorted: sorted.sh sorted_codeopt.sh sorted_opcodes.sh
|
||||||
|
@./sorted.sh
|
||||||
|
@./sorted_codeopt.sh
|
||||||
|
@./sorted_opcodes.sh
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
38
.github/checks/sorted.sh
vendored
Executable file
38
.github/checks/sorted.sh
vendored
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
OLDCWD=`pwd`
|
||||||
|
SCRIPT_PATH=`dirname $0`
|
||||||
|
|
||||||
|
CHECK_DIR=../../src
|
||||||
|
|
||||||
|
SORT_OPT="-u -c"
|
||||||
|
|
||||||
|
# $1: filename
|
||||||
|
function checkarray_quoted_name
|
||||||
|
{
|
||||||
|
CHECK_FILE="$1"
|
||||||
|
START="\\/\\* BEGIN SORTED.SH \\*\\/"
|
||||||
|
END="\\/\\* END SORTED.SH \\*\\/"
|
||||||
|
|
||||||
|
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"
|
||||||
|
rm -rf .a.tmp
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if `LC_COLLATE=C sort $SORT_OPT .a.tmp`; then
|
||||||
|
echo ""$1" tables OK"
|
||||||
|
else
|
||||||
|
echo "error: "$1" tables are not sorted."
|
||||||
|
rm -rf .a.tmp
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
rm -rf .a.tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for N in `grep -rl "BEGIN SORTED.SH" "$CHECK_DIR"`; do
|
||||||
|
checkarray_quoted_name $N
|
||||||
|
done
|
||||||
68
.github/checks/sorted_codeopt.sh
vendored
Executable file
68
.github/checks/sorted_codeopt.sh
vendored
Executable file
@@ -0,0 +1,68 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
OLDCWD=`pwd`
|
||||||
|
SCRIPT_PATH=`dirname $0`
|
||||||
|
|
||||||
|
CHECK_DIR=../../src
|
||||||
|
|
||||||
|
SORT_OPT="-u -c"
|
||||||
|
|
||||||
|
# $1: filename
|
||||||
|
function checkarray
|
||||||
|
{
|
||||||
|
CHECK_FILE="$1"
|
||||||
|
START="\\/\\* BEGIN DECL SORTED_CODEOPT.SH \\*\\/"
|
||||||
|
END="\\/\\* END DECL SORTED_CODEOPT.SH \\*\\/"
|
||||||
|
|
||||||
|
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"
|
||||||
|
rm -rf .a.tmp
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if `LC_COLLATE=C sort $SORT_OPT .a.tmp`; then
|
||||||
|
echo ""$1" decls sorted."
|
||||||
|
else
|
||||||
|
echo "error: "$1" decls are not sorted."
|
||||||
|
rm -rf .a.tmp
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
START="\\/\\* BEGIN SORTED_CODEOPT.SH \\*\\/"
|
||||||
|
END="\\/\\* END SORTED_CODEOPT.SH \\*\\/"
|
||||||
|
|
||||||
|
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
|
||||||
|
echo "error: "$1" table is empty"
|
||||||
|
rm -rf .a.tmp .b.tmp
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if `LC_COLLATE=C sort $SORT_OPT .b.tmp`; then
|
||||||
|
echo ""$1" tables sorted."
|
||||||
|
else
|
||||||
|
echo "error: "$1" tables are not sorted."
|
||||||
|
rm -rf .a.tmp .b.tmp
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if cmp --silent -- .a.tmp .b.tmp; then
|
||||||
|
echo ""$1" tables OK"
|
||||||
|
else
|
||||||
|
echo "error: "$1" tables are different."
|
||||||
|
diff -y .a.tmp .b.tmp
|
||||||
|
rm -rf .a.tmp .b.tmp
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf .a.tmp .b.tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for N in `grep -rl "BEGIN DECL SORTED_CODEOPT.SH" "$CHECK_DIR"`; do
|
||||||
|
checkarray $N
|
||||||
|
done
|
||||||
40
.github/checks/sorted_opcodes.sh
vendored
Executable file
40
.github/checks/sorted_opcodes.sh
vendored
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
OLDCWD=`pwd`
|
||||||
|
SCRIPT_PATH=`dirname $0`
|
||||||
|
|
||||||
|
CHECK_DIR=../../src
|
||||||
|
|
||||||
|
SORT_OPT="-u -c"
|
||||||
|
|
||||||
|
# $1: filename
|
||||||
|
function checkarray_quoted_name
|
||||||
|
{
|
||||||
|
CHECK_FILE="$1"
|
||||||
|
START="\\/\\* BEGIN SORTED_OPCODES.SH \\*\\/"
|
||||||
|
END="\\/\\* END SORTED_OPCODES.SH \\*\\/"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then
|
||||||
|
echo "error: "$1" table is empty"
|
||||||
|
rm -rf .a.tmp
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if `LC_COLLATE=C sort $SORT_OPT .a.tmp`; then
|
||||||
|
echo ""$1" tables OK"
|
||||||
|
else
|
||||||
|
echo "error: "$1" tables are not sorted."
|
||||||
|
rm -rf .a.tmp
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
rm -rf .a.tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
for N in `grep -rl "BEGIN SORTED_OPCODES.SH" "$CHECK_DIR"`; do
|
||||||
|
checkarray_quoted_name $N
|
||||||
|
done
|
||||||
|
|
||||||
6
.github/workflows/build-on-pull-request.yml
vendored
6
.github/workflows/build-on-pull-request.yml
vendored
@@ -24,9 +24,15 @@ jobs:
|
|||||||
- name: Do some simple style checks
|
- name: Do some simple style checks
|
||||||
shell: bash
|
shell: bash
|
||||||
run: make -j2 checkstyle
|
run: make -j2 checkstyle
|
||||||
|
- name: Check bsearch tables
|
||||||
|
shell: bash
|
||||||
|
run: make -j2 sorted
|
||||||
- name: Build the tools.
|
- name: Build the tools.
|
||||||
shell: bash
|
shell: bash
|
||||||
run: make -j2 bin USER_CFLAGS=-Werror
|
run: make -j2 bin USER_CFLAGS=-Werror
|
||||||
|
- name: Build the dbginfo example
|
||||||
|
shell: bash
|
||||||
|
run: make -j2 -C src test
|
||||||
- name: Build the utilities.
|
- name: Build the utilities.
|
||||||
shell: bash
|
shell: bash
|
||||||
run: make -j2 util
|
run: make -j2 util
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ jobs:
|
|||||||
- name: Do some simple style checks
|
- name: Do some simple style checks
|
||||||
shell: bash
|
shell: bash
|
||||||
run: make -j2 checkstyle
|
run: make -j2 checkstyle
|
||||||
|
- name: Check bsearch tables
|
||||||
|
shell: bash
|
||||||
|
run: make -j2 sorted
|
||||||
- name: Build the tools.
|
- name: Build the tools.
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
8
Makefile
8
Makefile
@@ -51,7 +51,11 @@ util:
|
|||||||
|
|
||||||
# check the code style
|
# check the code style
|
||||||
checkstyle:
|
checkstyle:
|
||||||
@$(MAKE) -C .github/checks --no-print-directory $@
|
@$(MAKE) -C .github/checks --no-print-directory $@
|
||||||
|
|
||||||
|
# check bsearch tables
|
||||||
|
sorted:
|
||||||
|
@$(MAKE) -C .github/checks --no-print-directory $@
|
||||||
|
|
||||||
# runs regression tests, requires libtest target libraries
|
# runs regression tests, requires libtest target libraries
|
||||||
test:
|
test:
|
||||||
@@ -60,6 +64,8 @@ test:
|
|||||||
# GNU "check" target, which runs all tests
|
# GNU "check" target, which runs all tests
|
||||||
check:
|
check:
|
||||||
@$(MAKE) -C .github/checks checkstyle --no-print-directory
|
@$(MAKE) -C .github/checks checkstyle --no-print-directory
|
||||||
|
@$(MAKE) -C .github/checks sorted --no-print-directory
|
||||||
|
@$(MAKE) -C src test --no-print-directory
|
||||||
@$(MAKE) test
|
@$(MAKE) test
|
||||||
@$(MAKE) -C targettest platforms --no-print-directory
|
@$(MAKE) -C targettest platforms --no-print-directory
|
||||||
@$(MAKE) -C samples platforms --no-print-directory
|
@$(MAKE) -C samples platforms --no-print-directory
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ the [cc65 web site](https://cc65.github.io):
|
|||||||
| Dr. Jozo Dujmović | Picocomputer (RP6502) |
|
| Dr. Jozo Dujmović | Picocomputer (RP6502) |
|
||||||
| Watara | Watura/QuickShot Supervision |
|
| Watara | Watura/QuickShot Supervision |
|
||||||
| Synertek | SYM-1 |
|
| Synertek | SYM-1 |
|
||||||
|
| USSR | Agat-7/9 |
|
||||||
|
|
||||||
A generic configuration to adapt cc65 to new targets is also around.
|
A generic configuration to adapt cc65 to new targets is also around.
|
||||||
|
|
||||||
|
|||||||
39
asminc/agat.inc
Normal file
39
asminc/agat.inc
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
; Zero page stuff
|
||||||
|
|
||||||
|
WNDLFT := $20 ; Text window left
|
||||||
|
WNDWDTH := $21 ; Text window width
|
||||||
|
WNDTOP := $22 ; Text window top
|
||||||
|
WNDBTM := $23 ; Text window bottom+1
|
||||||
|
CH := $24 ; Cursor horizontal position
|
||||||
|
CV := $25 ; Cursor vertical position
|
||||||
|
BASL := $28 ; Text base address low
|
||||||
|
BASH := $29 ; Text base address high
|
||||||
|
CURSOR := $2D ; Cursor character
|
||||||
|
TATTR := $32 ; Text attributes
|
||||||
|
PROMPT := $33 ; Used by GETLN
|
||||||
|
VCOUT := $36 ; COUT Subroutine Vector
|
||||||
|
VCIN := $38 ; CIN Subroutine Vector
|
||||||
|
RNDL := $4E ; Random counter low
|
||||||
|
RNDH := $4F ; Random counter high
|
||||||
|
HIMEM := $73 ; Highest available memory address+1
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
; Vectors
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
; Hardware
|
||||||
|
|
||||||
|
; Keyboard input
|
||||||
|
KBD := $C000 ; Read keyboard
|
||||||
|
KBDSTRB := $C010 ; Clear keyboard strobe
|
||||||
|
|
||||||
|
; Game controller
|
||||||
|
BUTN0 := $C061 ; Open-Apple Key
|
||||||
|
BUTN1 := $C062 ; Closed-Apple Key
|
||||||
@@ -24,6 +24,8 @@ DOSWARM := $03D0 ; DOS warmstart vector
|
|||||||
BRKVec := $03F0 ; Break vector
|
BRKVec := $03F0 ; Break vector
|
||||||
SOFTEV := $03F2 ; Vector for warm start
|
SOFTEV := $03F2 ; Vector for warm start
|
||||||
PWREDUP := $03F4 ; This must be = EOR #$A5 of SOFTEV+1
|
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
|
; 80 column firmware
|
||||||
|
|||||||
44
cfg/agat.cfg
Normal file
44
cfg/agat.cfg
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Default configuration
|
||||||
|
|
||||||
|
FEATURES {
|
||||||
|
STARTADDRESS: default = $1903;
|
||||||
|
}
|
||||||
|
SYMBOLS {
|
||||||
|
__EXEHDR__: type = import;
|
||||||
|
__FILETYPE__: type = weak, value = $0006; # file type
|
||||||
|
__STACKSIZE__: type = weak, value = $0400; # 1k stack
|
||||||
|
__HIMEM__: type = weak, value = $C000; # Presumed RAM end
|
||||||
|
}
|
||||||
|
MEMORY {
|
||||||
|
ZP: file = "", define = yes, start = $0080, size = $001A;
|
||||||
|
HEADER: file = %O, start = %S - $003A, size = $003A;
|
||||||
|
MAIN: file = %O, define = yes, start = %S, size = __HIMEM__ - %S;
|
||||||
|
BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__;
|
||||||
|
}
|
||||||
|
SEGMENTS {
|
||||||
|
ZEROPAGE: load = ZP, type = zp;
|
||||||
|
EXEHDR: load = HEADER, type = ro, optional = yes;
|
||||||
|
STARTUP: load = MAIN, type = ro, optional = yes;
|
||||||
|
LOWCODE: load = MAIN, type = ro, optional = yes;
|
||||||
|
CODE: load = MAIN, type = ro;
|
||||||
|
RODATA: load = MAIN, type = ro;
|
||||||
|
DATA: load = MAIN, type = rw;
|
||||||
|
INIT: load = MAIN, type = rw, optional = yes;
|
||||||
|
ONCE: load = MAIN, type = ro, define = yes;
|
||||||
|
BSS: load = BSS, type = bss, 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__;
|
||||||
|
}
|
||||||
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__;
|
||||||
|
}
|
||||||
79
doc/agat.sgml
Normal file
79
doc/agat.sgml
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<!doctype linuxdoc system>
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<title>Agat-7/9 - specific information for cc65
|
||||||
|
|
||||||
|
<author><url url="https://sourceforge.net/u/olegodintsov/profile/" name="Oleg A. Odintsov">,<newline>
|
||||||
|
<url url="mailto:sintechs@gmail.com" name="Konstantin Fedorov">
|
||||||
|
|
||||||
|
<abstract>
|
||||||
|
An overview over the Agat-7 and Agat-9 and theirs interfaces to the cc65 C
|
||||||
|
compiler.
|
||||||
|
</abstract>
|
||||||
|
|
||||||
|
<!-- Table of contents -->
|
||||||
|
<toc>
|
||||||
|
|
||||||
|
<!-- Begin the document -->
|
||||||
|
|
||||||
|
<sect>Overview
|
||||||
|
|
||||||
|
<p>The Agat was a series of 8-bit computers produced in the Soviet Union from 1983 to 1993.
|
||||||
|
It was based on Apple II architecture with all electronic components made in the Soviet Union except for 6502 microprocessors supplied by UMC (UM6502A).
|
||||||
|
<p>If compared to Apple II, Agat had many improvements such as color text mode, additional graphic modes and flexible memory controller.
|
||||||
|
Agat-7 had an Apple II compatibility card called "Module 121", while Agat-9 had a built-in Apple II+ mode activated by soft-switch.
|
||||||
|
<p>All mass-produced Agat models were disk-based systems, 2K ROM contained only basic machine language monitor and disassembler.
|
||||||
|
Agat-7 had 140K floppy-drive based on Apple DISK II, while Agat-9 was supplied with 840K drive having its own sector format and controller.
|
||||||
|
|
||||||
|
<sect>Binary format<p>
|
||||||
|
|
||||||
|
The standard binary file format generated by the linker for the Agat target is
|
||||||
|
an AppleSingle file to be compatible with AppleCommander <url url="https://applecommander.github.io/">.
|
||||||
|
The default load address is $1903.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect>Platform-specific header files<p>
|
||||||
|
|
||||||
|
Programs containing Agat-specific code may use the <tt/agat.h/ or
|
||||||
|
<tt/agat.inc/ include files.
|
||||||
|
|
||||||
|
<sect>Usefull info<p>
|
||||||
|
|
||||||
|
<sect1>Emulation<p>
|
||||||
|
|
||||||
|
<enum>
|
||||||
|
<item> Oleg Odintsov's Agat Emulator - <url url="https://agatemulator.sourceforge.net/english.html">
|
||||||
|
<item> MAME - <url url="https://www.mamedev.org/">
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<sect1>Links<p>
|
||||||
|
<enum>
|
||||||
|
<item> Most informative source on Agat (in russian) - <url url="https://agatcomp.ru">
|
||||||
|
<item> Wikipedia - <url url="https://en.wikipedia.org/wiki/Agat_(computer)">
|
||||||
|
<item> Controversial article on Agat from <url name="BYTE Magazine November 1984 Vol. 9, No. 12" url="https://archive.org/details/byte-magazine-1984-11/page/n135/mode/2up?view=theater">.
|
||||||
|
The author reviewed custom-build mockup Agat bearing little relation to even the early Agat systems.
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
|
||||||
|
<sect>License<p>
|
||||||
|
|
||||||
|
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:
|
||||||
|
<enum>
|
||||||
|
<item> 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.
|
||||||
|
<item> Altered source versions must be plainly marked as such, and must not
|
||||||
|
be misrepresented as being the original software.
|
||||||
|
<item> This notice may not be removed or altered from any source
|
||||||
|
distribution.
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
</article>
|
||||||
@@ -87,7 +87,7 @@ several useful settings:
|
|||||||
exit then a plain vanilla ProDOS 8 doesn't make use of the Language Card bank
|
exit then a plain vanilla ProDOS 8 doesn't make use of the Language Card bank
|
||||||
2 at all.
|
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.
|
For plain vanilla DOS 3.3 which doesn't make use of the Language Card at all.
|
||||||
|
|
||||||
</descrip><p>
|
</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
|
exit then a plain vanilla ProDOS 8 doesn't make use of the Language Card bank
|
||||||
2 at all.
|
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.
|
For plain vanilla DOS 3.3 which doesn't make use of the Language Card at all.
|
||||||
|
|
||||||
</descrip><p>
|
</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).
|
(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>
|
<sect1><tt>.IFP4510</tt><label id=".IFP4510"><p>
|
||||||
|
|
||||||
Conditional assembly: Check if the assembler is currently in 4510 mode
|
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>
|
<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>
|
<sect1><tt>.P4510</tt><label id=".P4510"><p>
|
||||||
|
|
||||||
Enable the 4510 instruction set. This is a superset of the 65C02 and
|
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>,
|
See: <tt><ref id=".CPU" name=".CPU"></tt>,
|
||||||
<tt><ref id=".IFP02" name=".IFP02"></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=".IFPDTV" name=".IFPDTV"></tt>,
|
||||||
<tt><ref id=".IFP816" name=".IFP816"></tt>,
|
<tt><ref id=".IFP816" name=".IFP816"></tt>,
|
||||||
<tt><ref id=".IFPC02" name=".IFPC02"></tt>,
|
<tt><ref id=".IFPC02" name=".IFPC02"></tt>,
|
||||||
<tt><ref id=".IFPSC02" name=".IFPSC02"></tt>,
|
<tt><ref id=".IFPSC02" name=".IFPSC02"></tt>,
|
||||||
<tt><ref id=".P02" name=".P02"></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=".P816" name=".P816"></tt>,
|
||||||
<tt><ref id=".P4510" name=".P4510"></tt>,
|
<tt><ref id=".P4510" name=".P4510"></tt>,
|
||||||
<tt><ref id=".PC02" name=".PC02"></tt>,
|
<tt><ref id=".PC02" name=".PC02"></tt>,
|
||||||
|
|||||||
114
doc/cc65.sgml
114
doc/cc65.sgml
@@ -63,6 +63,8 @@ Short options:
|
|||||||
-V Print the compiler version number
|
-V Print the compiler version number
|
||||||
-W [-+]warning[,...] Control warnings ('-' disables, '+' enables)
|
-W [-+]warning[,...] Control warnings ('-' disables, '+' enables)
|
||||||
-d Debug mode
|
-d Debug mode
|
||||||
|
-dM Output all user macros (needs -E)
|
||||||
|
-dP Output all predefined macros (needs -E)
|
||||||
-g Add debug info to object file
|
-g Add debug info to object file
|
||||||
-h Help (this text)
|
-h Help (this text)
|
||||||
-j Default characters are signed
|
-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.
|
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>
|
<tag><tt>--debug-tables name</tt></tag>
|
||||||
|
|
||||||
Writes symbol table information to a file, which includes details on structs, unions
|
Writes symbol table information to a file, which includes details on structs, unions
|
||||||
@@ -1154,6 +1178,96 @@ The compiler defines several macros at startup:
|
|||||||
<item><tt/__CC65_STD_CC65__/
|
<item><tt/__CC65_STD_CC65__/
|
||||||
</itemize>
|
</itemize>
|
||||||
|
|
||||||
|
<label id="macro-CPU">
|
||||||
|
<tag><tt>__CPU__</tt></tag>
|
||||||
|
|
||||||
|
This macro contains a bitset that allows to check if a specific instruction
|
||||||
|
set is supported. For example, the 65C02 CPU supports all instructions of the
|
||||||
|
65SC02. So testing for the instruction set of the 65SC02 using the following
|
||||||
|
check will succeed for both CPUs (and also for the 65816 and HUC6280).
|
||||||
|
|
||||||
|
<tscreen><verb>
|
||||||
|
#if (__CPU__ & __CPU_ISET_65SC02__)
|
||||||
|
</verb></tscreen>
|
||||||
|
|
||||||
|
This is much simpler and more future proof than checking for specific CPUs.
|
||||||
|
|
||||||
|
The compiler defines a set of constants named <tt/__CPU_ISET_xxx/ to do the
|
||||||
|
checks. The <tt/__CPU__/ variable is usually derived from the target system
|
||||||
|
given, but can be changed using the <tt/<ref id="option--cpu" name="--cpu">/
|
||||||
|
command line option.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_6502__</tt></tag>
|
||||||
|
|
||||||
|
This macro is defined if the code is compiled for a 6502 CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_6502X__</tt></tag>
|
||||||
|
|
||||||
|
This macro is defined if the code is compiled for a 6502 CPU with invalid
|
||||||
|
opcodes.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_6502DTV__</tt></tag>
|
||||||
|
|
||||||
|
This macro is defined if the code is compiled for a DTV CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_65SC02__</tt></tag>
|
||||||
|
|
||||||
|
This macro is defined if the code is compiled for a 65SC02 CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_65C02__</tt></tag>
|
||||||
|
|
||||||
|
This macro is defined if the code is compiled for a 65C02 CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_65816__</tt></tag>
|
||||||
|
|
||||||
|
This macro is defined if the code is compiled for a 65816 CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_HUC6280__</tt></tag>
|
||||||
|
|
||||||
|
This macro is defined if the code is compiled for a HUC6280 CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_ISET_6502__</tt></tag>
|
||||||
|
|
||||||
|
This macro expands to a numeric constant that can be used to check the
|
||||||
|
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||||
|
of the 6502 CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_ISET_6502X__</tt></tag>
|
||||||
|
|
||||||
|
This macro expands to a numeric constant that can be used to check the
|
||||||
|
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||||
|
of the 6502X CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_ISET_6502DTV__</tt></tag>
|
||||||
|
|
||||||
|
This macro expands to a numeric constant that can be used to check the
|
||||||
|
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||||
|
of the 6502DTV CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_ISET_65SC02__</tt></tag>
|
||||||
|
|
||||||
|
This macro expands to a numeric constant that can be used to check the
|
||||||
|
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||||
|
of the 65SC02 CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_ISET_65C02__</tt></tag>
|
||||||
|
|
||||||
|
This macro expands to a numeric constant that can be used to check the
|
||||||
|
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||||
|
of the 65C02 CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_ISET_65816__</tt></tag>
|
||||||
|
|
||||||
|
This macro expands to a numeric constant that can be used to check the
|
||||||
|
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||||
|
of the 65816 CPU.
|
||||||
|
|
||||||
|
<tag><tt>__CPU_ISET_HUC6280__</tt></tag>
|
||||||
|
|
||||||
|
This macro expands to a numeric constant that can be used to check the
|
||||||
|
<tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set
|
||||||
|
of the HUC6280 CPU.
|
||||||
|
|
||||||
<tag><tt>__CX16__</tt></tag>
|
<tag><tt>__CX16__</tt></tag>
|
||||||
|
|
||||||
This macro is defined if the target is the Commander X16 (-t cx16).
|
This macro is defined if the target is the Commander X16 (-t cx16).
|
||||||
|
|||||||
@@ -109,6 +109,9 @@
|
|||||||
|
|
||||||
<descrip>
|
<descrip>
|
||||||
|
|
||||||
|
<tag><htmlurl url="agat.html" name="agat.html"></tag>
|
||||||
|
Topics specific to the Agat machines.
|
||||||
|
|
||||||
<tag><htmlurl url="apple2.html" name="apple2.html"></tag>
|
<tag><htmlurl url="apple2.html" name="apple2.html"></tag>
|
||||||
Topics specific to the Apple ][.
|
Topics specific to the Apple ][.
|
||||||
|
|
||||||
|
|||||||
@@ -165,8 +165,26 @@ The names in the parentheses denote the symbols to be used for static linking of
|
|||||||
|
|
||||||
<sect1>Graphics drivers<p>
|
<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>
|
<sect1>Extended memory drivers<p>
|
||||||
|
|
||||||
|
|||||||
76
include/agat.h
Normal file
76
include/agat.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#ifndef _AGAT_H
|
||||||
|
#define _AGAT_H
|
||||||
|
|
||||||
|
/* Check for errors */
|
||||||
|
#if !defined(__AGAT__)
|
||||||
|
# error This module may only be used when compiling for the Agat!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Color defines */
|
||||||
|
#define COLOR_BLACK 0x00
|
||||||
|
#define COLOR_RED 0x01
|
||||||
|
#define COLOR_GREEN 0x02
|
||||||
|
#define COLOR_YELLOW 0x03
|
||||||
|
#define COLOR_BLUE 0x04
|
||||||
|
#define COLOR_MAGENTA 0x05
|
||||||
|
#define COLOR_CYAN 0x06
|
||||||
|
#define COLOR_WHITE 0x07
|
||||||
|
|
||||||
|
/* Characters codes */
|
||||||
|
#define CH_CTRL_C 0x03
|
||||||
|
#define CH_ENTER 0x0D
|
||||||
|
#define CH_ESC 0x1B
|
||||||
|
#define CH_CURS_LEFT 0x08
|
||||||
|
#define CH_CURS_RIGHT 0x15
|
||||||
|
#define CH_CURS_UP 0x19
|
||||||
|
#define CH_CURS_DOWN 0x1A
|
||||||
|
#define CH_ESC 0x1B
|
||||||
|
#define CH_HLINE 0x1B
|
||||||
|
#define CH_VLINE 0x5C
|
||||||
|
#define CH_ULCORNER 0x10
|
||||||
|
#define CH_URCORNER 0x12
|
||||||
|
#define CH_LLCORNER 0x1D
|
||||||
|
#define CH_LRCORNER 0x1F
|
||||||
|
|
||||||
|
/* Masks for joy_read */
|
||||||
|
#define JOY_UP_MASK 0x10
|
||||||
|
#define JOY_DOWN_MASK 0x20
|
||||||
|
#define JOY_LEFT_MASK 0x04
|
||||||
|
#define JOY_RIGHT_MASK 0x08
|
||||||
|
#define JOY_BTN_1_MASK 0x40
|
||||||
|
#define JOY_BTN_2_MASK 0x80
|
||||||
|
|
||||||
|
/* Return codes for get_ostype */
|
||||||
|
#define AGAT_UNKNOWN 0x00
|
||||||
|
#define AGAT_7 0x10 /* Agat 7 */
|
||||||
|
#define AGAT_9 0x20 /* Agat 9 */
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Code */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned char get_ostype (void);
|
||||||
|
/* Get the machine type. Returns one of the AGAT_xxx codes. */
|
||||||
|
|
||||||
|
void rebootafterexit (void);
|
||||||
|
/* Reboot machine after program termination has completed. */
|
||||||
|
|
||||||
|
/* The following #defines will cause the matching functions calls in conio.h
|
||||||
|
** to be overlaid by macros with the same names, saving the function call
|
||||||
|
** overhead.
|
||||||
|
*/
|
||||||
|
#define _bgcolor(color) COLOR_BLACK
|
||||||
|
#define _bordercolor(color) COLOR_BLACK
|
||||||
|
|
||||||
|
/* End of agat.h */
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -40,6 +40,20 @@
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CPU__ & __CPU_ISET_65SC02__)
|
||||||
|
/* Always inline, three bytes is not more than a jsr */
|
||||||
|
|
||||||
|
#define ntohs(x) \
|
||||||
|
( \
|
||||||
|
__AX__=(x), \
|
||||||
|
asm("phx"), \
|
||||||
|
asm("tax"), \
|
||||||
|
asm("pla"), \
|
||||||
|
__AX__ \
|
||||||
|
)
|
||||||
|
#define htons(x) ntohs(x)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#if (__OPT_i__ < 200)
|
#if (__OPT_i__ < 200)
|
||||||
int __fastcall__ ntohs (int val);
|
int __fastcall__ ntohs (int val);
|
||||||
@@ -56,12 +70,12 @@ int __fastcall__ htons (int val);
|
|||||||
)
|
)
|
||||||
#define htons(x) ntohs(x)
|
#define htons(x) ntohs(x)
|
||||||
|
|
||||||
#endif
|
#endif /* __OPT_i__ < 200 */
|
||||||
|
|
||||||
|
#endif /* __CPU__ & __CPU_ISET_65SC02__ */
|
||||||
|
|
||||||
long __fastcall__ ntohl (long val);
|
long __fastcall__ ntohl (long val);
|
||||||
long __fastcall__ htonl (long val);
|
long __fastcall__ htonl (long val);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of arpa/inet.h */
|
/* End of arpa/inet.h */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -110,7 +110,23 @@
|
|||||||
#define COLOR_LIGHTBLUE (BCOLOR_LIGHTBLUE | CATTR_LUMA7)
|
#define COLOR_LIGHTBLUE (BCOLOR_LIGHTBLUE | CATTR_LUMA7)
|
||||||
#define COLOR_GRAY3 (BCOLOR_WHITE | CATTR_LUMA5)
|
#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 */
|
/* Masks for joy_read */
|
||||||
#define JOY_UP_MASK 0x01
|
#define JOY_UP_MASK 0x01
|
||||||
|
|||||||
@@ -57,8 +57,7 @@
|
|||||||
/* The addresses of the static drivers */
|
/* The addresses of the static drivers */
|
||||||
extern void plus4_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */
|
extern void plus4_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */
|
||||||
extern void plus4_stdser_ser[]; /* Referred to by ser_static_stddrv[] */
|
extern void plus4_stdser_ser[]; /* Referred to by ser_static_stddrv[] */
|
||||||
|
extern void ted_hi_tgi[];
|
||||||
|
|
||||||
|
|
||||||
/* End of plus4.h */
|
/* End of plus4.h */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -37,6 +37,8 @@
|
|||||||
# include <apple2enh.h>
|
# include <apple2enh.h>
|
||||||
#elif defined(__APPLE2__)
|
#elif defined(__APPLE2__)
|
||||||
# include <apple2.h>
|
# include <apple2.h>
|
||||||
|
#elif defined(__AGAT__)
|
||||||
|
# include <agat.h>
|
||||||
#elif defined(__ATARI__)
|
#elif defined(__ATARI__)
|
||||||
# include <atari.h>
|
# include <atari.h>
|
||||||
#elif defined(__ATARI2600__)
|
#elif defined(__ATARI2600__)
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ CBMS = c128 \
|
|||||||
GEOS = geos-apple \
|
GEOS = geos-apple \
|
||||||
geos-cbm
|
geos-cbm
|
||||||
|
|
||||||
TARGETS = apple2 \
|
TARGETS = agat \
|
||||||
|
apple2 \
|
||||||
apple2enh \
|
apple2enh \
|
||||||
atari \
|
atari \
|
||||||
atarixl \
|
atarixl \
|
||||||
|
|||||||
23
libsrc/agat/_scrsize.s
Normal file
23
libsrc/agat/_scrsize.s
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
;
|
||||||
|
; Ullrich von Bassewitz, 26.10.2000
|
||||||
|
; Konstantin Fedorov, 12.06.2025
|
||||||
|
;
|
||||||
|
; Screen size variables
|
||||||
|
;
|
||||||
|
|
||||||
|
.export screensize
|
||||||
|
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
screensize:
|
||||||
|
lda WNDWDTH
|
||||||
|
bit TATTR
|
||||||
|
bmi t64
|
||||||
|
lsr
|
||||||
|
t64:
|
||||||
|
tax
|
||||||
|
lda WNDBTM
|
||||||
|
sec
|
||||||
|
sbc WNDTOP
|
||||||
|
tay
|
||||||
|
rts
|
||||||
113
libsrc/agat/break.s
Normal file
113
libsrc/agat/break.s
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
;
|
||||||
|
; Ullrich von Bassewitz, 27.09.1998
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; void __fastcall__ set_brk (unsigned Addr);
|
||||||
|
; void reset_brk (void);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _set_brk, _reset_brk
|
||||||
|
.destructor _reset_brk
|
||||||
|
|
||||||
|
; Be sure to export the following variables absolute
|
||||||
|
.export _brk_a: abs, _brk_x: abs, _brk_y: abs
|
||||||
|
.export _brk_sr: abs, _brk_pc: abs
|
||||||
|
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
_brk_a = $45
|
||||||
|
_brk_x = $46
|
||||||
|
_brk_y = $47
|
||||||
|
_brk_sr = $48
|
||||||
|
_brk_sp = $49
|
||||||
|
_brk_pc = $3A
|
||||||
|
|
||||||
|
.bss
|
||||||
|
oldvec: .res 2 ; Old vector
|
||||||
|
|
||||||
|
|
||||||
|
.data
|
||||||
|
uservec: jmp $FFFF ; Patched at runtime
|
||||||
|
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
; Set the break vector
|
||||||
|
.proc _set_brk
|
||||||
|
|
||||||
|
sta uservec+1
|
||||||
|
stx uservec+2 ; Set the user vector
|
||||||
|
|
||||||
|
lda oldvec
|
||||||
|
ora oldvec+1 ; Did we save the vector already?
|
||||||
|
bne L1 ; Jump if we installed the handler already
|
||||||
|
|
||||||
|
lda BRKVec
|
||||||
|
sta oldvec
|
||||||
|
lda BRKVec+1
|
||||||
|
sta oldvec+1 ; Save the old vector
|
||||||
|
|
||||||
|
L1: lda #<brk_handler ; Set the break vector to our routine
|
||||||
|
ldx #>brk_handler
|
||||||
|
sta BRKVec
|
||||||
|
stx BRKVec+1
|
||||||
|
rts
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
; Reset the break vector
|
||||||
|
.proc _reset_brk
|
||||||
|
|
||||||
|
lda oldvec
|
||||||
|
ldx oldvec+1
|
||||||
|
beq @L9 ; Jump if vector not installed
|
||||||
|
sta BRKVec
|
||||||
|
stx BRKVec+1
|
||||||
|
lda #$00
|
||||||
|
sta oldvec ; Clear the old vector
|
||||||
|
stx oldvec+1
|
||||||
|
@L9: rts
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; Break handler, called if a break occurs
|
||||||
|
|
||||||
|
.proc brk_handler
|
||||||
|
|
||||||
|
sec
|
||||||
|
lda _brk_pc
|
||||||
|
sbc #$02 ; Point to start of brk
|
||||||
|
sta _brk_pc
|
||||||
|
lda _brk_pc+1
|
||||||
|
sbc #$00
|
||||||
|
sta _brk_pc+1
|
||||||
|
|
||||||
|
clc
|
||||||
|
lda _brk_sp
|
||||||
|
adc #$04 ; Adjust stack pointer
|
||||||
|
sta _brk_sp
|
||||||
|
|
||||||
|
lda _brk_sr ; Clear brk
|
||||||
|
and #$EF
|
||||||
|
sta _brk_sr
|
||||||
|
|
||||||
|
jsr uservec ; Call the user's routine
|
||||||
|
|
||||||
|
lda _brk_pc+1
|
||||||
|
pha
|
||||||
|
lda _brk_pc
|
||||||
|
pha
|
||||||
|
lda _brk_sr
|
||||||
|
pha
|
||||||
|
|
||||||
|
ldx _brk_x
|
||||||
|
ldy _brk_y
|
||||||
|
lda _brk_a
|
||||||
|
|
||||||
|
rti ; Jump back...
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
||||||
18
libsrc/agat/cclear.s
Normal file
18
libsrc/agat/cclear.s
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
;
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; void __fastcall__ cclear (unsigned char length);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _cclear
|
||||||
|
.import COUT
|
||||||
|
.include "zeropage.inc"
|
||||||
|
|
||||||
|
_cclear:
|
||||||
|
sta ptr1
|
||||||
|
lda #$A0
|
||||||
|
next:
|
||||||
|
jsr COUT
|
||||||
|
dec ptr1
|
||||||
|
bne next
|
||||||
|
rts
|
||||||
23
libsrc/agat/cgetc.s
Normal file
23
libsrc/agat/cgetc.s
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
;
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; char cgetc (void);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _cgetc
|
||||||
|
.import cursor
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
_cgetc:
|
||||||
|
lda #$DF ; _
|
||||||
|
bit cursor
|
||||||
|
bne hascur
|
||||||
|
lda #$00
|
||||||
|
hascur:
|
||||||
|
sta CURSOR
|
||||||
|
jsr j1
|
||||||
|
cmp #$A0
|
||||||
|
bpl :+
|
||||||
|
and #$7F
|
||||||
|
: rts
|
||||||
|
j1: jmp (VCIN)
|
||||||
33
libsrc/agat/chline.s
Normal file
33
libsrc/agat/chline.s
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
;
|
||||||
|
; Ullrich von Bassewitz, 08.08.1998
|
||||||
|
; Colin Leroy-Mira, 26.05.2025
|
||||||
|
; Konstantin Fedorov, 12.06.2025
|
||||||
|
;
|
||||||
|
; void chlinexy (unsigned char x, unsigned char y, unsigned char length);
|
||||||
|
; void chline (unsigned char length);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _chlinexy, _chline, chlinedirect
|
||||||
|
.import gotoxy, putchar
|
||||||
|
|
||||||
|
.include "zeropage.inc"
|
||||||
|
|
||||||
|
_chlinexy:
|
||||||
|
pha ; Save the length
|
||||||
|
jsr gotoxy ; Call this one, will pop params
|
||||||
|
pla ; Restore the length and run into _chline
|
||||||
|
|
||||||
|
_chline:
|
||||||
|
ldx #$1B ; horizontal line character
|
||||||
|
|
||||||
|
chlinedirect:
|
||||||
|
stx tmp1
|
||||||
|
cmp #$00 ; Is the length zero?
|
||||||
|
beq done ; Jump if done
|
||||||
|
sta tmp2
|
||||||
|
: lda tmp1 ; Screen code
|
||||||
|
jsr putchar ; Direct output
|
||||||
|
dec tmp2
|
||||||
|
bne :-
|
||||||
|
done: rts
|
||||||
|
|
||||||
10
libsrc/agat/clrscr.s
Normal file
10
libsrc/agat/clrscr.s
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
;
|
||||||
|
; Kevin Ruland
|
||||||
|
;
|
||||||
|
; void clrscr (void);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _clrscr
|
||||||
|
.import HOME
|
||||||
|
|
||||||
|
_clrscr := HOME
|
||||||
20
libsrc/agat/color.s
Normal file
20
libsrc/agat/color.s
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
;
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; unsigned char __fastcall__ textcolor (unsigned char color);
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
.export _textcolor
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
|
||||||
|
_textcolor:
|
||||||
|
ldx TATTR
|
||||||
|
eor TATTR
|
||||||
|
and #$07
|
||||||
|
eor TATTR
|
||||||
|
sta TATTR
|
||||||
|
txa
|
||||||
|
and #$0F
|
||||||
|
rts
|
||||||
14
libsrc/agat/cout.s
Normal file
14
libsrc/agat/cout.s
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
;
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; COUT routine
|
||||||
|
;
|
||||||
|
|
||||||
|
.export COUT
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
COUT:
|
||||||
|
cmp #$10
|
||||||
|
bpl out
|
||||||
|
ora #$80
|
||||||
|
out: jmp (VCOUT)
|
||||||
60
libsrc/agat/cputc.s
Normal file
60
libsrc/agat/cputc.s
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
;
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
; Konstantin Fedorov, 12.06.2025
|
||||||
|
;
|
||||||
|
; void __fastcall__ cputcxy (unsigned char x, unsigned char y, char c);
|
||||||
|
; void __fastcall__ cputc (char c);
|
||||||
|
;
|
||||||
|
|
||||||
|
.import COUT
|
||||||
|
.export _cputcxy, _cputc, newline, putchar,putchardirect
|
||||||
|
.import gotoxy, VTABZ
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
_cputcxy:
|
||||||
|
pha
|
||||||
|
jsr gotoxy
|
||||||
|
pla
|
||||||
|
_cputc:
|
||||||
|
cmp #$0D ; Test for \r = carriage return
|
||||||
|
bne notleft
|
||||||
|
ldy #$00
|
||||||
|
sty CH
|
||||||
|
rts
|
||||||
|
notleft:
|
||||||
|
cmp #$0A ; Test for \n = line feed
|
||||||
|
beq newline
|
||||||
|
|
||||||
|
putchar:
|
||||||
|
ldy CH
|
||||||
|
sta (BASL),Y
|
||||||
|
iny
|
||||||
|
lda TATTR
|
||||||
|
bmi wch ; Skip if t64
|
||||||
|
sta (BASL),Y
|
||||||
|
iny
|
||||||
|
wch:
|
||||||
|
sty CH
|
||||||
|
cpy WNDWDTH
|
||||||
|
bcc noend
|
||||||
|
ldy #$00
|
||||||
|
sty CH
|
||||||
|
newline:
|
||||||
|
inc CV
|
||||||
|
lda CV
|
||||||
|
cmp WNDBTM
|
||||||
|
bcc :+
|
||||||
|
lda WNDTOP
|
||||||
|
sta CV
|
||||||
|
: jmp VTABZ
|
||||||
|
noend:
|
||||||
|
rts
|
||||||
|
|
||||||
|
putchardirect:
|
||||||
|
ldy CH
|
||||||
|
sta (BASL),Y
|
||||||
|
lda TATTR
|
||||||
|
bmi :+
|
||||||
|
iny
|
||||||
|
sta (BASL),Y
|
||||||
|
: rts
|
||||||
78
libsrc/agat/crt0.s
Normal file
78
libsrc/agat/crt0.s
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
;
|
||||||
|
; Startup code for cc65 (Agat version)
|
||||||
|
;
|
||||||
|
|
||||||
|
.export __STARTUP__ : absolute = 1 ; Mark as startup
|
||||||
|
.export _exit
|
||||||
|
|
||||||
|
.import initlib, donelib
|
||||||
|
.import zerobss, callmain
|
||||||
|
.import __ONCE_LOAD__, __ONCE_SIZE__ ; Linker generated
|
||||||
|
|
||||||
|
.include "zeropage.inc"
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.segment "STARTUP"
|
||||||
|
jsr init
|
||||||
|
jsr zerobss
|
||||||
|
jsr callmain
|
||||||
|
_exit:
|
||||||
|
ldx #<exit
|
||||||
|
lda #>exit
|
||||||
|
jsr reset
|
||||||
|
jsr donelib
|
||||||
|
exit:
|
||||||
|
ldx #$02
|
||||||
|
: lda rvsave,x
|
||||||
|
sta SOFTEV,x
|
||||||
|
dex
|
||||||
|
bpl :-
|
||||||
|
ldx #zpspace-1
|
||||||
|
: lda zpsave,x
|
||||||
|
sta sp,x
|
||||||
|
dex
|
||||||
|
bpl :-
|
||||||
|
ldx #$FF
|
||||||
|
txs
|
||||||
|
jmp DOSWARM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.segment "ONCE"
|
||||||
|
|
||||||
|
init:
|
||||||
|
ldx #zpspace-1
|
||||||
|
: lda sp,x
|
||||||
|
sta zpsave,x
|
||||||
|
dex
|
||||||
|
bpl :-
|
||||||
|
|
||||||
|
ldx #$02
|
||||||
|
: lda SOFTEV,x
|
||||||
|
sta rvsave,x
|
||||||
|
dex
|
||||||
|
bpl :-
|
||||||
|
|
||||||
|
lda HIMEM
|
||||||
|
ldx HIMEM+1
|
||||||
|
sta sp
|
||||||
|
stx sp+1
|
||||||
|
ldx #<_exit
|
||||||
|
lda #>_exit
|
||||||
|
jsr reset
|
||||||
|
jmp initlib
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
reset:
|
||||||
|
stx SOFTEV
|
||||||
|
sta SOFTEV+1
|
||||||
|
eor #$A5
|
||||||
|
sta PWREDUP
|
||||||
|
rts
|
||||||
|
|
||||||
|
.segment "INIT"
|
||||||
|
zpsave: .res zpspace
|
||||||
|
rvsave: .res 3
|
||||||
29
libsrc/agat/cvline.s
Normal file
29
libsrc/agat/cvline.s
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
;
|
||||||
|
; Ullrich von Bassewitz, 08.08.1998
|
||||||
|
; Colin Leroy-Mira, 26.05.2025
|
||||||
|
; Konstantin Fedorov, 12.06.2025
|
||||||
|
;
|
||||||
|
; void cvlinexy (unsigned char x, unsigned char y, unsigned char length);
|
||||||
|
; void cvline (unsigned char length);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _cvlinexy, _cvline
|
||||||
|
.import gotoxy, putchardirect, newline
|
||||||
|
|
||||||
|
.include "zeropage.inc"
|
||||||
|
|
||||||
|
_cvlinexy:
|
||||||
|
pha ; Save the length
|
||||||
|
jsr gotoxy ; Call this one, will pop params
|
||||||
|
pla ; Restore the length and run into _cvline
|
||||||
|
|
||||||
|
_cvline:
|
||||||
|
cmp #$00 ; Is the length zero?
|
||||||
|
beq done ; Jump if done
|
||||||
|
sta tmp2
|
||||||
|
: lda #$5C ; vertical line character
|
||||||
|
jsr putchardirect ; Write, no cursor advance
|
||||||
|
jsr newline ; Advance cursor to next line
|
||||||
|
dec tmp2
|
||||||
|
bne :-
|
||||||
|
done: rts
|
||||||
43
libsrc/agat/exehdr.s
Normal file
43
libsrc/agat/exehdr.s
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
;
|
||||||
|
; Oliver Schmidt, 2012-06-10
|
||||||
|
;
|
||||||
|
; This module supplies an AppleSingle version 2 file header + entry with
|
||||||
|
; ID 11 according to https://tools.ietf.org/rfc/rfc1740.txt Appendix A.
|
||||||
|
;
|
||||||
|
; Agat target uses this header only for compatibility with Apple Commander
|
||||||
|
; because Agat's 140K disk filesystem is identical to Apple II DOS 3.3 and
|
||||||
|
; "ac.jar -as" option can be used to import binaries into disk images.
|
||||||
|
|
||||||
|
.export __EXEHDR__ : absolute = 1 ; Linker referenced
|
||||||
|
.import __FILETYPE__ ; Linker generated
|
||||||
|
.import __MAIN_START__, __MAIN_LAST__ ; Linker generated
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
; Data Fork
|
||||||
|
ID01_LENGTH = __MAIN_LAST__ - __MAIN_START__
|
||||||
|
ID01_OFFSET = ID01 - START
|
||||||
|
|
||||||
|
; ProDOS File Info
|
||||||
|
ID11_LENGTH = ID01 - ID11
|
||||||
|
ID11_OFFSET = ID11 - START
|
||||||
|
|
||||||
|
; ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.segment "EXEHDR"
|
||||||
|
|
||||||
|
START: .byte $00, $05, $16, $00 ; Magic number
|
||||||
|
.byte $00, $02, $00, $00 ; Version number
|
||||||
|
.res 16 ; Filler
|
||||||
|
.byte 0, 2 ; Number of entries
|
||||||
|
.byte 0, 0, 0, 1 ; Entry ID 1 - Data Fork
|
||||||
|
.byte 0, 0, >ID01_OFFSET, <ID01_OFFSET ; Offset
|
||||||
|
.byte 0, 0, >ID01_LENGTH, <ID01_LENGTH ; Length
|
||||||
|
.byte 0, 0, 0, 11 ; Entry ID 11 - ProDOS File Info
|
||||||
|
.byte 0, 0, >ID11_OFFSET, <ID11_OFFSET ; Offset
|
||||||
|
.byte 0, 0, >ID11_LENGTH, <ID11_LENGTH ; Length
|
||||||
|
ID11: .byte 0, %11000011 ; Access - Destroy, Rename, Write, Read
|
||||||
|
.byte >__FILETYPE__, <__FILETYPE__ ; File Type
|
||||||
|
.byte 0, 0 ; Auxiliary Type high
|
||||||
|
.byte >__MAIN_START__, <__MAIN_START__ ; Auxiliary Type low
|
||||||
|
ID01:
|
||||||
28
libsrc/agat/gotoxy.s
Normal file
28
libsrc/agat/gotoxy.s
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
;
|
||||||
|
; Ullrich von Bassewitz, 06.08.1998
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; void __fastcall__ gotoxy (unsigned char x, unsigned char y);
|
||||||
|
; void __fastcall__ gotox (unsigned char x);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export gotoxy, _gotoxy, _gotox
|
||||||
|
.import popa, VTABZ
|
||||||
|
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
gotoxy:
|
||||||
|
jsr popa ; Get Y
|
||||||
|
_gotoxy:
|
||||||
|
clc
|
||||||
|
adc WNDTOP
|
||||||
|
sta CV ; Store Y
|
||||||
|
jsr VTABZ
|
||||||
|
jsr popa ; Get X
|
||||||
|
_gotox:
|
||||||
|
bit TATTR
|
||||||
|
bmi t64
|
||||||
|
asl
|
||||||
|
t64:
|
||||||
|
sta CH ; Store X
|
||||||
|
rts
|
||||||
16
libsrc/agat/gotoy.s
Normal file
16
libsrc/agat/gotoy.s
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
;
|
||||||
|
; Ullrich von Bassewitz, 06.08.1998
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; void __fastcall__ gotoy (unsigned char y);
|
||||||
|
;
|
||||||
|
|
||||||
|
.import VTABZ
|
||||||
|
.export _gotoy
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
_gotoy:
|
||||||
|
clc
|
||||||
|
adc WNDTOP
|
||||||
|
sta CV
|
||||||
|
jmp VTABZ
|
||||||
15
libsrc/agat/home.s
Normal file
15
libsrc/agat/home.s
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
;
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; HOME routine
|
||||||
|
;
|
||||||
|
|
||||||
|
.export HOME
|
||||||
|
.import COUT
|
||||||
|
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
HOME:
|
||||||
|
lda #$8C
|
||||||
|
jmp COUT
|
||||||
|
rts
|
||||||
19
libsrc/agat/kbhit.s
Normal file
19
libsrc/agat/kbhit.s
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
;
|
||||||
|
; Kevin Ruland
|
||||||
|
; Ullrich von Bassewitz, 2005-03-25
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; unsigned char kbhit (void);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _kbhit
|
||||||
|
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
_kbhit:
|
||||||
|
lda KBD ; Reading KBD checks for keypress
|
||||||
|
rol ; if high bit is set, key was pressed
|
||||||
|
lda #$00
|
||||||
|
tax
|
||||||
|
rol
|
||||||
|
rts
|
||||||
18
libsrc/agat/randomize.s
Normal file
18
libsrc/agat/randomize.s
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
;
|
||||||
|
; Ullrich von Bassewitz, 07.11.2002
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; void _randomize (void);
|
||||||
|
; /* Initialize the random number generator */
|
||||||
|
;
|
||||||
|
|
||||||
|
.export __randomize
|
||||||
|
.import _srand
|
||||||
|
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
__randomize:
|
||||||
|
ldx RNDH ; Use random value supplied by ROM
|
||||||
|
lda RNDL
|
||||||
|
jmp _srand ; Initialize generator
|
||||||
|
|
||||||
38
libsrc/agat/revers.s
Normal file
38
libsrc/agat/revers.s
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
;
|
||||||
|
; Ullrich von Bassewitz, 2005-03-28
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; unsigned char __fastcall__ revers (unsigned char onoff)
|
||||||
|
; unsigned char __fastcall__ flash (unsigned char onoff)
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _revers, _flash
|
||||||
|
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
_revers:
|
||||||
|
tax
|
||||||
|
beq noinv
|
||||||
|
lda TATTR
|
||||||
|
and #$D7
|
||||||
|
sta TATTR
|
||||||
|
rts
|
||||||
|
noinv:
|
||||||
|
lda TATTR
|
||||||
|
ora #$20
|
||||||
|
sta TATTR
|
||||||
|
rts
|
||||||
|
|
||||||
|
_flash:
|
||||||
|
tax
|
||||||
|
beq noflash
|
||||||
|
lda TATTR
|
||||||
|
and #$DF
|
||||||
|
ora #$08
|
||||||
|
sta TATTR
|
||||||
|
rts
|
||||||
|
noflash:
|
||||||
|
lda TATTR
|
||||||
|
ora #$20
|
||||||
|
sta TATTR
|
||||||
|
rts
|
||||||
24
libsrc/agat/vtabz.s
Normal file
24
libsrc/agat/vtabz.s
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
;
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; VTABZ routine
|
||||||
|
;
|
||||||
|
|
||||||
|
.export VTABZ
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
VTABZ:
|
||||||
|
lda CV
|
||||||
|
ror
|
||||||
|
ror
|
||||||
|
ror
|
||||||
|
and #$C0
|
||||||
|
sta BASL
|
||||||
|
lda CV
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
eor BASH
|
||||||
|
and #$07
|
||||||
|
eor BASH
|
||||||
|
sta BASH
|
||||||
|
rts
|
||||||
19
libsrc/agat/wherex.s
Normal file
19
libsrc/agat/wherex.s
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
;
|
||||||
|
; Kevin Ruland
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; unsigned char wherex (void);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _wherex
|
||||||
|
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
_wherex:
|
||||||
|
lda CH
|
||||||
|
bit TATTR
|
||||||
|
bmi t64
|
||||||
|
lsr
|
||||||
|
t64:
|
||||||
|
ldx #$00
|
||||||
|
rts
|
||||||
17
libsrc/agat/wherey.s
Normal file
17
libsrc/agat/wherey.s
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
;
|
||||||
|
; Kevin Ruland
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; unsigned char wherey (void);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _wherey
|
||||||
|
|
||||||
|
.include "agat.inc"
|
||||||
|
|
||||||
|
_wherey:
|
||||||
|
lda CV
|
||||||
|
sec
|
||||||
|
sbc WNDTOP
|
||||||
|
ldx #$00
|
||||||
|
rts
|
||||||
50
libsrc/agat/write.s
Normal file
50
libsrc/agat/write.s
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
;
|
||||||
|
; Oleg A. Odintsov, Moscow, 2024
|
||||||
|
;
|
||||||
|
; int __fastcall__ write (int fd, const void* buf, unsigned count);
|
||||||
|
;
|
||||||
|
|
||||||
|
.export _write
|
||||||
|
.import popax, popptr1
|
||||||
|
.import COUT
|
||||||
|
|
||||||
|
.include "zeropage.inc"
|
||||||
|
|
||||||
|
_write:
|
||||||
|
sta ptr2
|
||||||
|
stx ptr2+1
|
||||||
|
jsr popptr1
|
||||||
|
jsr popax
|
||||||
|
|
||||||
|
; Check for zero count
|
||||||
|
ora ptr2
|
||||||
|
beq done
|
||||||
|
|
||||||
|
; Get char from buf
|
||||||
|
next: ldy #$00
|
||||||
|
lda (ptr1),y
|
||||||
|
|
||||||
|
; Replace '\n' with '\r'
|
||||||
|
cmp #$0A
|
||||||
|
bne output
|
||||||
|
lda #$8D
|
||||||
|
|
||||||
|
; Set hi bit and write to device
|
||||||
|
output:
|
||||||
|
jsr COUT ; Preserves X and Y
|
||||||
|
|
||||||
|
; Increment pointer
|
||||||
|
inc ptr1
|
||||||
|
bne :+
|
||||||
|
inc ptr1+1
|
||||||
|
|
||||||
|
; Decrement count
|
||||||
|
: dec ptr2
|
||||||
|
bne next
|
||||||
|
dec ptr2+1
|
||||||
|
bpl next
|
||||||
|
|
||||||
|
; Return success
|
||||||
|
done: lda #$00
|
||||||
|
rts
|
||||||
|
|
||||||
@@ -58,6 +58,7 @@ init: ldx #zpspace-1
|
|||||||
; Check for ProDOS.
|
; Check for ProDOS.
|
||||||
ldy $BF00 ; MLI call entry point
|
ldy $BF00 ; MLI call entry point
|
||||||
cpy #$4C ; Is MLI present? (JMP opcode)
|
cpy #$4C ; Is MLI present? (JMP opcode)
|
||||||
|
php ; Remember whether we're running ProDOS
|
||||||
bne basic
|
bne basic
|
||||||
|
|
||||||
; Check the ProDOS system bit map.
|
; Check the ProDOS system bit map.
|
||||||
@@ -99,7 +100,20 @@ basic: lda HIMEM
|
|||||||
bit $C081
|
bit $C081
|
||||||
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.
|
; Aka __LC_LOAD__ iff segment LC exists.
|
||||||
lda #<(__ONCE_LOAD__ + __ONCE_SIZE__)
|
lda #<(__ONCE_LOAD__ + __ONCE_SIZE__)
|
||||||
ldy #>(__ONCE_LOAD__ + __ONCE_SIZE__)
|
ldy #>(__ONCE_LOAD__ + __ONCE_SIZE__)
|
||||||
@@ -144,6 +158,14 @@ quit: jsr $BF00 ; MLI call entry point
|
|||||||
.byte $65 ; Quit
|
.byte $65 ; Quit
|
||||||
.word q_param
|
.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
|
.rodata
|
||||||
|
|||||||
@@ -18,11 +18,16 @@ _cgetc: lda KEY_COUNT ; Get number of characters
|
|||||||
ora FKEY_COUNT ; Or with number of function key chars
|
ora FKEY_COUNT ; Or with number of function key chars
|
||||||
bne L2 ; Jump if there are already chars waiting
|
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
|
; Switch on the cursor if needed
|
||||||
|
|
||||||
ldy CURS_X
|
ldy CURS_X
|
||||||
lda (CRAM_PTR),y ; Get current char
|
lda (CRAM_PTR),y ; Get current char
|
||||||
pha ; And save it
|
pha ; And save it
|
||||||
|
|
||||||
lda CHARCOLOR
|
lda CHARCOLOR
|
||||||
sta (CRAM_PTR),y
|
sta (CRAM_PTR),y
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,7 @@
|
|||||||
.import callirq_y, initlib, donelib
|
.import callirq_y, initlib, donelib
|
||||||
.import callmain, zerobss
|
.import callmain, zerobss
|
||||||
.import __INTERRUPTOR_COUNT__
|
.import __INTERRUPTOR_COUNT__
|
||||||
.import __MAIN_START__, __MAIN_SIZE__ ; Linker generated
|
.import __HIMEM__ ; Linker generated
|
||||||
.import __STACKSIZE__ ; Linker generated
|
|
||||||
.importzp ST
|
.importzp ST
|
||||||
|
|
||||||
.include "zeropage.inc"
|
.include "zeropage.inc"
|
||||||
@@ -52,19 +51,28 @@ L1: lda sp,x
|
|||||||
tsx
|
tsx
|
||||||
stx spsave ; Save system stk ptr
|
stx spsave ; Save system stk ptr
|
||||||
|
|
||||||
lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
|
lda #<__HIMEM__
|
||||||
ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
|
ldx #>__HIMEM__
|
||||||
sta sp
|
sta sp
|
||||||
stx sp+1
|
stx sp+1
|
||||||
|
|
||||||
; Set up the IRQ vector in the banked RAM; and, switch off the ROM.
|
; Set up the IRQ vector in the banked RAM; and, switch off the ROM.
|
||||||
|
|
||||||
ldx #<IRQ
|
lda #<IRQ
|
||||||
ldy #>IRQ
|
ldx #>IRQ
|
||||||
sei ; No ints, handler not yet in place
|
sei ; No ints, handler not yet in place
|
||||||
sta ENABLE_RAM
|
sta ENABLE_RAM
|
||||||
stx $FFFE ; Install interrupt handler
|
sta $FFFE ; Install interrupt handler
|
||||||
sty $FFFF
|
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
|
cli ; Allow interrupts
|
||||||
|
|
||||||
; Clear the BSS data.
|
; Clear the BSS data.
|
||||||
@@ -95,6 +103,13 @@ _exit: pha ; Save the return code
|
|||||||
lda #0
|
lda #0
|
||||||
sta irqcount ; Disable custom IRQ handlers
|
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.
|
; Copy back the zero-page stuff.
|
||||||
|
|
||||||
ldx #zpspace-1
|
ldx #zpspace-1
|
||||||
@@ -122,9 +137,13 @@ L2: lda zpsave,x
|
|||||||
; IRQ handler. The handler in the ROM enables the Kernal, and jumps to
|
; 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
|
; $CE00, where the ROM code checks for a BRK or IRQ, and branches via the
|
||||||
; indirect vectors at $314/$316.
|
; 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
|
; When RAM is banked in, we skip the whole part of the ROM handler, and jump to
|
||||||
; own interrupt handlers if we have any; so, they need not use $314.
|
; 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"
|
.segment "LOWCODE"
|
||||||
|
|
||||||
@@ -139,15 +158,6 @@ IRQ: cld ; Just to be sure
|
|||||||
and #$10 ; Test for BRK bit
|
and #$10 ; Test for BRK bit
|
||||||
bne dobreak
|
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
|
; 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,
|
; on the stack, so that we get control of the CPU after the ROM handler,
|
||||||
; and can switch back to RAM.
|
; and can switch back to RAM.
|
||||||
@@ -161,7 +171,7 @@ IRQ: cld ; Just to be sure
|
|||||||
pha ; Push faked X register
|
pha ; Push faked X register
|
||||||
pha ; Push faked Y register
|
pha ; Push faked Y register
|
||||||
sta ENABLE_ROM ; Switch to ROM
|
sta ENABLE_ROM ; Switch to ROM
|
||||||
jmp (IRQVec) ; Jump indirect to Kernal IRQ handler
|
jmp (IRQVec) ; Jump indirect to IRQ stub
|
||||||
|
|
||||||
irq_ret:
|
irq_ret:
|
||||||
sta ENABLE_RAM ; Switch back to RAM
|
sta ENABLE_RAM ; Switch back to RAM
|
||||||
@@ -183,6 +193,22 @@ nohandler:
|
|||||||
sta ENABLE_ROM
|
sta ENABLE_ROM
|
||||||
jmp (BRKVec) ; Jump indirect to the break vector
|
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
|
; Data
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
; Oliver Schmidt, 2013-05-31
|
; Oliver Schmidt, 2013-05-31
|
||||||
;
|
;
|
||||||
|
|
||||||
.export joy_libref, ser_libref
|
.export joy_libref, ser_libref, tgi_libref
|
||||||
.import _exit
|
.import _exit
|
||||||
|
|
||||||
joy_libref := _exit
|
joy_libref := _exit
|
||||||
ser_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_CMD := ACIA+2 ; Command register
|
||||||
ACIA_CTRL := ACIA+3 ; Control 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
|
; Global variables
|
||||||
;
|
;
|
||||||
|
|
||||||
.bss
|
.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
|
SendHead: .res 1 ; Head of send buffer
|
||||||
SendTail: .res 1 ; Tail of send buffer
|
SendTail: .res 1 ; Tail of send buffer
|
||||||
SendFreeCnt: .res 1 ; Number of bytes in 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
|
; 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 $FF ; SER_BAUD_45_5
|
||||||
.byte $01 ; SER_BAUD_50
|
.byte $01 ; SER_BAUD_50
|
||||||
.byte $02 ; SER_BAUD_75
|
.byte $02 ; SER_BAUD_75
|
||||||
@@ -354,26 +354,27 @@ SER_IOCTL:
|
|||||||
;
|
;
|
||||||
|
|
||||||
SER_IRQ:
|
SER_IRQ:
|
||||||
lda ACIA_STATUS ; Check ACIA status for receive interrupt
|
lda ACIA_STATUS ; (4) Check for byte received
|
||||||
and #$08
|
and #$08 ; (2)
|
||||||
beq @L9 ; Jump if no ACIA interrupt (carry still clear)
|
beq @L9 ; (2*)
|
||||||
lda ACIA_DATA ; Get byte from ACIA
|
|
||||||
ldx RecvFreeCnt ; Check if we have free space left
|
lda ACIA_DATA ; (4) Get byte and put into receive buffer
|
||||||
beq @L1 ; Jump if no space in receive buffer
|
ldy RecvTail ; (4)
|
||||||
ldy RecvTail ; Load buffer pointer
|
ldx RecvFreeCnt ; (4)
|
||||||
sta RecvBuf,y ; Store received byte in buffer
|
beq @L3 ; (2*) Jump if no space in receive buffer
|
||||||
inc RecvTail ; Increment buffer pointer
|
sta RecvBuf,y ; (5)
|
||||||
dec RecvFreeCnt ; Decrement free space counter
|
inc RecvTail ; (6)
|
||||||
cpx #33 ; Check for buffer space low
|
dec RecvFreeCnt ; (6)
|
||||||
bcc @L1 ; Assert flow control if buffer space low
|
cpx #33 ; (2) Check for buffer space low
|
||||||
|
bcc @L2 ; (2*)
|
||||||
rts ; Return with carry set (interrupt handled)
|
rts ; Return with carry set (interrupt handled)
|
||||||
|
|
||||||
; Assert flow control if buffer space too low
|
; Assert flow control if buffer space too low
|
||||||
|
|
||||||
@L1: lda RtsOff
|
@L2: lda RtsOff ; (3)
|
||||||
sta ACIA_CMD
|
sta ACIA_CMD ; (4)
|
||||||
sta Stopped
|
sta Stopped ; (3)
|
||||||
sec ; Interrupt handled
|
@L3: sec ; Interrupt handled
|
||||||
@L9: rts
|
@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"
|
||||||
@@ -109,6 +109,7 @@ DISK_apple2 = samples.dsk
|
|||||||
DISK_apple2enh = samples.dsk
|
DISK_apple2enh = samples.dsk
|
||||||
DISK_atari = samples.atr
|
DISK_atari = samples.atr
|
||||||
DISK_atarixl = samples.atr
|
DISK_atarixl = samples.atr
|
||||||
|
DISK_plus4 = samples.d64
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# System-dependent settings
|
# System-dependent settings
|
||||||
@@ -156,6 +157,8 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000
|
|||||||
.o:
|
.o:
|
||||||
ifeq ($(SYS),vic20)
|
ifeq ($(SYS),vic20)
|
||||||
$(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib
|
$(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
|
else
|
||||||
$(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib
|
$(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib
|
||||||
endif
|
endif
|
||||||
@@ -168,6 +171,11 @@ DIRLIST = tutorial geos atari2600 atari5200 apple2 gamate lynx supervision sym1
|
|||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# Lists of executables
|
# Lists of executables
|
||||||
|
EXELIST_agat = \
|
||||||
|
ascii \
|
||||||
|
checkversion \
|
||||||
|
hello \
|
||||||
|
sieve
|
||||||
|
|
||||||
EXELIST_apple2 = \
|
EXELIST_apple2 = \
|
||||||
ascii \
|
ascii \
|
||||||
@@ -331,9 +339,11 @@ EXELIST_plus4 = \
|
|||||||
enumdevdir \
|
enumdevdir \
|
||||||
gunzip65 \
|
gunzip65 \
|
||||||
hello \
|
hello \
|
||||||
|
mandelbrot \
|
||||||
terminal \
|
terminal \
|
||||||
tinyshell \
|
tinyshell \
|
||||||
sieve
|
sieve \
|
||||||
|
tgidemo
|
||||||
|
|
||||||
EXELIST_sim6502 = \
|
EXELIST_sim6502 = \
|
||||||
checkversion \
|
checkversion \
|
||||||
@@ -400,6 +410,7 @@ all:
|
|||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# List of every supported platform
|
# List of every supported platform
|
||||||
TARGETS := \
|
TARGETS := \
|
||||||
|
agat \
|
||||||
apple2 \
|
apple2 \
|
||||||
apple2enh \
|
apple2enh \
|
||||||
atari \
|
atari \
|
||||||
@@ -455,7 +466,15 @@ multdemo: multidemo.o
|
|||||||
ovrldemo: overlaydemo.o
|
ovrldemo: overlaydemo.o
|
||||||
$(LD) $(LDFLAGS) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(SYS).lib
|
$(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.
|
# TGI programs on the VIC-20 need a special ld65 configuration file.
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define DYN_BOX_DRAW
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define DYN_BOX_DRAW
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Workaround missing clock stuff */
|
/* Workaround missing clock stuff */
|
||||||
#ifdef __APPLE2__
|
#if defined(__APPLE2__) || defined(__AGAT__)
|
||||||
# define clock() 0
|
# define clock() 0
|
||||||
# define CLOCKS_PER_SEC 1
|
# define CLOCKS_PER_SEC 1
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -12,8 +12,10 @@
|
|||||||
# define DYN_DRV 1
|
# define DYN_DRV 1
|
||||||
#endif
|
#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
|
#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 void DoCircles (void)
|
||||||
{
|
{
|
||||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLUE };
|
|
||||||
unsigned char I;
|
unsigned char I;
|
||||||
unsigned char Color = COLOR_BACK;
|
unsigned char Color = COLOR_BACK;
|
||||||
const unsigned X = MaxX / 2;
|
const unsigned X = MaxX / 2;
|
||||||
const unsigned Y = MaxY / 2;
|
const unsigned Y = MaxY / 2;
|
||||||
const unsigned Limit = (X < Y) ? Y : X;
|
const unsigned Limit = (X < Y) ? Y : X;
|
||||||
|
|
||||||
tgi_setpalette (Palette);
|
|
||||||
tgi_setcolor (COLOR_FORE);
|
tgi_setcolor (COLOR_FORE);
|
||||||
tgi_clear ();
|
tgi_clear ();
|
||||||
tgi_line (0, 0, MaxX, MaxY);
|
tgi_line (0, 0, MaxX, MaxY);
|
||||||
@@ -87,7 +111,9 @@ static void DoCircles (void)
|
|||||||
tgi_ellipse (X, Y, I, tgi_imulround (I, AspectRatio));
|
tgi_ellipse (X, Y, I, tgi_imulround (I, AspectRatio));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while (kbhit ()) {
|
||||||
|
cgetc ();
|
||||||
|
}
|
||||||
cgetc ();
|
cgetc ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,11 +121,9 @@ static void DoCircles (void)
|
|||||||
|
|
||||||
static void DoCheckerboard (void)
|
static void DoCheckerboard (void)
|
||||||
{
|
{
|
||||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK };
|
|
||||||
unsigned X, Y;
|
unsigned X, Y;
|
||||||
unsigned char Color = COLOR_BACK;
|
unsigned char Color = COLOR_BACK;
|
||||||
|
|
||||||
tgi_setpalette (Palette);
|
|
||||||
tgi_clear ();
|
tgi_clear ();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -123,13 +147,11 @@ static void DoCheckerboard (void)
|
|||||||
|
|
||||||
static void DoDiagram (void)
|
static void DoDiagram (void)
|
||||||
{
|
{
|
||||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK };
|
|
||||||
int XOrigin, YOrigin;
|
int XOrigin, YOrigin;
|
||||||
int Amp;
|
int Amp;
|
||||||
int X, Y;
|
int X, Y;
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
tgi_setpalette (Palette);
|
|
||||||
tgi_setcolor (COLOR_FORE);
|
tgi_setcolor (COLOR_FORE);
|
||||||
tgi_clear ();
|
tgi_clear ();
|
||||||
|
|
||||||
@@ -160,6 +182,9 @@ static void DoDiagram (void)
|
|||||||
tgi_lineto (XOrigin + X, YOrigin + Y);
|
tgi_lineto (XOrigin + X, YOrigin + Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (kbhit ()) {
|
||||||
|
cgetc ();
|
||||||
|
}
|
||||||
cgetc ();
|
cgetc ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,11 +192,9 @@ static void DoDiagram (void)
|
|||||||
|
|
||||||
static void DoLines (void)
|
static void DoLines (void)
|
||||||
{
|
{
|
||||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK };
|
|
||||||
unsigned X;
|
unsigned X;
|
||||||
const unsigned Min = (MaxX < MaxY) ? MaxX : MaxY;
|
const unsigned Min = (MaxX < MaxY) ? MaxX : MaxY;
|
||||||
|
|
||||||
tgi_setpalette (Palette);
|
|
||||||
tgi_setcolor (COLOR_FORE);
|
tgi_setcolor (COLOR_FORE);
|
||||||
tgi_clear ();
|
tgi_clear ();
|
||||||
|
|
||||||
@@ -182,6 +205,9 @@ static void DoLines (void)
|
|||||||
tgi_line (Min, Min, Min-X, 0);
|
tgi_line (Min, Min, Min-X, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (kbhit ()) {
|
||||||
|
cgetc ();
|
||||||
|
}
|
||||||
cgetc ();
|
cgetc ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,10 +242,11 @@ int main (void)
|
|||||||
Border = bordercolor (COLOR_BLACK);
|
Border = bordercolor (COLOR_BLACK);
|
||||||
|
|
||||||
/* Do graphics stuff */
|
/* Do graphics stuff */
|
||||||
DoCircles ();
|
|
||||||
DoCheckerboard ();
|
/* use default palette */ DoCircles ();
|
||||||
DoDiagram ();
|
DoPalette (0); DoCheckerboard ();
|
||||||
DoLines ();
|
DoPalette (1); DoDiagram ();
|
||||||
|
DoPalette (2); DoLines ();
|
||||||
|
|
||||||
#if DYN_DRV
|
#if DYN_DRV
|
||||||
/* Unload the driver */
|
/* Unload the driver */
|
||||||
|
|||||||
15
src/Makefile
15
src/Makefile
@@ -178,4 +178,19 @@ $(eval $(call OBJS_template,common))
|
|||||||
|
|
||||||
$(foreach prog,$(PROGS),$(eval $(call PROG_template,$(prog))))
|
$(foreach prog,$(PROGS),$(eval $(call PROG_template,$(prog))))
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: dbginfo dbgsh test
|
||||||
|
|
||||||
|
test: dbginfo dbgsh
|
||||||
|
|
||||||
|
$(eval $(call OBJS_template,dbginfo))
|
||||||
|
|
||||||
|
dbginfo: $(dbginfo_OBJS)
|
||||||
|
|
||||||
|
../wrk/dbgsh$(EXE_SUFFIX): $(dbginfo_OBJS) ../wrk/common/common.a
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
||||||
|
|
||||||
|
dbgsh: ../wrk/dbgsh$(EXE_SUFFIX)
|
||||||
|
|
||||||
|
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
|||||||
@@ -394,6 +394,16 @@ void DoConditionals (void)
|
|||||||
CalcOverallIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOK_IFP02X:
|
||||||
|
D = AllocIf (".IFP02X", 1);
|
||||||
|
NextTok ();
|
||||||
|
if (IfCond) {
|
||||||
|
SetIfCond (D, GetCPU() == CPU_6502X);
|
||||||
|
}
|
||||||
|
ExpectSep ();
|
||||||
|
CalcOverallIfCond ();
|
||||||
|
break;
|
||||||
|
|
||||||
case TOK_IFP4510:
|
case TOK_IFP4510:
|
||||||
D = AllocIf (".IFP4510", 1);
|
D = AllocIf (".IFP4510", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -485,6 +495,7 @@ int CheckConditionals (void)
|
|||||||
case TOK_IFNDEF:
|
case TOK_IFNDEF:
|
||||||
case TOK_IFNREF:
|
case TOK_IFNREF:
|
||||||
case TOK_IFP02:
|
case TOK_IFP02:
|
||||||
|
case TOK_IFP02X:
|
||||||
case TOK_IFP4510:
|
case TOK_IFP4510:
|
||||||
case TOK_IFP816:
|
case TOK_IFP816:
|
||||||
case TOK_IFPC02:
|
case TOK_IFPC02:
|
||||||
|
|||||||
@@ -169,8 +169,10 @@ static const struct {
|
|||||||
unsigned Count;
|
unsigned Count;
|
||||||
InsDesc Ins[56];
|
InsDesc Ins[56];
|
||||||
} InsTab6502 = {
|
} InsTab6502 = {
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
sizeof (InsTab6502.Ins) / sizeof (InsTab6502.Ins[0]),
|
sizeof (InsTab6502.Ins) / sizeof (InsTab6502.Ins[0]),
|
||||||
{
|
{
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "ADC", 0x080A26C, 0x60, 0, PutAll },
|
{ "ADC", 0x080A26C, 0x60, 0, PutAll },
|
||||||
{ "AND", 0x080A26C, 0x20, 0, PutAll },
|
{ "AND", 0x080A26C, 0x20, 0, PutAll },
|
||||||
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
||||||
@@ -227,6 +229,7 @@ static const struct {
|
|||||||
{ "TXA", 0x0000001, 0x8a, 0, PutAll },
|
{ "TXA", 0x0000001, 0x8a, 0, PutAll },
|
||||||
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
||||||
{ "TYA", 0x0000001, 0x98, 0, PutAll }
|
{ "TYA", 0x0000001, 0x98, 0, PutAll }
|
||||||
|
/* END SORTED.SH */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -235,8 +238,10 @@ static const struct {
|
|||||||
unsigned Count;
|
unsigned Count;
|
||||||
InsDesc Ins[75];
|
InsDesc Ins[75];
|
||||||
} InsTab6502X = {
|
} InsTab6502X = {
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
sizeof (InsTab6502X.Ins) / sizeof (InsTab6502X.Ins[0]),
|
sizeof (InsTab6502X.Ins) / sizeof (InsTab6502X.Ins[0]),
|
||||||
{
|
{
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "ADC", 0x080A26C, 0x60, 0, PutAll },
|
{ "ADC", 0x080A26C, 0x60, 0, PutAll },
|
||||||
{ "ALR", 0x0800000, 0x4B, 0, PutAll }, /* X */
|
{ "ALR", 0x0800000, 0x4B, 0, PutAll }, /* X */
|
||||||
{ "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X */
|
{ "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X */
|
||||||
@@ -312,6 +317,7 @@ static const struct {
|
|||||||
{ "TXA", 0x0000001, 0x8a, 0, PutAll },
|
{ "TXA", 0x0000001, 0x8a, 0, PutAll },
|
||||||
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
||||||
{ "TYA", 0x0000001, 0x98, 0, PutAll }
|
{ "TYA", 0x0000001, 0x98, 0, PutAll }
|
||||||
|
/* END SORTED.SH */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -324,8 +330,10 @@ static const struct {
|
|||||||
unsigned Count;
|
unsigned Count;
|
||||||
InsDesc Ins[71];
|
InsDesc Ins[71];
|
||||||
} InsTab6502DTV = {
|
} InsTab6502DTV = {
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
sizeof (InsTab6502DTV.Ins) / sizeof (InsTab6502DTV.Ins[0]),
|
sizeof (InsTab6502DTV.Ins) / sizeof (InsTab6502DTV.Ins[0]),
|
||||||
{
|
{
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "ADC", 0x080A26C, 0x60, 0, PutAll },
|
{ "ADC", 0x080A26C, 0x60, 0, PutAll },
|
||||||
{ "ALR", 0x0800000, 0x4B, 0, PutAll }, /* X */
|
{ "ALR", 0x0800000, 0x4B, 0, PutAll }, /* X */
|
||||||
{ "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X */
|
{ "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X */
|
||||||
@@ -397,6 +405,7 @@ static const struct {
|
|||||||
{ "TXA", 0x0000001, 0x8a, 0, PutAll },
|
{ "TXA", 0x0000001, 0x8a, 0, PutAll },
|
||||||
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
||||||
{ "TYA", 0x0000001, 0x98, 0, PutAll }
|
{ "TYA", 0x0000001, 0x98, 0, PutAll }
|
||||||
|
/* END SORTED.SH */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -405,8 +414,10 @@ static const struct {
|
|||||||
unsigned Count;
|
unsigned Count;
|
||||||
InsDesc Ins[66];
|
InsDesc Ins[66];
|
||||||
} InsTab65SC02 = {
|
} InsTab65SC02 = {
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
sizeof (InsTab65SC02.Ins) / sizeof (InsTab65SC02.Ins[0]),
|
sizeof (InsTab65SC02.Ins) / sizeof (InsTab65SC02.Ins[0]),
|
||||||
{
|
{
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
||||||
{ "AND", 0x080A66C, 0x20, 0, PutAll },
|
{ "AND", 0x080A66C, 0x20, 0, PutAll },
|
||||||
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
||||||
@@ -473,6 +484,7 @@ static const struct {
|
|||||||
{ "TXA", 0x0000001, 0x8a, 0, PutAll },
|
{ "TXA", 0x0000001, 0x8a, 0, PutAll },
|
||||||
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
||||||
{ "TYA", 0x0000001, 0x98, 0, PutAll }
|
{ "TYA", 0x0000001, 0x98, 0, PutAll }
|
||||||
|
/* END SORTED.SH */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -481,8 +493,10 @@ static const struct {
|
|||||||
unsigned Count;
|
unsigned Count;
|
||||||
InsDesc Ins[100];
|
InsDesc Ins[100];
|
||||||
} InsTab65C02 = {
|
} InsTab65C02 = {
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
sizeof (InsTab65C02.Ins) / sizeof (InsTab65C02.Ins[0]),
|
sizeof (InsTab65C02.Ins) / sizeof (InsTab65C02.Ins[0]),
|
||||||
{
|
{
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
||||||
{ "AND", 0x080A66C, 0x20, 0, PutAll },
|
{ "AND", 0x080A66C, 0x20, 0, PutAll },
|
||||||
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
||||||
@@ -583,6 +597,7 @@ static const struct {
|
|||||||
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
||||||
{ "TYA", 0x0000001, 0x98, 0, PutAll },
|
{ "TYA", 0x0000001, 0x98, 0, PutAll },
|
||||||
{ "WAI", 0x0000001, 0xcb, 0, PutAll }
|
{ "WAI", 0x0000001, 0xcb, 0, PutAll }
|
||||||
|
/* END SORTED.SH */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -591,8 +606,10 @@ static const struct {
|
|||||||
unsigned Count;
|
unsigned Count;
|
||||||
InsDesc Ins[133];
|
InsDesc Ins[133];
|
||||||
} InsTab4510 = {
|
} InsTab4510 = {
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
sizeof (InsTab4510.Ins) / sizeof (InsTab4510.Ins[0]),
|
sizeof (InsTab4510.Ins) / sizeof (InsTab4510.Ins[0]),
|
||||||
{
|
{
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
||||||
{ "AND", 0x080A66C, 0x20, 0, PutAll },
|
{ "AND", 0x080A66C, 0x20, 0, PutAll },
|
||||||
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
||||||
@@ -726,6 +743,7 @@ static const struct {
|
|||||||
{ "TYA", 0x0000001, 0x98, 0, PutAll },
|
{ "TYA", 0x0000001, 0x98, 0, PutAll },
|
||||||
{ "TYS", 0x0000001, 0x2b, 0, PutAll },
|
{ "TYS", 0x0000001, 0x2b, 0, PutAll },
|
||||||
{ "TZA", 0x0000001, 0x6b, 0, PutAll },
|
{ "TZA", 0x0000001, 0x6b, 0, PutAll },
|
||||||
|
/* END SORTED.SH */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -734,8 +752,10 @@ static const struct {
|
|||||||
unsigned Count;
|
unsigned Count;
|
||||||
InsDesc Ins[100];
|
InsDesc Ins[100];
|
||||||
} InsTab65816 = {
|
} InsTab65816 = {
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
sizeof (InsTab65816.Ins) / sizeof (InsTab65816.Ins[0]),
|
sizeof (InsTab65816.Ins) / sizeof (InsTab65816.Ins[0]),
|
||||||
{
|
{
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "ADC", 0x0b8f6fc, 0x60, 0, PutAll },
|
{ "ADC", 0x0b8f6fc, 0x60, 0, PutAll },
|
||||||
{ "AND", 0x0b8f6fc, 0x20, 0, PutAll },
|
{ "AND", 0x0b8f6fc, 0x20, 0, PutAll },
|
||||||
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
||||||
@@ -836,6 +856,7 @@ static const struct {
|
|||||||
{ "WDM", 0x0800004, 0x42, 6, PutAll },
|
{ "WDM", 0x0800004, 0x42, 6, PutAll },
|
||||||
{ "XBA", 0x0000001, 0xeb, 0, PutAll },
|
{ "XBA", 0x0000001, 0xeb, 0, PutAll },
|
||||||
{ "XCE", 0x0000001, 0xfb, 0, PutAll }
|
{ "XCE", 0x0000001, 0xfb, 0, PutAll }
|
||||||
|
/* END SORTED.SH */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -844,8 +865,10 @@ static const struct {
|
|||||||
unsigned Count;
|
unsigned Count;
|
||||||
InsDesc Ins[26];
|
InsDesc Ins[26];
|
||||||
} InsTabSweet16 = {
|
} InsTabSweet16 = {
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
sizeof (InsTabSweet16.Ins) / sizeof (InsTabSweet16.Ins[0]),
|
sizeof (InsTabSweet16.Ins) / sizeof (InsTabSweet16.Ins[0]),
|
||||||
{
|
{
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "ADD", AMSW16_REG, 0xA0, 0, PutSweet16 },
|
{ "ADD", AMSW16_REG, 0xA0, 0, PutSweet16 },
|
||||||
{ "BC", AMSW16_BRA, 0x03, 0, PutSweet16Branch },
|
{ "BC", AMSW16_BRA, 0x03, 0, PutSweet16Branch },
|
||||||
{ "BK", AMSW16_IMP, 0x0A, 0, PutSweet16 },
|
{ "BK", AMSW16_IMP, 0x0A, 0, PutSweet16 },
|
||||||
@@ -872,6 +895,7 @@ static const struct {
|
|||||||
{ "STD", AMSW16_IND, 0x70, 0, PutSweet16 },
|
{ "STD", AMSW16_IND, 0x70, 0, PutSweet16 },
|
||||||
{ "STP", AMSW16_IND, 0x90, 0, PutSweet16 },
|
{ "STP", AMSW16_IND, 0x90, 0, PutSweet16 },
|
||||||
{ "SUB", AMSW16_REG, 0xB0, 0, PutSweet16 },
|
{ "SUB", AMSW16_REG, 0xB0, 0, PutSweet16 },
|
||||||
|
/* END SORTED.SH */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -880,8 +904,10 @@ static const struct {
|
|||||||
unsigned Count;
|
unsigned Count;
|
||||||
InsDesc Ins[135];
|
InsDesc Ins[135];
|
||||||
} InsTabHuC6280 = {
|
} InsTabHuC6280 = {
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
sizeof (InsTabHuC6280.Ins) / sizeof (InsTabHuC6280.Ins[0]),
|
sizeof (InsTabHuC6280.Ins) / sizeof (InsTabHuC6280.Ins[0]),
|
||||||
{
|
{
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
||||||
{ "AND", 0x080A66C, 0x20, 0, PutAll },
|
{ "AND", 0x080A66C, 0x20, 0, PutAll },
|
||||||
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
{ "ASL", 0x000006e, 0x02, 1, PutAll },
|
||||||
@@ -1017,6 +1043,7 @@ static const struct {
|
|||||||
{ "TXA", 0x0000001, 0x8a, 0, PutAll },
|
{ "TXA", 0x0000001, 0x8a, 0, PutAll },
|
||||||
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
{ "TXS", 0x0000001, 0x9a, 0, PutAll },
|
||||||
{ "TYA", 0x0000001, 0x98, 0, PutAll }
|
{ "TYA", 0x0000001, 0x98, 0, PutAll }
|
||||||
|
/* END SORTED.SH */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -350,6 +350,10 @@ static void SetSys (const char* Sys)
|
|||||||
NewSymbol ("__RP6502__", 1);
|
NewSymbol ("__RP6502__", 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TGT_AGAT:
|
||||||
|
NewSymbol ("__AGAT__", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
AbEnd ("Invalid target name: '%s'", Sys);
|
AbEnd ("Invalid target name: '%s'", Sys);
|
||||||
|
|
||||||
|
|||||||
@@ -1562,6 +1562,14 @@ static void DoP02 (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void DoP02X (void)
|
||||||
|
/* Switch to 6502 CPU */
|
||||||
|
{
|
||||||
|
SetCPU (CPU_6502X);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void DoPC02 (void)
|
static void DoPC02 (void)
|
||||||
/* Switch to 65C02 CPU */
|
/* Switch to 65C02 CPU */
|
||||||
{
|
{
|
||||||
@@ -2057,70 +2065,72 @@ struct CtrlDesc {
|
|||||||
void (*Handler) (void); /* Command handler */
|
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]))
|
#define PSEUDO_COUNT (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0]))
|
||||||
static CtrlDesc CtrlCmdTab [] = {
|
static CtrlDesc CtrlCmdTab [] = {
|
||||||
{ ccNone, DoA16 },
|
{ ccNone, DoA16 }, /* .A16 */
|
||||||
{ ccNone, DoA8 },
|
{ ccNone, DoA8 }, /* .A8 */
|
||||||
{ ccNone, DoAddr }, /* .ADDR */
|
{ ccNone, DoAddr }, /* .ADDR */
|
||||||
{ ccNone, DoUnexpected }, /* .ADDRSIZE */
|
{ ccNone, DoUnexpected }, /* .ADDRSIZE */
|
||||||
{ ccNone, DoAlign },
|
{ ccNone, DoAlign }, /* .ALIGN */
|
||||||
{ ccNone, DoASCIIZ },
|
{ ccNone, DoASCIIZ }, /* .ASCIIZ */
|
||||||
{ ccNone, DoUnexpected }, /* .ASIZE */
|
{ ccNone, DoUnexpected }, /* .ASIZE */
|
||||||
{ ccNone, DoAssert },
|
{ ccNone, DoAssert }, /* .ASSERT */
|
||||||
{ ccNone, DoAutoImport },
|
{ ccNone, DoAutoImport }, /* .AUTOIMPORT */
|
||||||
{ ccNone, DoUnexpected }, /* .BANK */
|
{ ccNone, DoUnexpected }, /* .BANK */
|
||||||
{ ccNone, DoUnexpected }, /* .BANKBYTE */
|
{ ccNone, DoUnexpected }, /* .BANKBYTE */
|
||||||
{ ccNone, DoBankBytes },
|
{ ccNone, DoBankBytes }, /* .BANKBYTES */
|
||||||
{ ccNone, DoUnexpected }, /* .BLANK */
|
{ ccNone, DoUnexpected }, /* .BLANK */
|
||||||
{ ccNone, DoBss },
|
{ ccNone, DoBss }, /* .BSS */
|
||||||
{ ccNone, DoByte },
|
{ ccNone, DoByte }, /* .BYT, .BYTE */
|
||||||
{ ccNone, DoCase },
|
{ ccNone, DoCase }, /* .CASE */
|
||||||
{ ccNone, DoCharMap },
|
{ ccNone, DoCharMap }, /* .CHARMAP */
|
||||||
{ ccNone, DoCode },
|
{ ccNone, DoCode }, /* .CODE */
|
||||||
{ ccNone, DoUnexpected, }, /* .CONCAT */
|
{ ccNone, DoUnexpected, }, /* .CONCAT */
|
||||||
{ ccNone, DoConDes },
|
{ ccNone, DoConDes }, /* .CONDES */
|
||||||
{ ccNone, DoUnexpected }, /* .CONST */
|
{ ccNone, DoUnexpected }, /* .CONST */
|
||||||
{ ccNone, DoConstructor },
|
{ ccNone, DoConstructor }, /* .CONSTRUCTOR */
|
||||||
{ ccNone, DoUnexpected }, /* .CPU */
|
{ ccNone, DoUnexpected }, /* .CPU */
|
||||||
{ ccNone, DoData },
|
{ ccNone, DoData }, /* .DATA */
|
||||||
{ ccNone, DoDbg, },
|
{ ccNone, DoDbg, }, /* .DBG */
|
||||||
{ ccNone, DoDByt },
|
{ ccNone, DoDByt }, /* .DBYT */
|
||||||
{ ccNone, DoDebugInfo },
|
{ ccNone, DoDebugInfo }, /* .DEBUGINFO */
|
||||||
{ ccKeepToken, DoDefine },
|
{ ccKeepToken, DoDefine }, /* .DEF, .DEFINE */
|
||||||
{ ccNone, DoUnexpected }, /* .DEFINED */
|
{ ccNone, DoUnexpected }, /* .DEFINED */
|
||||||
{ ccNone, DoUnexpected }, /* .DEFINEDMACRO */
|
{ ccNone, DoUnexpected }, /* .DEFINEDMACRO */
|
||||||
{ ccNone, DoDelMac },
|
{ ccNone, DoDelMac }, /* .DELMAC, .DELMACRO */
|
||||||
{ ccNone, DoDestructor },
|
{ ccNone, DoDestructor }, /* .DESTRUCTOR */
|
||||||
{ ccNone, DoDWord },
|
{ ccNone, DoDWord }, /* .DWORD */
|
||||||
{ ccKeepToken, DoConditionals }, /* .ELSE */
|
{ ccKeepToken, DoConditionals }, /* .ELSE */
|
||||||
{ ccKeepToken, DoConditionals }, /* .ELSEIF */
|
{ ccKeepToken, DoConditionals }, /* .ELSEIF */
|
||||||
{ ccKeepToken, DoEnd },
|
{ ccKeepToken, DoEnd }, /* .END */
|
||||||
{ ccNone, DoUnexpected }, /* .ENDENUM */
|
{ ccNone, DoUnexpected }, /* .ENDENUM */
|
||||||
{ ccKeepToken, DoConditionals }, /* .ENDIF */
|
{ ccKeepToken, DoConditionals }, /* .ENDIF */
|
||||||
{ ccNone, DoUnexpected }, /* .ENDMACRO */
|
{ ccNone, DoUnexpected }, /* .ENDMAC, .ENDMACRO */
|
||||||
{ ccNone, DoEndProc },
|
{ ccNone, DoEndProc }, /* .ENDPROC */
|
||||||
{ ccNone, DoUnexpected }, /* .ENDREPEAT */
|
{ ccNone, DoUnexpected }, /* .ENDREP, .ENDREPEAT */
|
||||||
{ ccNone, DoEndScope },
|
{ ccNone, DoEndScope }, /* .ENDSCOPE */
|
||||||
{ ccNone, DoUnexpected }, /* .ENDSTRUCT */
|
{ ccNone, DoUnexpected }, /* .ENDSTRUCT */
|
||||||
{ ccNone, DoUnexpected }, /* .ENDUNION */
|
{ ccNone, DoUnexpected }, /* .ENDUNION */
|
||||||
{ ccNone, DoEnum },
|
{ ccNone, DoEnum }, /* .ENUM */
|
||||||
{ ccNone, DoError },
|
{ ccNone, DoError }, /* .ERROR */
|
||||||
{ ccNone, DoExitMacro },
|
{ ccNone, DoExitMacro }, /* .EXITMAC, .EXITMACRO */
|
||||||
{ ccNone, DoExport },
|
{ ccNone, DoExport }, /* .EXPORT */
|
||||||
{ ccNone, DoExportZP },
|
{ ccNone, DoExportZP }, /* .EXPORTZP */
|
||||||
{ ccNone, DoFarAddr },
|
{ ccNone, DoFarAddr }, /* .FARADDR */
|
||||||
{ ccNone, DoFatal },
|
{ ccNone, DoFatal }, /* .FATAL */
|
||||||
{ ccNone, DoFeature },
|
{ ccNone, DoFeature }, /* .FEATURE */
|
||||||
{ ccNone, DoFileOpt },
|
{ ccNone, DoFileOpt }, /* .FOPT, .FILEOPT */
|
||||||
{ ccNone, DoForceImport },
|
{ ccNone, DoForceImport }, /* .FORCEIMPORT */
|
||||||
{ ccNone, DoUnexpected }, /* .FORCEWORD */
|
{ ccNone, DoUnexpected }, /* .FORCEWORD */
|
||||||
{ ccNone, DoGlobal },
|
{ ccNone, DoGlobal }, /* .GLOBAL */
|
||||||
{ ccNone, DoGlobalZP },
|
{ ccNone, DoGlobalZP }, /* .GLOBALZP */
|
||||||
{ ccNone, DoUnexpected }, /* .HIBYTE */
|
{ ccNone, DoUnexpected }, /* .HIBYTE */
|
||||||
{ ccNone, DoHiBytes },
|
{ ccNone, DoHiBytes }, /* .HIBYTES */
|
||||||
{ ccNone, DoUnexpected }, /* .HIWORD */
|
{ ccNone, DoUnexpected }, /* .HIWORD */
|
||||||
{ ccNone, DoI16 },
|
{ ccNone, DoI16 }, /* .I16 */
|
||||||
{ ccNone, DoI8 },
|
{ ccNone, DoI8 }, /* .I8 */
|
||||||
{ ccNone, DoUnexpected }, /* .IDENT */
|
{ ccNone, DoUnexpected }, /* .IDENT */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IF */
|
{ ccKeepToken, DoConditionals }, /* .IF */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFBLANK */
|
{ ccKeepToken, DoConditionals }, /* .IFBLANK */
|
||||||
@@ -2131,81 +2141,83 @@ static CtrlDesc CtrlCmdTab [] = {
|
|||||||
{ ccKeepToken, DoConditionals }, /* .IFNDEF */
|
{ ccKeepToken, DoConditionals }, /* .IFNDEF */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFNREF */
|
{ ccKeepToken, DoConditionals }, /* .IFNREF */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFP02 */
|
{ ccKeepToken, DoConditionals }, /* .IFP02 */
|
||||||
|
{ ccKeepToken, DoConditionals }, /* .IFP02X */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFP4510 */
|
{ ccKeepToken, DoConditionals }, /* .IFP4510 */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFP816 */
|
{ ccKeepToken, DoConditionals }, /* .IFP816 */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFPC02 */
|
{ ccKeepToken, DoConditionals }, /* .IFPC02 */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFPDTV */
|
{ ccKeepToken, DoConditionals }, /* .IFPDTV */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFPSC02 */
|
{ ccKeepToken, DoConditionals }, /* .IFPSC02 */
|
||||||
{ ccKeepToken, DoConditionals }, /* .IFREF */
|
{ ccKeepToken, DoConditionals }, /* .IFREF */
|
||||||
{ ccNone, DoImport },
|
{ ccNone, DoImport }, /* .IMPORT */
|
||||||
{ ccNone, DoImportZP },
|
{ ccNone, DoImportZP }, /* .IMPORTZP */
|
||||||
{ ccNone, DoIncBin },
|
{ ccNone, DoIncBin }, /* .INCBIN */
|
||||||
{ ccNone, DoInclude },
|
{ ccNone, DoInclude }, /* .INCLUDE */
|
||||||
{ ccNone, DoInterruptor },
|
{ ccNone, DoInterruptor }, /* .INTERRUPTPOR */
|
||||||
{ ccNone, DoUnexpected }, /* .ISIZE */
|
{ ccNone, DoUnexpected }, /* .ISIZE */
|
||||||
{ ccNone, DoUnexpected }, /* .ISMNEMONIC */
|
{ ccNone, DoUnexpected }, /* .ISMNEMONIC */
|
||||||
{ ccNone, DoInvalid }, /* .LEFT */
|
{ ccNone, DoInvalid }, /* .LEFT */
|
||||||
{ ccNone, DoLineCont },
|
{ ccNone, DoLineCont }, /* .LINECONT */
|
||||||
{ ccNone, DoList },
|
{ ccNone, DoList }, /* .LIST */
|
||||||
{ ccNone, DoListBytes },
|
{ ccNone, DoListBytes }, /* .LISTBYTES */
|
||||||
{ ccNone, DoLiteral },
|
{ ccNone, DoLiteral }, /* .LITERAL */
|
||||||
{ ccNone, DoUnexpected }, /* .LOBYTE */
|
{ ccNone, DoUnexpected }, /* .LOBYTE */
|
||||||
{ ccNone, DoLoBytes },
|
{ ccNone, DoLoBytes }, /* .LOBYTES */
|
||||||
{ ccNone, DoUnexpected }, /* .LOCAL */
|
{ ccNone, DoUnexpected }, /* .LOCAL */
|
||||||
{ ccNone, DoLocalChar },
|
{ ccNone, DoLocalChar }, /* .LOCALCHAR */
|
||||||
{ ccNone, DoUnexpected }, /* .LOWORD */
|
{ ccNone, DoUnexpected }, /* .LOWORD */
|
||||||
{ ccNone, DoMacPack },
|
{ ccNone, DoMacPack }, /* .MACPACK */
|
||||||
{ ccNone, DoMacro },
|
{ ccNone, DoMacro }, /* .MAC, .MACRO */
|
||||||
{ ccNone, DoUnexpected }, /* .MATCH */
|
{ ccNone, DoUnexpected }, /* .MATCH */
|
||||||
{ ccNone, DoUnexpected }, /* .MAX */
|
{ ccNone, DoUnexpected }, /* .MAX */
|
||||||
{ ccNone, DoInvalid }, /* .MID */
|
{ ccNone, DoInvalid }, /* .MID */
|
||||||
{ ccNone, DoUnexpected }, /* .MIN */
|
{ ccNone, DoUnexpected }, /* .MIN */
|
||||||
{ ccNone, DoNull },
|
{ ccNone, DoNull }, /* .NULL */
|
||||||
{ ccNone, DoOrg },
|
{ ccNone, DoOrg }, /* .ORG */
|
||||||
{ ccNone, DoOut },
|
{ ccNone, DoOut }, /* .OUT */
|
||||||
{ ccNone, DoP02 },
|
{ ccNone, DoP02 }, /* .P02 */
|
||||||
{ ccNone, DoP4510 },
|
{ ccNone, DoP02X }, /* .P02X */
|
||||||
{ ccNone, DoP816 },
|
{ ccNone, DoP4510 }, /* .P4510 */
|
||||||
{ ccNone, DoPageLength },
|
{ ccNone, DoP816 }, /* .P816 */
|
||||||
|
{ ccNone, DoPageLength }, /* .PAGELEN, .PAGELENGTH */
|
||||||
{ ccNone, DoUnexpected }, /* .PARAMCOUNT */
|
{ ccNone, DoUnexpected }, /* .PARAMCOUNT */
|
||||||
{ ccNone, DoPC02 },
|
{ ccNone, DoPC02 }, /* .PSC02 */
|
||||||
{ ccNone, DoPDTV },
|
{ ccNone, DoPDTV }, /* .PDTV */
|
||||||
{ ccNone, DoPopCharmap },
|
{ ccNone, DoPopCharmap }, /* .POPCHARMAP */
|
||||||
{ ccNone, DoPopCPU },
|
{ ccNone, DoPopCPU }, /* .POPCPU */
|
||||||
{ ccNone, DoPopSeg },
|
{ ccNone, DoPopSeg }, /* .POPSEG */
|
||||||
{ ccNone, DoProc },
|
{ ccNone, DoProc }, /* .PROC */
|
||||||
{ ccNone, DoPSC02 },
|
{ ccNone, DoPSC02 }, /* .PSC02 */
|
||||||
{ ccNone, DoPushCharmap },
|
{ ccNone, DoPushCharmap }, /* .PUSHCHARMAP */
|
||||||
{ ccNone, DoPushCPU },
|
{ ccNone, DoPushCPU }, /* .PUSHCPU */
|
||||||
{ ccNone, DoPushSeg },
|
{ ccNone, DoPushSeg }, /* .PUSHSEG */
|
||||||
{ ccNone, DoUnexpected }, /* .REFERENCED */
|
{ ccNone, DoUnexpected }, /* .REF, .REFERENCED */
|
||||||
{ ccNone, DoReferTo }, /* .REFERTO */
|
{ ccNone, DoReferTo }, /* .REFTO, .REFERTO */
|
||||||
{ ccNone, DoReloc },
|
{ ccNone, DoReloc }, /* .RELOC */
|
||||||
{ ccNone, DoRepeat },
|
{ ccNone, DoRepeat }, /* .REPEAT */
|
||||||
{ ccNone, DoRes },
|
{ ccNone, DoRes }, /* .RES */
|
||||||
{ ccNone, DoInvalid }, /* .RIGHT */
|
{ ccNone, DoInvalid }, /* .RIGHT */
|
||||||
{ ccNone, DoROData },
|
{ ccNone, DoROData }, /* .RODATA */
|
||||||
{ ccNone, DoScope },
|
{ ccNone, DoScope }, /* .SCOPE */
|
||||||
{ ccNone, DoSegment },
|
{ ccNone, DoSegment }, /* .SEGMENT */
|
||||||
{ ccNone, DoUnexpected }, /* .SET */
|
{ ccNone, DoUnexpected }, /* .SET */
|
||||||
{ ccNone, DoSetCPU },
|
{ ccNone, DoSetCPU }, /* .SETCPU */
|
||||||
{ ccNone, DoUnexpected }, /* .SIZEOF */
|
{ ccNone, DoUnexpected }, /* .SIZEOF */
|
||||||
{ ccNone, DoSmart },
|
{ ccNone, DoSmart }, /* .SMART */
|
||||||
{ ccNone, DoUnexpected }, /* .SPRINTF */
|
{ ccNone, DoUnexpected }, /* .SPRINTF */
|
||||||
{ ccNone, DoUnexpected }, /* .STRAT */
|
{ ccNone, DoUnexpected }, /* .STRAT */
|
||||||
{ ccNone, DoUnexpected }, /* .STRING */
|
{ ccNone, DoUnexpected }, /* .STRING */
|
||||||
{ ccNone, DoUnexpected }, /* .STRLEN */
|
{ ccNone, DoUnexpected }, /* .STRLEN */
|
||||||
{ ccNone, DoStruct },
|
{ ccNone, DoStruct }, /* .STRUCT */
|
||||||
{ ccNone, DoTag },
|
{ ccNone, DoTag }, /* .TAG */
|
||||||
{ ccNone, DoUnexpected }, /* .TCOUNT */
|
{ ccNone, DoUnexpected }, /* .TCOUNT */
|
||||||
{ ccNone, DoUnexpected }, /* .TIME */
|
{ ccNone, DoUnexpected }, /* .TIME */
|
||||||
{ ccKeepToken, DoUnDef },
|
{ ccKeepToken, DoUnDef }, /* .UNDEF, .UNDEFINE */
|
||||||
{ ccNone, DoUnion },
|
{ ccNone, DoUnion }, /* .UNION */
|
||||||
{ ccNone, DoUnexpected }, /* .VERSION */
|
{ ccNone, DoUnexpected }, /* .VERSION */
|
||||||
{ ccNone, DoWarning },
|
{ ccNone, DoWarning }, /* .WARNING */
|
||||||
{ ccNone, DoWord },
|
{ ccNone, DoWord }, /* .WORD */
|
||||||
{ ccNone, DoUnexpected }, /* .XMATCH */
|
{ ccNone, DoUnexpected }, /* .XMATCH */
|
||||||
{ ccNone, DoZeropage },
|
{ ccNone, DoZeropage }, /* .ZEROPAGE */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -131,10 +131,12 @@ static int C = 0; /* Current input character */
|
|||||||
int ForcedEnd = 0;
|
int ForcedEnd = 0;
|
||||||
|
|
||||||
/* List of dot keywords with the corresponding tokens */
|
/* List of dot keywords with the corresponding tokens */
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
struct DotKeyword {
|
struct DotKeyword {
|
||||||
const char* Key; /* MUST be first field */
|
const char* Key; /* MUST be first field */
|
||||||
token_t Tok;
|
token_t Tok;
|
||||||
} DotKeywords [] = {
|
} DotKeywords [] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ ".A16", TOK_A16 },
|
{ ".A16", TOK_A16 },
|
||||||
{ ".A8", TOK_A8 },
|
{ ".A8", TOK_A8 },
|
||||||
{ ".ADDR", TOK_ADDR },
|
{ ".ADDR", TOK_ADDR },
|
||||||
@@ -219,6 +221,7 @@ struct DotKeyword {
|
|||||||
{ ".IFNDEF", TOK_IFNDEF },
|
{ ".IFNDEF", TOK_IFNDEF },
|
||||||
{ ".IFNREF", TOK_IFNREF },
|
{ ".IFNREF", TOK_IFNREF },
|
||||||
{ ".IFP02", TOK_IFP02 },
|
{ ".IFP02", TOK_IFP02 },
|
||||||
|
{ ".IFP02X", TOK_IFP02X },
|
||||||
{ ".IFP4510", TOK_IFP4510 },
|
{ ".IFP4510", TOK_IFP4510 },
|
||||||
{ ".IFP816", TOK_IFP816 },
|
{ ".IFP816", TOK_IFP816 },
|
||||||
{ ".IFPC02", TOK_IFPC02 },
|
{ ".IFPC02", TOK_IFPC02 },
|
||||||
@@ -257,6 +260,7 @@ struct DotKeyword {
|
|||||||
{ ".ORG", TOK_ORG },
|
{ ".ORG", TOK_ORG },
|
||||||
{ ".OUT", TOK_OUT },
|
{ ".OUT", TOK_OUT },
|
||||||
{ ".P02", TOK_P02 },
|
{ ".P02", TOK_P02 },
|
||||||
|
{ ".P02X", TOK_P02X },
|
||||||
{ ".P4510", TOK_P4510 },
|
{ ".P4510", TOK_P4510 },
|
||||||
{ ".P816", TOK_P816 },
|
{ ".P816", TOK_P816 },
|
||||||
{ ".PAGELEN", TOK_PAGELENGTH },
|
{ ".PAGELEN", TOK_PAGELENGTH },
|
||||||
@@ -306,6 +310,7 @@ struct DotKeyword {
|
|||||||
{ ".XMATCH", TOK_XMATCH },
|
{ ".XMATCH", TOK_XMATCH },
|
||||||
{ ".XOR", TOK_BOOLXOR },
|
{ ".XOR", TOK_BOOLXOR },
|
||||||
{ ".ZEROPAGE", TOK_ZEROPAGE },
|
{ ".ZEROPAGE", TOK_ZEROPAGE },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -193,6 +193,7 @@ typedef enum token_t {
|
|||||||
TOK_IFNDEF,
|
TOK_IFNDEF,
|
||||||
TOK_IFNREF,
|
TOK_IFNREF,
|
||||||
TOK_IFP02,
|
TOK_IFP02,
|
||||||
|
TOK_IFP02X,
|
||||||
TOK_IFP4510,
|
TOK_IFP4510,
|
||||||
TOK_IFP816,
|
TOK_IFP816,
|
||||||
TOK_IFPC02,
|
TOK_IFPC02,
|
||||||
@@ -226,6 +227,7 @@ typedef enum token_t {
|
|||||||
TOK_ORG,
|
TOK_ORG,
|
||||||
TOK_OUT,
|
TOK_OUT,
|
||||||
TOK_P02,
|
TOK_P02,
|
||||||
|
TOK_P02X,
|
||||||
TOK_P4510,
|
TOK_P4510,
|
||||||
TOK_P816,
|
TOK_P816,
|
||||||
TOK_PAGELENGTH,
|
TOK_PAGELENGTH,
|
||||||
|
|||||||
@@ -90,7 +90,9 @@ struct FuncInfo {
|
|||||||
** routines are marked to use only the A register. The remainder is ignored
|
** routines are marked to use only the A register. The remainder is ignored
|
||||||
** anyway.
|
** anyway.
|
||||||
*/
|
*/
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
static const FuncInfo FuncInfoTable[] = {
|
static const FuncInfo FuncInfoTable[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "addeq0sp", SLV_TOP | REG_AX, PSTATE_ALL | REG_AXY },
|
{ "addeq0sp", SLV_TOP | REG_AX, PSTATE_ALL | REG_AXY },
|
||||||
{ "addeqysp", SLV_IND | REG_AXY, PSTATE_ALL | REG_AXY },
|
{ "addeqysp", SLV_IND | REG_AXY, PSTATE_ALL | REG_AXY },
|
||||||
{ "addysp", REG_SP | REG_Y, PSTATE_ALL | REG_SP },
|
{ "addysp", REG_SP | REG_Y, PSTATE_ALL | REG_SP },
|
||||||
@@ -190,12 +192,12 @@ static const FuncInfo FuncInfoTable[] = {
|
|||||||
{ "ldeaxysp", SLV_IND | REG_Y, PSTATE_ALL | REG_EAXY },
|
{ "ldeaxysp", SLV_IND | REG_Y, PSTATE_ALL | REG_EAXY },
|
||||||
{ "leaa0sp", REG_SP | REG_A, PSTATE_ALL | REG_AX },
|
{ "leaa0sp", REG_SP | REG_A, PSTATE_ALL | REG_AX },
|
||||||
{ "leaaxsp", REG_SP | REG_AX, PSTATE_ALL | REG_AX },
|
{ "leaaxsp", REG_SP | REG_AX, PSTATE_ALL | REG_AX },
|
||||||
{ "leave00", REG_SP, PSTATE_ALL | REG_SP | REG_AXY },
|
|
||||||
{ "leave0", REG_SP, PSTATE_ALL | REG_SP | REG_XY },
|
|
||||||
{ "leave", REG_SP, PSTATE_ALL | REG_SP | REG_Y },
|
{ "leave", REG_SP, PSTATE_ALL | REG_SP | REG_Y },
|
||||||
{ "leavey00", REG_SP, PSTATE_ALL | REG_SP | REG_AXY },
|
{ "leave0", REG_SP, PSTATE_ALL | REG_SP | REG_XY },
|
||||||
{ "leavey0", REG_SP, PSTATE_ALL | REG_SP | REG_XY },
|
{ "leave00", REG_SP, PSTATE_ALL | REG_SP | REG_AXY },
|
||||||
{ "leavey", REG_SP | REG_Y, PSTATE_ALL | REG_SP | REG_Y },
|
{ "leavey", REG_SP | REG_Y, PSTATE_ALL | REG_SP | REG_Y },
|
||||||
|
{ "leavey0", REG_SP, PSTATE_ALL | REG_SP | REG_XY },
|
||||||
|
{ "leavey00", REG_SP, PSTATE_ALL | REG_SP | REG_AXY },
|
||||||
{ "lsubeq", REG_EAXY | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI },
|
{ "lsubeq", REG_EAXY | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI },
|
||||||
{ "lsubeq0sp", SLV_TOP | REG_EAX, PSTATE_ALL | REG_EAXY },
|
{ "lsubeq0sp", SLV_TOP | REG_EAX, PSTATE_ALL | REG_EAXY },
|
||||||
{ "lsubeq1", REG_Y | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI },
|
{ "lsubeq1", REG_Y | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI },
|
||||||
@@ -376,11 +378,14 @@ static const FuncInfo FuncInfoTable[] = {
|
|||||||
{ "tosxoreax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 },
|
{ "tosxoreax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 },
|
||||||
{ "tsteax", REG_EAX, PSTATE_ALL | REG_Y },
|
{ "tsteax", REG_EAX, PSTATE_ALL | REG_Y },
|
||||||
{ "utsteax", REG_EAX, PSTATE_ALL | REG_Y },
|
{ "utsteax", REG_EAX, PSTATE_ALL | REG_Y },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
#define FuncInfoCount (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0]))
|
#define FuncInfoCount (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0]))
|
||||||
|
|
||||||
/* Table with names of zero page locations used by the compiler */
|
/* Table with names of zero page locations used by the compiler */
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
static const ZPInfo ZPInfoTable[] = {
|
static const ZPInfo ZPInfoTable[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ 0, "ptr1", 2, REG_PTR1_LO, REG_PTR1 },
|
{ 0, "ptr1", 2, REG_PTR1_LO, REG_PTR1 },
|
||||||
{ 0, "ptr1+1", 1, REG_PTR1_HI, REG_PTR1 },
|
{ 0, "ptr1+1", 1, REG_PTR1_HI, REG_PTR1 },
|
||||||
{ 0, "ptr2", 2, REG_PTR2_LO, REG_PTR2 },
|
{ 0, "ptr2", 2, REG_PTR2_LO, REG_PTR2 },
|
||||||
@@ -398,6 +403,7 @@ static const ZPInfo ZPInfoTable[] = {
|
|||||||
{ 0, "tmp2", 1, REG_NONE, REG_NONE },
|
{ 0, "tmp2", 1, REG_NONE, REG_NONE },
|
||||||
{ 0, "tmp3", 1, REG_NONE, REG_NONE },
|
{ 0, "tmp3", 1, REG_NONE, REG_NONE },
|
||||||
{ 0, "tmp4", 1, REG_NONE, REG_NONE },
|
{ 0, "tmp4", 1, REG_NONE, REG_NONE },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
#define ZPInfoCount (sizeof(ZPInfoTable) / sizeof(ZPInfoTable[0]))
|
#define ZPInfoCount (sizeof(ZPInfoTable) / sizeof(ZPInfoTable[0]))
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ struct OptFunc {
|
|||||||
|
|
||||||
|
|
||||||
/* A list of all the function descriptions */
|
/* A list of all the function descriptions */
|
||||||
|
/* CAUTION: should be sorted by "name" */
|
||||||
|
/* BEGIN DECL SORTED_CODEOPT.SH */
|
||||||
static OptFunc DOpt65C02BitOps = { Opt65C02BitOps, "Opt65C02BitOps", 66, 0, 0, 0, 0, 0 };
|
static OptFunc DOpt65C02BitOps = { Opt65C02BitOps, "Opt65C02BitOps", 66, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOpt65C02Ind = { Opt65C02Ind, "Opt65C02Ind", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOpt65C02Ind = { Opt65C02Ind, "Opt65C02Ind", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOpt65C02Stores = { Opt65C02Stores, "Opt65C02Stores", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOpt65C02Stores = { Opt65C02Stores, "Opt65C02Stores", 100, 0, 0, 0, 0, 0 };
|
||||||
@@ -152,18 +154,13 @@ static OptFunc DOptJumpTarget3 = { OptJumpTarget3, "OptJumpTarget3", 100, 0,
|
|||||||
static OptFunc DOptLoad1 = { OptLoad1, "OptLoad1", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptLoad1 = { OptLoad1, "OptLoad1", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptLoad2 = { OptLoad2, "OptLoad2", 200, 0, 0, 0, 0, 0 };
|
static OptFunc DOptLoad2 = { OptLoad2, "OptLoad2", 200, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptLoad3 = { OptLoad3, "OptLoad3", 0, 0, 0, 0, 0, 0 };
|
static OptFunc DOptLoad3 = { OptLoad3, "OptLoad3", 0, 0, 0, 0, 0, 0 };
|
||||||
|
static OptFunc DOptLoadStoreLoad= { OptLoadStoreLoad,"OptLoadStoreLoad", 0, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptLongAssign = { OptLongAssign, "OptLongAssign", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptLongAssign = { OptLongAssign, "OptLongAssign", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptLongCopy = { OptLongCopy, "OptLongCopy", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptLongCopy = { OptLongCopy, "OptLongCopy", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptNegAX1 = { OptNegAX1, "OptNegAX1", 165, 0, 0, 0, 0, 0 };
|
static OptFunc DOptNegAX1 = { OptNegAX1, "OptNegAX1", 165, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptNegAX2 = { OptNegAX2, "OptNegAX2", 200, 0, 0, 0, 0, 0 };
|
static OptFunc DOptNegAX2 = { OptNegAX2, "OptNegAX2", 200, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptPrecalc = { OptPrecalc, "OptPrecalc", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptPrecalc = { OptPrecalc, "OptPrecalc", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptPtrLoad1 = { OptPtrLoad1, "OptPtrLoad1", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptPtrLoad1 = { OptPtrLoad1, "OptPtrLoad1", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptPtrLoad2 = { OptPtrLoad2, "OptPtrLoad2", 100, 0, 0, 0, 0, 0 };
|
|
||||||
static OptFunc DOptPtrLoad3 = { OptPtrLoad3, "OptPtrLoad3", 100, 0, 0, 0, 0, 0 };
|
|
||||||
static OptFunc DOptPtrLoad4 = { OptPtrLoad4, "OptPtrLoad4", 100, 0, 0, 0, 0, 0 };
|
|
||||||
static OptFunc DOptPtrLoad5 = { OptPtrLoad5, "OptPtrLoad5", 50, 0, 0, 0, 0, 0 };
|
|
||||||
static OptFunc DOptPtrLoad6 = { OptPtrLoad6, "OptPtrLoad6", 60, 0, 0, 0, 0, 0 };
|
|
||||||
static OptFunc DOptPtrLoad7 = { OptPtrLoad7, "OptPtrLoad7", 140, 0, 0, 0, 0, 0 };
|
|
||||||
static OptFunc DOptPtrLoad11 = { OptPtrLoad11, "OptPtrLoad11", 92, 0, 0, 0, 0, 0 };
|
static OptFunc DOptPtrLoad11 = { OptPtrLoad11, "OptPtrLoad11", 92, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptPtrLoad12 = { OptPtrLoad12, "OptPtrLoad12", 50, 0, 0, 0, 0, 0 };
|
static OptFunc DOptPtrLoad12 = { OptPtrLoad12, "OptPtrLoad12", 50, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptPtrLoad13 = { OptPtrLoad13, "OptPtrLoad13", 65, 0, 0, 0, 0, 0 };
|
static OptFunc DOptPtrLoad13 = { OptPtrLoad13, "OptPtrLoad13", 65, 0, 0, 0, 0, 0 };
|
||||||
@@ -173,6 +170,12 @@ static OptFunc DOptPtrLoad16 = { OptPtrLoad16, "OptPtrLoad16", 100, 0,
|
|||||||
static OptFunc DOptPtrLoad17 = { OptPtrLoad17, "OptPtrLoad17", 190, 0, 0, 0, 0, 0 };
|
static OptFunc DOptPtrLoad17 = { OptPtrLoad17, "OptPtrLoad17", 190, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptPtrLoad18 = { OptPtrLoad18, "OptPtrLoad18", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptPtrLoad18 = { OptPtrLoad18, "OptPtrLoad18", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptPtrLoad19 = { OptPtrLoad19, "OptPtrLoad19", 65, 0, 0, 0, 0, 0 };
|
static OptFunc DOptPtrLoad19 = { OptPtrLoad19, "OptPtrLoad19", 65, 0, 0, 0, 0, 0 };
|
||||||
|
static OptFunc DOptPtrLoad2 = { OptPtrLoad2, "OptPtrLoad2", 100, 0, 0, 0, 0, 0 };
|
||||||
|
static OptFunc DOptPtrLoad3 = { OptPtrLoad3, "OptPtrLoad3", 100, 0, 0, 0, 0, 0 };
|
||||||
|
static OptFunc DOptPtrLoad4 = { OptPtrLoad4, "OptPtrLoad4", 100, 0, 0, 0, 0, 0 };
|
||||||
|
static OptFunc DOptPtrLoad5 = { OptPtrLoad5, "OptPtrLoad5", 50, 0, 0, 0, 0, 0 };
|
||||||
|
static OptFunc DOptPtrLoad6 = { OptPtrLoad6, "OptPtrLoad6", 60, 0, 0, 0, 0, 0 };
|
||||||
|
static OptFunc DOptPtrLoad7 = { OptPtrLoad7, "OptPtrLoad7", 140, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptPtrStore1 = { OptPtrStore1, "OptPtrStore1", 65, 0, 0, 0, 0, 0 };
|
static OptFunc DOptPtrStore1 = { OptPtrStore1, "OptPtrStore1", 65, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 65, 0, 0, 0, 0, 0 };
|
static OptFunc DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 65, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptPtrStore3 = { OptPtrStore3, "OptPtrStore3", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptPtrStore3 = { OptPtrStore3, "OptPtrStore3", 100, 0, 0, 0, 0, 0 };
|
||||||
@@ -202,7 +205,6 @@ static OptFunc DOptStore3 = { OptStore3, "OptStore3", 120, 0,
|
|||||||
static OptFunc DOptStore4 = { OptStore4, "OptStore4", 50, 0, 0, 0, 0, 0 };
|
static OptFunc DOptStore4 = { OptStore4, "OptStore4", 50, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptStore5 = { OptStore5, "OptStore5", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptStore5 = { OptStore5, "OptStore5", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptStoreLoad = { OptStoreLoad, "OptStoreLoad", 0, 0, 0, 0, 0, 0 };
|
static OptFunc DOptStoreLoad = { OptStoreLoad, "OptStoreLoad", 0, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptLoadStoreLoad= { OptLoadStoreLoad,"OptLoadStoreLoad", 0, 0, 0, 0, 0, 0 };
|
|
||||||
static OptFunc DOptSub1 = { OptSub1, "OptSub1", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptSub1 = { OptSub1, "OptSub1", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptSub2 = { OptSub2, "OptSub2", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptSub2 = { OptSub2, "OptSub2", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptSub3 = { OptSub3, "OptSub3", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptSub3 = { OptSub3, "OptSub3", 100, 0, 0, 0, 0, 0 };
|
||||||
@@ -214,10 +216,13 @@ static OptFunc DOptTransfers3 = { OptTransfers3, "OptTransfers3", 65, 0,
|
|||||||
static OptFunc DOptTransfers4 = { OptTransfers4, "OptTransfers4", 65, 0, 0, 0, 0, 0 };
|
static OptFunc DOptTransfers4 = { OptTransfers4, "OptTransfers4", 65, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptUnusedLoads = { OptUnusedLoads, "OptUnusedLoads", 0, 0, 0, 0, 0, 0 };
|
static OptFunc DOptUnusedLoads = { OptUnusedLoads, "OptUnusedLoads", 0, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptUnusedStores = { OptUnusedStores, "OptUnusedStores", 0, 0, 0, 0, 0, 0 };
|
static OptFunc DOptUnusedStores = { OptUnusedStores, "OptUnusedStores", 0, 0, 0, 0, 0, 0 };
|
||||||
|
/* END DECL SORTED_CODEOPT.SH */
|
||||||
|
|
||||||
|
|
||||||
/* Table containing all the steps in alphabetical order */
|
/* Table containing all the steps in alphabetical order */
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
static OptFunc* OptFuncs[] = {
|
static OptFunc* OptFuncs[] = {
|
||||||
|
/* BEGIN SORTED_CODEOPT.SH */
|
||||||
&DOpt65C02BitOps,
|
&DOpt65C02BitOps,
|
||||||
&DOpt65C02Ind,
|
&DOpt65C02Ind,
|
||||||
&DOpt65C02Stores,
|
&DOpt65C02Stores,
|
||||||
@@ -268,6 +273,7 @@ static OptFunc* OptFuncs[] = {
|
|||||||
&DOptLoad1,
|
&DOptLoad1,
|
||||||
&DOptLoad2,
|
&DOptLoad2,
|
||||||
&DOptLoad3,
|
&DOptLoad3,
|
||||||
|
&DOptLoadStoreLoad,
|
||||||
&DOptLongAssign,
|
&DOptLongAssign,
|
||||||
&DOptLongCopy,
|
&DOptLongCopy,
|
||||||
&DOptNegAX1,
|
&DOptNegAX1,
|
||||||
@@ -318,7 +324,6 @@ static OptFunc* OptFuncs[] = {
|
|||||||
&DOptStore4,
|
&DOptStore4,
|
||||||
&DOptStore5,
|
&DOptStore5,
|
||||||
&DOptStoreLoad,
|
&DOptStoreLoad,
|
||||||
&DOptLoadStoreLoad,
|
|
||||||
&DOptSub1,
|
&DOptSub1,
|
||||||
&DOptSub2,
|
&DOptSub2,
|
||||||
&DOptSub3,
|
&DOptSub3,
|
||||||
@@ -330,6 +335,7 @@ static OptFunc* OptFuncs[] = {
|
|||||||
&DOptTransfers4,
|
&DOptTransfers4,
|
||||||
&DOptUnusedLoads,
|
&DOptUnusedLoads,
|
||||||
&DOptUnusedStores,
|
&DOptUnusedStores,
|
||||||
|
/* END SORTED_CODEOPT.SH */
|
||||||
};
|
};
|
||||||
#define OPTFUNC_COUNT (sizeof(OptFuncs) / sizeof(OptFuncs[0]))
|
#define OPTFUNC_COUNT (sizeof(OptFuncs) / sizeof(OptFuncs[0]))
|
||||||
|
|
||||||
|
|||||||
@@ -1225,6 +1225,12 @@ static int CmpHarmless (const void* Key, const void* Entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
|
static const char* const Tab[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
|
"_abs",
|
||||||
|
/* END SORTED.SH */
|
||||||
|
};
|
||||||
|
|
||||||
int HarmlessCall (const CodeEntry* E, int PushedBytes)
|
int HarmlessCall (const CodeEntry* E, int PushedBytes)
|
||||||
/* Check if this is a call to a harmless subroutine that will not interrupt
|
/* Check if this is a call to a harmless subroutine that will not interrupt
|
||||||
@@ -1252,10 +1258,6 @@ int HarmlessCall (const CodeEntry* E, int PushedBytes)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
static const char* const Tab[] = {
|
|
||||||
"_abs",
|
|
||||||
};
|
|
||||||
|
|
||||||
void* R = bsearch (E->Arg,
|
void* R = bsearch (E->Arg,
|
||||||
Tab,
|
Tab,
|
||||||
sizeof (Tab) / sizeof (Tab[0]),
|
sizeof (Tab) / sizeof (Tab[0]),
|
||||||
|
|||||||
@@ -496,6 +496,14 @@ void Compile (const char* FileName)
|
|||||||
while (PreprocessNextLine ())
|
while (PreprocessNextLine ())
|
||||||
{ /* Nothing */ }
|
{ /* Nothing */ }
|
||||||
|
|
||||||
|
/* Output macros if requested by the user */
|
||||||
|
if (DumpPredefMacros) {
|
||||||
|
OutputPredefMacros ();
|
||||||
|
}
|
||||||
|
if (DumpUserMacros) {
|
||||||
|
OutputUserMacros ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Close the output file */
|
/* Close the output file */
|
||||||
CloseOutputFile ();
|
CloseOutputFile ();
|
||||||
|
|
||||||
|
|||||||
@@ -1464,7 +1464,9 @@ static unsigned Opt_a_tosxor (StackOpData* D)
|
|||||||
|
|
||||||
/* The first column of these two tables must be sorted in lexical order */
|
/* The first column of these two tables must be sorted in lexical order */
|
||||||
|
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
static const OptFuncDesc FuncTable[] = {
|
static const OptFuncDesc FuncTable[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "___bzero", Opt___bzero, REG_NONE, OP_X_ZERO | OP_A_KNOWN },
|
{ "___bzero", Opt___bzero, REG_NONE, OP_X_ZERO | OP_A_KNOWN },
|
||||||
{ "staspidx", Opt_staspidx, REG_NONE, OP_NONE },
|
{ "staspidx", Opt_staspidx, REG_NONE, OP_NONE },
|
||||||
{ "staxspidx", Opt_staxspidx, REG_AX, OP_NONE },
|
{ "staxspidx", Opt_staxspidx, REG_AX, OP_NONE },
|
||||||
@@ -1485,9 +1487,12 @@ static const OptFuncDesc FuncTable[] = {
|
|||||||
{ "tosuleax", Opt_tosuleax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
{ "tosuleax", Opt_tosuleax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
||||||
{ "tosultax", Opt_tosultax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
{ "tosultax", Opt_tosultax, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
||||||
{ "tosxorax", Opt_tosxorax, REG_NONE, OP_NONE },
|
{ "tosxorax", Opt_tosxorax, REG_NONE, OP_NONE },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
static const OptFuncDesc FuncRegATable[] = {
|
static const OptFuncDesc FuncRegATable[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "tosandax", Opt_a_tosand, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
{ "tosandax", Opt_a_tosand, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
||||||
{ "toseqax", Opt_a_toseq, REG_NONE, OP_NONE },
|
{ "toseqax", Opt_a_toseq, REG_NONE, OP_NONE },
|
||||||
{ "tosgeax", Opt_a_tosuge, REG_NONE, OP_NONE },
|
{ "tosgeax", Opt_a_tosuge, REG_NONE, OP_NONE },
|
||||||
@@ -1503,6 +1508,7 @@ static const OptFuncDesc FuncRegATable[] = {
|
|||||||
{ "tosuleax", Opt_a_tosule, REG_NONE, OP_NONE },
|
{ "tosuleax", Opt_a_tosule, REG_NONE, OP_NONE },
|
||||||
{ "tosultax", Opt_a_tosult, REG_NONE, OP_NONE },
|
{ "tosultax", Opt_a_tosult, REG_NONE, OP_NONE },
|
||||||
{ "tosxorax", Opt_a_tosxor, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
{ "tosxorax", Opt_a_tosxor, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FUNC_COUNT(Table) (sizeof(Table) / sizeof(Table[0]))
|
#define FUNC_COUNT(Table) (sizeof(Table) / sizeof(Table[0]))
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "coll.h"
|
#include "coll.h"
|
||||||
|
#include "debugflag.h"
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "strbuf.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 */
|
/* Print a message about a fatal error and die */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (Debug) {
|
||||||
|
fprintf(stderr, "[%s:%d] ", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
fprintf (stderr, "%s:%u: Fatal: ", GetDiagnosticFileName (), GetDiagnosticLineNum ());
|
fprintf (stderr, "%s:%u: Fatal: ", GetDiagnosticFileName (), GetDiagnosticLineNum ());
|
||||||
|
|
||||||
va_start (ap, Format);
|
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 */
|
/* Print a message about an internal compiler error and die */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (Debug) {
|
||||||
|
fprintf(stderr, "[%s:%d] ", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
fprintf (stderr, "%s:%u: Internal compiler error:\n",
|
fprintf (stderr, "%s:%u: Internal compiler error:\n",
|
||||||
GetDiagnosticFileName (), GetDiagnosticLineNum ());
|
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 */
|
/* Print an error message with the line info given explicitly */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (Debug) {
|
||||||
|
fprintf(stderr, "[%s:%d] ", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntError (EC, LI, Format, ap);
|
IntError (EC, LI, Format, ap);
|
||||||
va_end (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 */
|
/* Print an error message */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (Debug) {
|
||||||
|
fprintf(stderr, "[%s:%d] ", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntError (EC_PARSER, GetDiagnosticLI (), Format, ap);
|
IntError (EC_PARSER, GetDiagnosticLI (), Format, ap);
|
||||||
va_end (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 */
|
/* Print an error message. For use within the preprocessor */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (Debug) {
|
||||||
|
fprintf(stderr, "[%s:%d] ", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntError (EC_PP, GetCurLineInfo (), Format, ap);
|
IntError (EC_PP, GetCurLineInfo (), Format, ap);
|
||||||
va_end (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 */
|
/* Print a warning message with the line info given explicitly */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (Debug) {
|
||||||
|
fprintf(stderr, "[%s:%d] ", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntWarning (EC, LI, Format, ap);
|
IntWarning (EC, LI, Format, ap);
|
||||||
va_end (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 */
|
/* Print a warning message */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (Debug) {
|
||||||
|
fprintf(stderr, "[%s:%d] ", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntWarning (EC_PARSER, GetDiagnosticLI (), Format, ap);
|
IntWarning (EC_PARSER, GetDiagnosticLI (), Format, ap);
|
||||||
va_end (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 */
|
/* Print a warning message. For use within the preprocessor */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (Debug) {
|
||||||
|
fprintf(stderr, "[%s:%d] ", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntWarning (EC_PP, GetCurLineInfo (), Format, ap);
|
IntWarning (EC_PP, GetCurLineInfo (), Format, ap);
|
||||||
va_end (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 */
|
/* Print a note message with the line info given explicitly */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (Debug) {
|
||||||
|
fprintf(stderr, "[%s:%d] ", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntNote (LI, Format, ap);
|
IntNote (LI, Format, ap);
|
||||||
va_end (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 */
|
/* Print a note message */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (Debug) {
|
||||||
|
fprintf(stderr, "[%s:%d] ", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntNote (GetDiagnosticLI (), Format, ap);
|
IntNote (GetDiagnosticLI (), Format, ap);
|
||||||
va_end (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 */
|
/* Print a note message. For use within the preprocessor */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (Debug) {
|
||||||
|
fprintf(stderr, "[%s:%d] ", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
IntNote (GetDiagnosticLI (), Format, ap);
|
IntNote (GetDiagnosticLI (), Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|||||||
@@ -103,28 +103,36 @@ struct StrBuf;
|
|||||||
void PrintFileInclusionInfo (const LineInfo* LI);
|
void PrintFileInclusionInfo (const LineInfo* LI);
|
||||||
/* Print hierarchy of file inclusion */
|
/* 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 */
|
/* 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 */
|
/* 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 */
|
/* 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 */
|
/* 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 */
|
/* 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 */
|
/* 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 */
|
/* 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 */
|
/* Print a warning message. For use within the preprocessor */
|
||||||
|
|
||||||
void UnreachableCodeWarning (void);
|
void UnreachableCodeWarning (void);
|
||||||
@@ -140,13 +148,16 @@ IntStack* FindWarning (const char* Name);
|
|||||||
void ListWarnings (FILE* F);
|
void ListWarnings (FILE* F);
|
||||||
/* Print a list of warning types/names to the given file */
|
/* 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 */
|
/* 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 */
|
/* 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 */
|
/* Print a note message. For use within the preprocessor */
|
||||||
|
|
||||||
unsigned GetTotalErrors (void);
|
unsigned GetTotalErrors (void);
|
||||||
|
|||||||
@@ -44,12 +44,14 @@
|
|||||||
|
|
||||||
|
|
||||||
unsigned char AddSource = 0; /* Add source lines as comments */
|
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 AutoCDecl = 0; /* Make functions default to __cdecl__ */
|
||||||
unsigned char DebugInfo = 0; /* Add debug info to the obj */
|
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 PreprocessOnly = 0; /* Just preprocess the input */
|
||||||
unsigned char DebugOptOutput = 0; /* Output debug stuff */
|
unsigned char DebugOptOutput = 0; /* Output debug stuff */
|
||||||
unsigned RegisterSpace = 6; /* Space available for register vars */
|
unsigned RegisterSpace = 6; /* Space available for register vars */
|
||||||
unsigned AllowNewComments = 0; /* Allow new style comments in C89 mode */
|
|
||||||
|
|
||||||
/* Stackable options */
|
/* Stackable options */
|
||||||
IntStack WritableStrings = INTSTACK(0); /* Literal strings are r/w */
|
IntStack WritableStrings = INTSTACK(0); /* Literal strings are r/w */
|
||||||
|
|||||||
@@ -52,12 +52,14 @@
|
|||||||
|
|
||||||
/* Options */
|
/* Options */
|
||||||
extern unsigned char AddSource; /* Add source lines as comments */
|
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 AutoCDecl; /* Make functions default to __cdecl__ */
|
||||||
extern unsigned char DebugInfo; /* Add debug info to the obj */
|
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 PreprocessOnly; /* Just preprocess the input */
|
||||||
extern unsigned char DebugOptOutput; /* Output debug stuff */
|
extern unsigned char DebugOptOutput; /* Output debug stuff */
|
||||||
extern unsigned RegisterSpace; /* Space available for register vars */
|
extern unsigned RegisterSpace; /* Space available for register vars */
|
||||||
extern unsigned AllowNewComments; /* Allow new style comments in C89 mode */
|
|
||||||
|
|
||||||
/* Stackable options */
|
/* Stackable options */
|
||||||
extern IntStack WritableStrings; /* Literal strings are r/w */
|
extern IntStack WritableStrings; /* Literal strings are r/w */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*****************************************************************************/
|
|
||||||
/* */
|
/* */
|
||||||
/* macrotab.h */
|
/* macrotab.h */
|
||||||
/* */
|
/* */
|
||||||
@@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
/* cc65 */
|
/* cc65 */
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "output.h"
|
||||||
#include "preproc.h"
|
#include "preproc.h"
|
||||||
#include "macrotab.h"
|
#include "macrotab.h"
|
||||||
|
|
||||||
@@ -60,6 +61,70 @@ static Macro* MacroTab[MACRO_TAB_SIZE];
|
|||||||
/* The undefined macros list head */
|
/* The undefined macros list head */
|
||||||
static Macro* UndefinedMacrosListHead;
|
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
|
/* Allocate a macro structure with the given name. The structure is not
|
||||||
** inserted into the macro table.
|
** inserted into the macro table.
|
||||||
*/
|
*/
|
||||||
@@ -84,6 +149,7 @@ Macro* NewMacro (const char* Name)
|
|||||||
M->ParamCount = -1; /* Flag: Not a function-like macro */
|
M->ParamCount = -1; /* Flag: Not a function-like macro */
|
||||||
InitCollection (&M->Params);
|
InitCollection (&M->Params);
|
||||||
SB_Init (&M->Replacement);
|
SB_Init (&M->Replacement);
|
||||||
|
M->Predefined = Predefined;
|
||||||
M->Variadic = 0;
|
M->Variadic = 0;
|
||||||
memcpy (M->Name, Name, Len+1);
|
memcpy (M->Name, Name, Len+1);
|
||||||
|
|
||||||
@@ -116,7 +182,7 @@ Macro* CloneMacro (const Macro* M)
|
|||||||
** Use FreeMacro for that.
|
** Use FreeMacro for that.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
Macro* New = NewMacro (M->Name);
|
Macro* New = NewMacro (M->Name, M->Predefined);
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
for (I = 0; I < CollCount (&M->Params); ++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)
|
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];
|
char Buf[64];
|
||||||
|
|
||||||
@@ -148,10 +214,10 @@ void DefineNumericMacro (const char* Name, long Val)
|
|||||||
|
|
||||||
|
|
||||||
void DefineTextMacro (const char* Name, const char* 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 */
|
/* Create a new macro */
|
||||||
Macro* M = NewMacro (Name);
|
Macro* M = NewMacro (Name, 1);
|
||||||
|
|
||||||
/* Set the value as replacement text */
|
/* Set the value as replacement text */
|
||||||
SB_CopyStr (&M->Replacement, Val);
|
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 */
|
int ParamCount; /* Number of parameters, -1 = no parens */
|
||||||
Collection Params; /* Parameter list (char*) */
|
Collection Params; /* Parameter list (char*) */
|
||||||
StrBuf Replacement; /* Replacement text */
|
StrBuf Replacement; /* Replacement text */
|
||||||
|
unsigned char Predefined; /* True if this is a predefined macro */
|
||||||
unsigned char Variadic; /* C99 variadic macro */
|
unsigned char Variadic; /* C99 variadic macro */
|
||||||
char Name[1]; /* Name, dynamically allocated */
|
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
|
/* Allocate a macro structure with the given name. The structure is not
|
||||||
** inserted into the macro table.
|
** inserted into the macro table.
|
||||||
*/
|
*/
|
||||||
@@ -87,10 +88,10 @@ Macro* CloneMacro (const Macro* M);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void DefineNumericMacro (const char* Name, long Val);
|
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);
|
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);
|
void InsertMacro (Macro* M);
|
||||||
/* Insert the given macro into the macro table. */
|
/* Insert the given macro into the macro table. */
|
||||||
@@ -132,6 +133,12 @@ int MacroCmp (const Macro* M1, const Macro* M2);
|
|||||||
void PrintMacroStats (FILE* F);
|
void PrintMacroStats (FILE* F);
|
||||||
/* Print macro statistics to the given text file. */
|
/* 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 */
|
/* End of macrotab.h */
|
||||||
|
|||||||
115
src/cc65/main.c
115
src/cc65/main.c
@@ -93,6 +93,8 @@ static void Usage (void)
|
|||||||
" -V\t\t\t\tPrint the compiler version number\n"
|
" -V\t\t\t\tPrint the compiler version number\n"
|
||||||
" -W [-+]warning[,...]\t\tControl warnings ('-' disables, '+' enables)\n"
|
" -W [-+]warning[,...]\t\tControl warnings ('-' disables, '+' enables)\n"
|
||||||
" -d\t\t\t\tDebug mode\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"
|
" -g\t\t\t\tAdd debug info to object file\n"
|
||||||
" -h\t\t\t\tHelp (this text)\n"
|
" -h\t\t\t\tHelp (this text)\n"
|
||||||
" -j\t\t\t\tDefault characters are signed\n"
|
" -j\t\t\t\tDefault characters are signed\n"
|
||||||
@@ -307,6 +309,10 @@ static void SetSys (const char* Sys)
|
|||||||
DefineNumericMacro ("__RP6502__", 1);
|
DefineNumericMacro ("__RP6502__", 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TGT_AGAT:
|
||||||
|
DefineNumericMacro ("__AGAT__", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
AbEnd ("Unknown target system '%s'", Sys);
|
AbEnd ("Unknown target system '%s'", Sys);
|
||||||
}
|
}
|
||||||
@@ -317,6 +323,81 @@ static void SetSys (const char* Sys)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void DefineCpuMacros (void)
|
||||||
|
/* Define macros for the target CPU */
|
||||||
|
{
|
||||||
|
const char* CPUName;
|
||||||
|
|
||||||
|
/* Note: The list of CPUs handled here must match the one checked in
|
||||||
|
** OptCPU().
|
||||||
|
*/
|
||||||
|
switch (CPU) {
|
||||||
|
|
||||||
|
/* The following ones are legal CPUs as far as the assembler is
|
||||||
|
** concerned but are ruled out earlier in the compiler, so this
|
||||||
|
** function should never see them.
|
||||||
|
*/
|
||||||
|
case CPU_NONE:
|
||||||
|
case CPU_SWEET16:
|
||||||
|
case CPU_M740:
|
||||||
|
case CPU_4510:
|
||||||
|
case CPU_UNKNOWN:
|
||||||
|
CPUName = (CPU == CPU_UNKNOWN)? "unknown" : CPUNames[CPU];
|
||||||
|
Internal ("Invalid CPU \"%s\"", CPUName);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPU_6502:
|
||||||
|
DefineNumericMacro ("__CPU_6502__", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPU_6502X:
|
||||||
|
DefineNumericMacro ("__CPU_6502X__", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPU_6502DTV:
|
||||||
|
DefineNumericMacro ("__CPU_6502DTV__", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPU_65SC02:
|
||||||
|
DefineNumericMacro ("__CPU_65SC02__", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPU_65C02:
|
||||||
|
DefineNumericMacro ("__CPU_65C02__", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPU_65816:
|
||||||
|
DefineNumericMacro ("__CPU_65816__", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPU_HUC6280:
|
||||||
|
DefineNumericMacro ("__CPU_HUC6280__", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FAIL ("Unexpected value in switch");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define the macros for instruction sets. We only include the ones for
|
||||||
|
** the available CPUs.
|
||||||
|
*/
|
||||||
|
DefineNumericMacro ("__CPU_ISET_6502__", CPU_ISET_6502);
|
||||||
|
DefineNumericMacro ("__CPU_ISET_6502X__", CPU_ISET_6502X);
|
||||||
|
DefineNumericMacro ("__CPU_ISET_6502DTV__", CPU_ISET_6502DTV);
|
||||||
|
DefineNumericMacro ("__CPU_ISET_65SC02__", CPU_ISET_65SC02);
|
||||||
|
DefineNumericMacro ("__CPU_ISET_65C02__", CPU_ISET_65C02);
|
||||||
|
DefineNumericMacro ("__CPU_ISET_65816__", CPU_ISET_65816);
|
||||||
|
DefineNumericMacro ("__CPU_ISET_HUC6280__", CPU_ISET_HUC6280);
|
||||||
|
|
||||||
|
/* Now define the macro that contains the bit set with the available
|
||||||
|
** cpu instructions.
|
||||||
|
*/
|
||||||
|
DefineNumericMacro ("__CPU__", CPUIsets[CPU]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void FileNameOption (const char* Opt, const char* Arg, StrBuf* Name)
|
static void FileNameOption (const char* Opt, const char* Arg, StrBuf* Name)
|
||||||
/* Handle an option that remembers a file name for later */
|
/* Handle an option that remembers a file name for later */
|
||||||
{
|
{
|
||||||
@@ -477,7 +558,9 @@ static void OptCreateFullDep (const char* Opt attribute ((unused)),
|
|||||||
static void OptCPU (const char* Opt, const char* Arg)
|
static void OptCPU (const char* Opt, const char* Arg)
|
||||||
/* Handle the --cpu option */
|
/* Handle the --cpu option */
|
||||||
{
|
{
|
||||||
/* Find the CPU from the given name */
|
/* Find the CPU from the given name. We do only accept a certain number
|
||||||
|
** of CPUs. If the list is changed, be sure to adjust SetCpuMacros().
|
||||||
|
*/
|
||||||
CPU = FindCPU (Arg);
|
CPU = FindCPU (Arg);
|
||||||
if (CPU != CPU_6502 && CPU != CPU_6502X && CPU != CPU_65SC02 &&
|
if (CPU != CPU_6502 && CPU != CPU_6502X && CPU != CPU_65SC02 &&
|
||||||
CPU != CPU_65C02 && CPU != CPU_65816 && CPU != CPU_HUC6280 &&
|
CPU != CPU_65C02 && CPU != CPU_65816 && CPU != CPU_HUC6280 &&
|
||||||
@@ -945,7 +1028,25 @@ int main (int argc, char* argv[])
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
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;
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
@@ -1057,13 +1158,20 @@ int main (int argc, char* argv[])
|
|||||||
AbEnd ("No input files");
|
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. */
|
/* Add the default include search paths. */
|
||||||
FinishIncludePaths ();
|
FinishIncludePaths ();
|
||||||
|
|
||||||
/* Create the output file name if it was not explicitly given */
|
/* Create the output file name if it was not explicitly given */
|
||||||
MakeDefaultOutputName (InputFile);
|
MakeDefaultOutputName (InputFile);
|
||||||
|
|
||||||
/* If no CPU given, use the default CPU for the target */
|
/* If no CPU given, use the default CPU for the target. Define macros that
|
||||||
|
** allow to query the CPU.
|
||||||
|
*/
|
||||||
if (CPU == CPU_UNKNOWN) {
|
if (CPU == CPU_UNKNOWN) {
|
||||||
if (Target != TGT_UNKNOWN) {
|
if (Target != TGT_UNKNOWN) {
|
||||||
CPU = GetTargetProperties (Target)->DefaultCPU;
|
CPU = GetTargetProperties (Target)->DefaultCPU;
|
||||||
@@ -1071,6 +1179,7 @@ int main (int argc, char* argv[])
|
|||||||
CPU = CPU_6502;
|
CPU = CPU_6502;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DefineCpuMacros ();
|
||||||
|
|
||||||
/* If no memory model was given, use the default */
|
/* If no memory model was given, use the default */
|
||||||
if (MemoryModel == MMODEL_UNKNOWN) {
|
if (MemoryModel == MMODEL_UNKNOWN) {
|
||||||
|
|||||||
@@ -55,9 +55,12 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Opcode description table */
|
/* Opcode description table */
|
||||||
|
/* CAUTION: table must be sorted by mnemonic for bsearch */
|
||||||
const OPCDesc OPCTable[OP65_COUNT] = {
|
const OPCDesc OPCTable[OP65_COUNT] = {
|
||||||
|
|
||||||
/* 65XX opcodes */
|
/* 65XX opcodes */
|
||||||
|
|
||||||
|
/* BEGIN SORTED_OPCODES.SH */
|
||||||
{ OP65_ADC, /* opcode */
|
{ OP65_ADC, /* opcode */
|
||||||
"adc", /* mnemonic */
|
"adc", /* mnemonic */
|
||||||
0, /* size */
|
0, /* size */
|
||||||
@@ -586,6 +589,7 @@ const OPCDesc OPCTable[OP65_COUNT] = {
|
|||||||
REG_Y, /* use */
|
REG_Y, /* use */
|
||||||
REG_A | PSTATE_ZN /* chg */
|
REG_A | PSTATE_ZN /* chg */
|
||||||
},
|
},
|
||||||
|
/* END SORTED_OPCODES.SH */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -89,10 +89,12 @@ typedef enum {
|
|||||||
} pragma_t;
|
} pragma_t;
|
||||||
|
|
||||||
/* Pragma table */
|
/* Pragma table */
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
static const struct Pragma {
|
static const struct Pragma {
|
||||||
const char* Key; /* Keyword */
|
const char* Key; /* Keyword */
|
||||||
pragma_t Tok; /* Token */
|
pragma_t Tok; /* Token */
|
||||||
} Pragmas[] = {
|
} Pragmas[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "align", PRAGMA_ALIGN },
|
{ "align", PRAGMA_ALIGN },
|
||||||
{ "allow-eager-inline", PRAGMA_ALLOW_EAGER_INLINE },
|
{ "allow-eager-inline", PRAGMA_ALLOW_EAGER_INLINE },
|
||||||
{ "allow_eager_inline", PRAGMA_ALLOW_EAGER_INLINE },
|
{ "allow_eager_inline", PRAGMA_ALLOW_EAGER_INLINE },
|
||||||
@@ -127,6 +129,7 @@ static const struct Pragma {
|
|||||||
{ "writable-strings", PRAGMA_WRITABLE_STRINGS },
|
{ "writable-strings", PRAGMA_WRITABLE_STRINGS },
|
||||||
{ "writable_strings", PRAGMA_WRITABLE_STRINGS },
|
{ "writable_strings", PRAGMA_WRITABLE_STRINGS },
|
||||||
{ "zpsym", PRAGMA_ZPSYM },
|
{ "zpsym", PRAGMA_ZPSYM },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
#define PRAGMA_COUNT (sizeof (Pragmas) / sizeof (Pragmas[0]))
|
#define PRAGMA_COUNT (sizeof (Pragmas) / sizeof (Pragmas[0]))
|
||||||
|
|
||||||
@@ -433,12 +436,7 @@ static void ApplySegNamePragma (pragma_t Token, int PushPop, const char* Name, u
|
|||||||
SetSegAddrSize (Name, AddrSize);
|
SetSegAddrSize (Name, AddrSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BSS variables are output at the end of the compilation. Don't
|
g_segname (Seg);
|
||||||
** bother to change their segment, now.
|
|
||||||
*/
|
|
||||||
if (Seg != SEG_BSS) {
|
|
||||||
g_segname (Seg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -216,10 +216,12 @@ typedef enum {
|
|||||||
|
|
||||||
|
|
||||||
/* Preprocessor directive tokens mapping table */
|
/* Preprocessor directive tokens mapping table */
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
static const struct PPDType {
|
static const struct PPDType {
|
||||||
const char* Tok; /* Token */
|
const char* Tok; /* Token */
|
||||||
ppdirective_t Type; /* Type */
|
ppdirective_t Type; /* Type */
|
||||||
} PPDTypes[] = {
|
} PPDTypes[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "define", PPD_DEFINE },
|
{ "define", PPD_DEFINE },
|
||||||
{ "elif", PPD_ELIF },
|
{ "elif", PPD_ELIF },
|
||||||
{ "else", PPD_ELSE },
|
{ "else", PPD_ELSE },
|
||||||
@@ -233,6 +235,7 @@ static const struct PPDType {
|
|||||||
{ "pragma", PPD_PRAGMA },
|
{ "pragma", PPD_PRAGMA },
|
||||||
{ "undef", PPD_UNDEF },
|
{ "undef", PPD_UNDEF },
|
||||||
{ "warning", PPD_WARNING },
|
{ "warning", PPD_WARNING },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Number of preprocessor directive types */
|
/* Number of preprocessor directive types */
|
||||||
@@ -2572,7 +2575,7 @@ static void DoDefine (void)
|
|||||||
CheckForBadIdent (Ident, Std, 0);
|
CheckForBadIdent (Ident, Std, 0);
|
||||||
|
|
||||||
/* Create a new macro definition */
|
/* Create a new macro definition */
|
||||||
M = NewMacro (Ident);
|
M = NewMacro (Ident, 0);
|
||||||
|
|
||||||
/* Check if this is a function-like macro */
|
/* Check if this is a function-like macro */
|
||||||
if (CurC == '(') {
|
if (CurC == '(') {
|
||||||
|
|||||||
@@ -87,11 +87,13 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Token table */
|
/* Token table */
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
static const struct Keyword {
|
static const struct Keyword {
|
||||||
char* Key; /* Keyword name */
|
char* Key; /* Keyword name */
|
||||||
unsigned char Tok; /* The token */
|
unsigned char Tok; /* The token */
|
||||||
unsigned char Std; /* Token supported in which standards? */
|
unsigned char Std; /* Token supported in which standards? */
|
||||||
} Keywords [] = {
|
} Keywords [] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "_Pragma", TOK_PRAGMA, TT_C89 | TT_C99 | TT_CC65 }, /* !! */
|
{ "_Pragma", TOK_PRAGMA, TT_C89 | TT_C99 | TT_CC65 }, /* !! */
|
||||||
{ "_Static_assert", TOK_STATIC_ASSERT, TT_CC65 }, /* C11 */
|
{ "_Static_assert", TOK_STATIC_ASSERT, TT_CC65 }, /* C11 */
|
||||||
{ "__AX__", TOK_AX, TT_C89 | TT_C99 | TT_CC65 },
|
{ "__AX__", TOK_AX, TT_C89 | TT_C99 | TT_CC65 },
|
||||||
@@ -145,6 +147,7 @@ static const struct Keyword {
|
|||||||
{ "void", TOK_VOID, TT_C89 | TT_C99 | TT_CC65 },
|
{ "void", TOK_VOID, TT_C89 | TT_C99 | TT_CC65 },
|
||||||
{ "volatile", TOK_VOLATILE, TT_C89 | TT_C99 | TT_CC65 },
|
{ "volatile", TOK_VOLATILE, TT_C89 | TT_C99 | TT_CC65 },
|
||||||
{ "while", TOK_WHILE, TT_C89 | TT_C99 | TT_CC65 },
|
{ "while", TOK_WHILE, TT_C89 | TT_C99 | TT_CC65 },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
#define KEY_COUNT (sizeof (Keywords) / sizeof (Keywords [0]))
|
#define KEY_COUNT (sizeof (Keywords) / sizeof (Keywords [0]))
|
||||||
|
|
||||||
|
|||||||
@@ -78,19 +78,20 @@ static void StdFunc_strlen (FuncDesc*, ExprDesc*);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Table with all known functions and their handlers. Must be sorted
|
/* Table with all known functions and their handlers.
|
||||||
** alphabetically!
|
** CAUTION: table must be alphabetically sorted for bsearch
|
||||||
*/
|
*/
|
||||||
static struct StdFuncDesc {
|
static struct StdFuncDesc {
|
||||||
const char* Name;
|
const char* Name;
|
||||||
void (*Handler) (FuncDesc*, ExprDesc*);
|
void (*Handler) (FuncDesc*, ExprDesc*);
|
||||||
} StdFuncs[] = {
|
} StdFuncs[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "memcpy", StdFunc_memcpy },
|
{ "memcpy", StdFunc_memcpy },
|
||||||
{ "memset", StdFunc_memset },
|
{ "memset", StdFunc_memset },
|
||||||
{ "strcmp", StdFunc_strcmp },
|
{ "strcmp", StdFunc_strcmp },
|
||||||
{ "strcpy", StdFunc_strcpy },
|
{ "strcpy", StdFunc_strcpy },
|
||||||
{ "strlen", StdFunc_strlen },
|
{ "strlen", StdFunc_strlen },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
#define FUNC_COUNT (sizeof (StdFuncs) / sizeof (StdFuncs[0]))
|
#define FUNC_COUNT (sizeof (StdFuncs) / sizeof (StdFuncs[0]))
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,11 @@ static int DoAssemble = 1;
|
|||||||
/* The name of the output file, NULL if none given */
|
/* The name of the output file, NULL if none given */
|
||||||
static const char* OutputName = 0;
|
static const char* OutputName = 0;
|
||||||
|
|
||||||
|
/* The path part of the output file, NULL if none given
|
||||||
|
** or the OutputName is just a filename with no path
|
||||||
|
** information. */
|
||||||
|
static char *OutputDirectory = 0;
|
||||||
|
|
||||||
/* The name of the linker configuration file if given */
|
/* The name of the linker configuration file if given */
|
||||||
static const char* LinkerConfig = 0;
|
static const char* LinkerConfig = 0;
|
||||||
|
|
||||||
@@ -555,7 +560,7 @@ static void AssembleFile (const char* File, const char* TmpFile, unsigned ArgCou
|
|||||||
if (TmpFile) {
|
if (TmpFile) {
|
||||||
ObjName = MakeFilename (TmpFile, ".o");
|
ObjName = MakeFilename (TmpFile, ".o");
|
||||||
} else {
|
} else {
|
||||||
ObjName = MakeTmpFilename (".o");
|
ObjName = MakeTmpFilename (OutputDirectory, File, ".o");
|
||||||
}
|
}
|
||||||
CmdSetOutput (&CA65, ObjName);
|
CmdSetOutput (&CA65, ObjName);
|
||||||
CmdAddFile (&LD65, ObjName);
|
CmdAddFile (&LD65, ObjName);
|
||||||
@@ -684,7 +689,7 @@ static void Compile (const char* File)
|
|||||||
|
|
||||||
if (DoAssemble) {
|
if (DoAssemble) {
|
||||||
/* set a temporary output file name */
|
/* set a temporary output file name */
|
||||||
TmpFile = MakeTmpFilename(".s");
|
TmpFile = MakeTmpFilename(OutputDirectory, File, ".s");
|
||||||
CmdSetOutput (&CC65, TmpFile);
|
CmdSetOutput (&CC65, TmpFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,7 +734,7 @@ static void CompileRes (const char* File)
|
|||||||
** BEFORE adding the file
|
** BEFORE adding the file
|
||||||
*/
|
*/
|
||||||
if (DoAssemble && DoLink) {
|
if (DoAssemble && DoLink) {
|
||||||
AsmName = MakeTmpFilename(".s");
|
AsmName = MakeTmpFilename(OutputDirectory, File, ".s");
|
||||||
CmdSetAsmOutput(&GRC, AsmName);
|
CmdSetAsmOutput(&GRC, AsmName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1623,6 +1628,7 @@ int main (int argc, char* argv [])
|
|||||||
case 'o':
|
case 'o':
|
||||||
/* Name the output file */
|
/* Name the output file */
|
||||||
OutputName = GetArg (&I, 2);
|
OutputName = GetArg (&I, 2);
|
||||||
|
OutputDirectory = GetFileDirectory(OutputName);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
@@ -1713,6 +1719,9 @@ int main (int argc, char* argv [])
|
|||||||
}
|
}
|
||||||
|
|
||||||
RemoveTempFiles ();
|
RemoveTempFiles ();
|
||||||
|
if (OutputDirectory != NULL) {
|
||||||
|
xfree(OutputDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return an apropriate exit code */
|
/* Return an apropriate exit code */
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
@@ -48,8 +48,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
static const FileId TypeTable[] = {
|
static const FileId TypeTable[] = {
|
||||||
/* Upper case stuff for obsolete operating systems */
|
/* Upper case stuff for obsolete operating systems */
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "A", FILETYPE_LIB },
|
{ "A", FILETYPE_LIB },
|
||||||
{ "A65", FILETYPE_ASM },
|
{ "A65", FILETYPE_ASM },
|
||||||
{ "ASM", FILETYPE_ASM },
|
{ "ASM", FILETYPE_ASM },
|
||||||
@@ -65,7 +67,6 @@ static const FileId TypeTable[] = {
|
|||||||
{ "S", FILETYPE_ASM },
|
{ "S", FILETYPE_ASM },
|
||||||
{ "SER", FILETYPE_O65 },
|
{ "SER", FILETYPE_O65 },
|
||||||
{ "TGI", FILETYPE_O65 },
|
{ "TGI", FILETYPE_O65 },
|
||||||
|
|
||||||
{ "a", FILETYPE_LIB },
|
{ "a", FILETYPE_LIB },
|
||||||
{ "a65", FILETYPE_ASM },
|
{ "a65", FILETYPE_ASM },
|
||||||
{ "asm", FILETYPE_ASM },
|
{ "asm", FILETYPE_ASM },
|
||||||
@@ -81,6 +82,7 @@ static const FileId TypeTable[] = {
|
|||||||
{ "s", FILETYPE_ASM },
|
{ "s", FILETYPE_ASM },
|
||||||
{ "ser", FILETYPE_O65 },
|
{ "ser", FILETYPE_O65 },
|
||||||
{ "tgi", FILETYPE_O65 },
|
{ "tgi", FILETYPE_O65 },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FILETYPE_COUNT (sizeof (TypeTable) / sizeof (TypeTable[0]))
|
#define FILETYPE_COUNT (sizeof (TypeTable) / sizeof (TypeTable[0]))
|
||||||
|
|||||||
@@ -33,8 +33,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# include <process.h>
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
#include "fname.h"
|
#include "fname.h"
|
||||||
@@ -93,7 +102,28 @@ const char* FindName (const char* Path)
|
|||||||
return Path + Len;
|
return Path + Len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *GetFileDirectory (const char* File)
|
||||||
|
/* Return a copy of the path part of a File, or NULL if there is none. */
|
||||||
|
{
|
||||||
|
char *Out, *P;
|
||||||
|
|
||||||
|
if (File == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Out = xmalloc (strlen (File) + 1);
|
||||||
|
strcpy(Out, File);
|
||||||
|
|
||||||
|
P = (char *)FindName (Out);
|
||||||
|
if (P == Out) {
|
||||||
|
/* This is a simple filename. */
|
||||||
|
xfree (Out);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*P = '\0';
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
char* MakeFilename (const char* Origin, const char* Ext)
|
char* MakeFilename (const char* Origin, const char* Ext)
|
||||||
/* Make a new file name from Origin and Ext. If Origin has an extension, it
|
/* Make a new file name from Origin and Ext. If Origin has an extension, it
|
||||||
@@ -119,35 +149,29 @@ char* MakeFilename (const char* Origin, const char* Ext)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
char* MakeTmpFilename (const char* Ext)
|
char* MakeTmpFilename (const char *Directory, const char *Origin, const char* Ext)
|
||||||
/* Make a new temporary file name from Ext. tmpnam(3) is called
|
/* Make a new temporary file name from Origin and Ext.
|
||||||
** and Ext is appended to generate the filename.
|
|
||||||
** The result is placed in a malloc'ed buffer and returned.
|
** The result is placed in a malloc'ed buffer and returned.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
char* Out;
|
char* Out;
|
||||||
char Buffer[L_tmpnam * 2]; /* a lazy way to ensure we have space for Ext */
|
size_t Len = 0;
|
||||||
|
static unsigned int Counter = 0;
|
||||||
|
|
||||||
/*
|
/* Allocate enough for the directory, ... */
|
||||||
** gcc emits the following warning here:
|
if (Directory != NULL) {
|
||||||
**
|
Len = strlen (Directory);
|
||||||
** warning: the use of `tmpnam' is dangerous, better use `mkstemp'
|
}
|
||||||
**
|
|
||||||
** however, mkstemp actually opens a file, which we do not want.
|
|
||||||
** tmpfile() is unsuitable for the same reason.
|
|
||||||
**
|
|
||||||
** we could write our own version, but then we would have to struggle
|
|
||||||
** with supporting multiple build environments.
|
|
||||||
**
|
|
||||||
** tmpnam(3) is safe here, because ca65 / cc65 / ld65 will simply clobber
|
|
||||||
** an existing file, or exit if with an error if they are unable to.
|
|
||||||
**
|
|
||||||
** gcc will also complain, if you don't use the return value from tmpnam(3)
|
|
||||||
*/
|
|
||||||
strcat(tmpnam(Buffer), Ext);
|
|
||||||
|
|
||||||
Out = xmalloc (strlen (Buffer) + 1);
|
/* ... plus the the original name, the maximum length of the PID, the
|
||||||
strcpy (Out, Buffer);
|
* maximum length of the counter, the extension, and the terminator.
|
||||||
|
*/
|
||||||
|
Len += strlen (Origin) + (strlen (".2147483648") * 2) + strlen (Ext) + 1;
|
||||||
|
Out = xmalloc (Len);
|
||||||
|
|
||||||
|
snprintf (Out, Len, "%s%s.%u.%u%s", (Directory != NULL ? Directory : ""),
|
||||||
|
FindName(Origin), getpid(), Counter, Ext);
|
||||||
|
Counter++;
|
||||||
|
|
||||||
return Out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ const char* FindName (const char* Path);
|
|||||||
** the file, the function returns Path as name.
|
** the file, the function returns Path as name.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
char *GetFileDirectory (const char* File);
|
||||||
|
/* Return a copy of the path part of a File, or NULL if there is none. */
|
||||||
|
|
||||||
char* MakeFilename (const char* Origin, const char* Ext);
|
char* MakeFilename (const char* Origin, const char* Ext);
|
||||||
/* Make a new file name from Origin and Ext. If Origin has an extension, it
|
/* Make a new file name from Origin and Ext. If Origin has an extension, it
|
||||||
** is removed and Ext is appended. If Origin has no extension, Ext is simply
|
** is removed and Ext is appended. If Origin has no extension, Ext is simply
|
||||||
@@ -59,9 +62,10 @@ char* MakeFilename (const char* Origin, const char* Ext);
|
|||||||
** The function may be used to create "foo.o" from "foo.s".
|
** The function may be used to create "foo.o" from "foo.s".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char* MakeTmpFilename (const char* Ext);
|
char* MakeTmpFilename (const char *Directory, const char *Origin, const char* Ext);
|
||||||
/* Make a new temporary file name from Ext. tmpnam(3) is called
|
/* Make a new temporary file name from Directory, Origin, and Ext.
|
||||||
** and Ext is appended to generate the filename.
|
** A temporary path is generated from the Directory,
|
||||||
|
** the Origin filename, the compiler's PID and the Extension.
|
||||||
** The result is placed in a malloc'ed buffer and returned.
|
** The result is placed in a malloc'ed buffer and returned.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,25 @@ static const unsigned char CTPET[256] = {
|
|||||||
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
|
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Translation table KOI8-R -> Agat-9 */
|
||||||
|
static unsigned char CTAgat[256] = {
|
||||||
|
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||||
|
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||||
|
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
|
||||||
|
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
|
||||||
|
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
|
||||||
|
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
|
||||||
|
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
|
||||||
|
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0xA0,
|
||||||
|
0x1B,0x5C,0x10,0x12,0x1D,0x1F,0x13,0x1C,0x11,0x1E,0x14,0xA0,0x02,0x5F,0xA0,0xA0,
|
||||||
|
0xA0,0xA0,0xA0,0xA0,0xA0,0x9E,0x04,0xA0,0x3C,0x3E,0xA0,0xA0,0x30,0x32,0xA0,0x2F,
|
||||||
|
0xA0,0xA0,0xA0,0x0F,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
|
||||||
|
0xA0,0xA0,0xA0,0x9F,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,
|
||||||
|
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
|
||||||
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
|
||||||
|
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
|
||||||
|
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
|
||||||
|
};
|
||||||
|
|
||||||
/* One entry in the target map */
|
/* One entry in the target map */
|
||||||
typedef struct TargetEntry TargetEntry;
|
typedef struct TargetEntry TargetEntry;
|
||||||
@@ -138,10 +156,13 @@ struct TargetEntry {
|
|||||||
target_t Id; /* Target ID */
|
target_t Id; /* Target ID */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Table that maps target names to IDs. Sorted alphabetically for bsearch().
|
/* Table that maps target names to IDs.
|
||||||
** Allows multiple entries for one target ID (target name aliases).
|
** Allows multiple entries for one target ID (target name aliases).
|
||||||
|
** CAUTION: must be alphabetically for bsearch().
|
||||||
*/
|
*/
|
||||||
static const TargetEntry TargetMap[] = {
|
static const TargetEntry TargetMap[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
|
{ "agat", TGT_AGAT },
|
||||||
{ "apple2", TGT_APPLE2 },
|
{ "apple2", TGT_APPLE2 },
|
||||||
{ "apple2enh", TGT_APPLE2ENH },
|
{ "apple2enh", TGT_APPLE2ENH },
|
||||||
{ "atari", TGT_ATARI },
|
{ "atari", TGT_ATARI },
|
||||||
@@ -180,6 +201,7 @@ static const TargetEntry TargetMap[] = {
|
|||||||
{ "sym1", TGT_SYM1 },
|
{ "sym1", TGT_SYM1 },
|
||||||
{ "telestrat", TGT_TELESTRAT },
|
{ "telestrat", TGT_TELESTRAT },
|
||||||
{ "vic20", TGT_VIC20 },
|
{ "vic20", TGT_VIC20 },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
#define MAP_ENTRY_COUNT (sizeof (TargetMap) / sizeof (TargetMap[0]))
|
#define MAP_ENTRY_COUNT (sizeof (TargetMap) / sizeof (TargetMap[0]))
|
||||||
|
|
||||||
@@ -223,6 +245,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = {
|
|||||||
{ "sym1", CPU_6502, BINFMT_BINARY, CTNone },
|
{ "sym1", CPU_6502, BINFMT_BINARY, CTNone },
|
||||||
{ "kim1", CPU_6502, BINFMT_BINARY, CTNone },
|
{ "kim1", CPU_6502, BINFMT_BINARY, CTNone },
|
||||||
{ "rp6502", CPU_65C02, BINFMT_BINARY, CTNone },
|
{ "rp6502", CPU_65C02, BINFMT_BINARY, CTNone },
|
||||||
|
{ "agat", CPU_6502, BINFMT_BINARY, CTAgat },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Target system */
|
/* Target system */
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ typedef enum {
|
|||||||
TGT_SYM1,
|
TGT_SYM1,
|
||||||
TGT_KIM1,
|
TGT_KIM1,
|
||||||
TGT_RP6502,
|
TGT_RP6502,
|
||||||
|
TGT_AGAT,
|
||||||
TGT_COUNT /* Number of target systems */
|
TGT_COUNT /* Number of target systems */
|
||||||
} target_t;
|
} target_t;
|
||||||
|
|
||||||
|
|||||||
@@ -2523,6 +2523,7 @@ static void NextChar (InputData* D)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* CAUTION: table must be sorted for bsearch */
|
||||||
static void NextToken (InputData* D)
|
static void NextToken (InputData* D)
|
||||||
/* Read the next token from the input stream */
|
/* Read the next token from the input stream */
|
||||||
{
|
{
|
||||||
@@ -2530,6 +2531,7 @@ static void NextToken (InputData* D)
|
|||||||
const char Keyword[12];
|
const char Keyword[12];
|
||||||
Token Tok;
|
Token Tok;
|
||||||
} KeywordTable[] = {
|
} KeywordTable[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "abs", TOK_ABSOLUTE },
|
{ "abs", TOK_ABSOLUTE },
|
||||||
{ "addrsize", TOK_ADDRSIZE },
|
{ "addrsize", TOK_ADDRSIZE },
|
||||||
{ "auto", TOK_AUTO },
|
{ "auto", TOK_AUTO },
|
||||||
@@ -2578,6 +2580,7 @@ static void NextToken (InputData* D)
|
|||||||
{ "var", TOK_VAR },
|
{ "var", TOK_VAR },
|
||||||
{ "version", TOK_VERSION },
|
{ "version", TOK_VERSION },
|
||||||
{ "zp", TOK_ZEROPAGE },
|
{ "zp", TOK_ZEROPAGE },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -61,14 +61,17 @@ struct ConverterMapEntry {
|
|||||||
StrBuf* (*ConvertFunc) (const Bitmap*, const Collection*);
|
StrBuf* (*ConvertFunc) (const Bitmap*, const Collection*);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Converter table, alphabetically sorted */
|
/* Converter table */
|
||||||
|
/* CAUTION: table must be alphabetically sorted for bsearch */
|
||||||
static const ConverterMapEntry ConverterMap[] = {
|
static const ConverterMapEntry ConverterMap[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "geos-bitmap", GenGeosBitmap },
|
{ "geos-bitmap", GenGeosBitmap },
|
||||||
{ "geos-icon", GenGeosIcon },
|
{ "geos-icon", GenGeosIcon },
|
||||||
{ "koala", GenKoala },
|
{ "koala", GenKoala },
|
||||||
{ "lynx-sprite", GenLynxSprite },
|
{ "lynx-sprite", GenLynxSprite },
|
||||||
{ "raw", GenRaw },
|
{ "raw", GenRaw },
|
||||||
{ "vic2-sprite", GenVic2Sprite },
|
{ "vic2-sprite", GenVic2Sprite },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -69,12 +69,14 @@ static InputFormatDesc InputFormatTable[ifCount] = {
|
|||||||
{ ReadPCXFile },
|
{ ReadPCXFile },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Table that maps extensions to input formats. Must be sorted alphabetically */
|
/* Table that maps extensions to input formats. */
|
||||||
|
/* CAUTION: table must be alphabetically sorted for bsearch */
|
||||||
static const FileId FormatTable[] = {
|
static const FileId FormatTable[] = {
|
||||||
/* Upper case stuff for obsolete operating systems */
|
/* Upper case stuff for obsolete operating systems */
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "PCX", ifPCX },
|
{ "PCX", ifPCX },
|
||||||
|
|
||||||
{ "pcx", ifPCX },
|
{ "pcx", ifPCX },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -78,22 +78,24 @@ static OutputFormatDesc OutputFormatTable[ofCount] = {
|
|||||||
{ WriteCFile },
|
{ WriteCFile },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Table that maps extensions to Output formats. Must be sorted alphabetically */
|
/* Table that maps extensions to Output formats. */
|
||||||
|
/* CAUTION: table must be alphabetically sorted for bsearch */
|
||||||
static const FileId FormatTable[] = {
|
static const FileId FormatTable[] = {
|
||||||
/* Upper case stuff for obsolete operating systems */
|
/* Upper case stuff for obsolete operating systems */
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "A", ofAsm },
|
{ "A", ofAsm },
|
||||||
{ "ASM", ofAsm },
|
{ "ASM", ofAsm },
|
||||||
{ "BIN", ofBin },
|
{ "BIN", ofBin },
|
||||||
{ "C", ofC },
|
{ "C", ofC },
|
||||||
{ "INC", ofAsm },
|
{ "INC", ofAsm },
|
||||||
{ "S", ofAsm },
|
{ "S", ofAsm },
|
||||||
|
|
||||||
{ "a", ofAsm },
|
{ "a", ofAsm },
|
||||||
{ "asm", ofAsm },
|
{ "asm", ofAsm },
|
||||||
{ "bin", ofBin },
|
{ "bin", ofBin },
|
||||||
{ "c", ofC },
|
{ "c", ofC },
|
||||||
{ "inc", ofAsm },
|
{ "inc", ofAsm },
|
||||||
{ "s", ofAsm },
|
{ "s", ofAsm },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -56,9 +56,12 @@ struct PaletteMapEntry {
|
|||||||
StrBuf* (*PaletteFunc) (const Bitmap*, const Collection*);
|
StrBuf* (*PaletteFunc) (const Bitmap*, const Collection*);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Converter table, alphabetically sorted */
|
/* Converter table */
|
||||||
|
/* CAUTION: table must be alphabetically sorted for bsearch */
|
||||||
static const PaletteMapEntry PaletteMap[] = {
|
static const PaletteMapEntry PaletteMap[] = {
|
||||||
|
/* BEGIN SORTED.SH */
|
||||||
{ "lynx-palette", GenLynxPalette },
|
{ "lynx-palette", GenLynxPalette },
|
||||||
|
/* END SORTED.SH */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -8,6 +8,10 @@
|
|||||||
lda #$ea
|
lda #$ea
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
.ifp02x
|
||||||
|
lax #$ea
|
||||||
|
.endif
|
||||||
|
|
||||||
.ifpsc02
|
.ifpsc02
|
||||||
jmp ($1234,x)
|
jmp ($1234,x)
|
||||||
.endif
|
.endif
|
||||||
@@ -72,3 +76,13 @@
|
|||||||
.byte 0,"CPU_ISET_6502DTV"
|
.byte 0,"CPU_ISET_6502DTV"
|
||||||
.endif
|
.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;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user