Compare commits

...

37 Commits

Author SHA1 Message Date
Evgeny Vrublevsky f789316f86 Add a test for the unnamed labels. 2024-04-07 13:34:49 +03:00
Evgeny Vrublevsky 270f3544b5 Document changes in unnamed labels. 2024-04-07 13:34:48 +03:00
Evgeny Vrublevsky c500cb9086 Add support of unnamed labels with @ (.localchar) prefix. 2024-04-07 13:34:48 +03:00
mrdudz b993d88339 second half of #2420 - don't use the loop macro. Fixes -j13 for me 2024-03-17 17:19:42 +01:00
Bob Andrews 25967e65b5
Merge pull request #2424 from acqn/Cleanup
[cc65] Cleanups in src/cc65/declare.c
2024-03-10 02:39:14 +01:00
Bob Andrews a372ead4de
Merge pull request #2334 from carlo-bramini/fix-sim65-1
[SIM65] Support undocumented opcodes for 6502
2024-03-10 00:37:18 +01:00
Bob Andrews 081d18f7d7
Merge pull request #2422 from acqn/SubFix
[cc65] Fixed potential errors with subtraction evaluation of identifiers at different memory locations
2024-03-09 13:02:27 +01:00
Bob Andrews a293920fb3
Merge pull request #2423 from acqn/BitfieldFix
[cc65] Fixed the error recovery integer type used for bit-fields
2024-03-09 12:05:20 +01:00
Bob Andrews 60c75bdb54
Merge pull request #2414 from SvenMichaelKlose/master
vic-asm.cfg: Fix size of MAIN to end at $1E00.
2024-03-09 12:00:42 +01:00
Sven Michael Klose 1fe12f112e
Merge branch 'cc65:master' into master 2024-03-08 17:41:06 +01:00
Sven Michael Klose a887b29ffb Revert "Test strtok()."
This reverts commit 3a7bd53956.
2024-03-05 07:04:59 +01:00
acqn 731f349b24 Removed ParamTypeCvt(). 2024-02-29 18:24:22 +08:00
acqn 98767741ce Reorganized stuff in src/cc65/declare.c. 2024-02-29 18:24:22 +08:00
acqn 9b2d27d1e1 Fixed the error recovery integer type used for bit-fields. 2024-02-29 18:23:04 +08:00
acqn 23aa562094 Fixed potential errors with subtraction evaluation of identifiers at different memory locations. 2024-02-24 15:34:38 +08:00
Bob Andrews 5c3ff714ae
Merge pull request #2415 from polluks/patch-13
[grc65] Fixed segv of empty resource file
2024-02-23 16:16:46 +01:00
Colin Leroy-Mira 86317711e0 IIgs SCC: Rework branches to X-indexed variables
and general cleanup/commenting
2024-02-23 01:20:47 +01:00
Colin Leroy-Mira 8b71fafb84 IIgs SCC: Allow choosing 115200bps as the card allows it
Of course, that won't work full speed with the standard
IRQ-based RX. But that will allow users to setup the port
at this speed without duplicating the setup part of the
code. Up to them to add hooks to disable IRQs and read
directly in a tight asm loop.
2024-02-23 01:20:47 +01:00
Colin Leroy-Mira 3fd78208ba Disable IRQ if opening at 115200 bps 2024-02-19 19:31:47 +01:00
Colin Leroy-Mira 7a12399b39 Allow choosing 115200bps as the card allows it
Of course, that won't work full speed with the
standard IRQ-based RX. But that will allow users
to setup the port at this speed without duplicating
the setup part of the code. Up to them to add hooks
to disable IRQs and read directly in a tight asm
loop.
2024-02-19 19:31:47 +01:00
Sven Michael Klose 294b034920 Add configuration files for expanded VICs. 2024-02-15 17:32:44 +01:00
Stefan ab0eb4fe58
oops 2024-02-15 09:03:46 +01:00
Stefan 8d4946b3f4
Fixed segv
touch /tmp/xx
grc65 /tmp/xx
2024-02-15 07:52:42 +01:00
Sven Michael Klose 3a7bd53956 Test strtok(). 2024-02-15 01:05:35 +01:00
Sven Michael Klose 8173c850fd Fix size of MAIN to end at $1E00.
Caused negative size of MAIN in cc65-contrib/quikmans2k8.
2024-02-15 00:00:46 +01:00
Bob Andrews 4bde3afd80
Merge pull request #2410 from alexthissen/serial
Improvements and fixes in serial support for Atari Lynx
2024-02-12 12:50:02 +01:00
Alex Thissen 7d6f3d24d4 Changed sta (ptr1,x) to sta (ptr1)
Reset serial status on ser_close
Fixed error for saving serial state
2024-02-11 23:12:27 +00:00
Alex Thissen 8b172e05bc Applied optimization as per review 42Bastian 2024-02-11 20:59:08 +00:00
Alex Thissen 1deb9e52ae Replaced last literal value for SERCTL 2024-02-11 15:46:23 +00:00
Alex Thissen acff429eb8 Added redeye check for SER_HS_SW handshake 2024-02-11 15:33:22 +00:00
Alex Thissen 6cf8ee8eb5 Removed baud rates from 150 and lower.
Fixed tab
Replaced uploader references to SERIAL_INTERRUPT
2024-02-10 23:19:05 +00:00
Alex Thissen 65bce9ecde Implemented mark and space checks. 2024-02-10 23:19:04 +00:00
Alex Thissen 014f85f226 Fixed baud rates 2024-02-10 23:19:04 +00:00
Alex Thissen 788ae82d30 Fixes to serial driver implementation 2024-02-10 23:19:02 +00:00
Carlo Bramini b04d79b1da [SIM65] Support undocumented opcodes for 6502
This PR is mostly a complete rewrite of the emulator for 6502/65c02 opcodes.
It provides an easier to maintain implementation of the instructions, by using few macros rather than having hand-written code for each function.
All undocumented, previously missing opcodes for 6502 are also implemented.
The patch also includes a detailed documentation of those opcodes, for reference to developers.
This PR should fix one of the milestones listed here for the next version of CC65:

https://github.com/cc65/wiki/wiki/Before-the-next-release
2024-02-08 12:13:17 +01:00
mrdudz 3dfe033000 update actions/upload-artifact@v3->actions/upload-artifact@v4, actions/cache@v3->actions/cache@v4 2024-02-03 17:02:08 +01:00
mrdudz 5acfb02794 update actions/checkout@v3 -> actions/checkout@v4 and microsoft/setup-msbuild@v1.1 -> microsoft/setup-msbuild@v2. lets see what happens :) 2024-02-03 16:20:17 +01:00
29 changed files with 2766 additions and 1746 deletions

View File

@ -19,7 +19,7 @@ jobs:
- shell: bash - shell: bash
run: git config --global core.autocrlf input run: git config --global core.autocrlf input
- name: Checkout Source - name: Checkout Source
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Do some simple style checks - name: Do some simple style checks
shell: bash shell: bash
@ -44,7 +44,7 @@ jobs:
shell: bash shell: bash
run: make -j2 doc run: make -j2 doc
- name: Upload a documents snapshot. - name: Upload a documents snapshot.
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: docs name: docs
path: ./html path: ./html
@ -62,10 +62,10 @@ jobs:
run: git config --global core.autocrlf input run: git config --global core.autocrlf input
- name: Checkout Source - name: Checkout Source
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.1 uses: microsoft/setup-msbuild@v2
- name: Build app (x86 debug) - name: Build app (x86 debug)
run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug -property:Platform=Win32 run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug -property:Platform=Win32

View File

@ -18,10 +18,10 @@ jobs:
run: git config --global core.autocrlf input run: git config --global core.autocrlf input
- name: Checkout Source - name: Checkout Source
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.1 uses: microsoft/setup-msbuild@v2
- name: Build app (debug) - name: Build app (debug)
run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug
@ -44,7 +44,7 @@ jobs:
- shell: bash - shell: bash
run: git config --global core.autocrlf input run: git config --global core.autocrlf input
- name: Checkout Source - name: Checkout Source
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Do some simple style checks - name: Do some simple style checks
shell: bash shell: bash
@ -86,18 +86,18 @@ jobs:
mv cc65.zip cc65-snapshot-win32.zip mv cc65.zip cc65-snapshot-win32.zip
- name: Upload a 32-bit Snapshot Zip - name: Upload a 32-bit Snapshot Zip
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: cc65-snapshot-win32 name: cc65-snapshot-win32
path: cc65-snapshot-win32.zip path: cc65-snapshot-win32.zip
- name: Upload a 64-bit Snapshot Zip - name: Upload a 64-bit Snapshot Zip
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: cc65-snapshot-win64 name: cc65-snapshot-win64
path: cc65-snapshot-win64.zip path: cc65-snapshot-win64.zip
- name: Get the online documents repo. - name: Get the online documents repo.
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
repository: cc65/doc repository: cc65/doc
# this token will expire, if it does, generate a new one as decribed in https://github.com/cc65/cc65/issues/2065 # this token will expire, if it does, generate a new one as decribed in https://github.com/cc65/cc65/issues/2065
@ -120,7 +120,7 @@ jobs:
- name: Package offline documents. - name: Package offline documents.
run: 7z a cc65-snapshot-docs.zip ./html/*.* run: 7z a cc65-snapshot-docs.zip ./html/*.*
- name: Upload a Documents Snapshot Zip - name: Upload a Documents Snapshot Zip
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: cc65-snapshot-docs name: cc65-snapshot-docs
path: cc65-snapshot-docs.zip path: cc65-snapshot-docs.zip

View File

@ -30,7 +30,7 @@ jobs:
run: mkdir ~/.cache-sha run: mkdir ~/.cache-sha
- name: Cache SHA - name: Cache SHA
uses: actions/cache@v3 uses: actions/cache@v4
id: check-sha id: check-sha
with: with:
path: ~/.cache-sha path: ~/.cache-sha
@ -43,11 +43,11 @@ jobs:
- name: Checkout source - name: Checkout source
if: steps.check-sha.outputs.cache-hit != 'true' if: steps.check-sha.outputs.cache-hit != 'true'
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Add msbuild to PATH - name: Add msbuild to PATH
if: steps.check-sha.outputs.cache-hit != 'true' if: steps.check-sha.outputs.cache-hit != 'true'
uses: microsoft/setup-msbuild@v1.1 uses: microsoft/setup-msbuild@v2
- name: Build app (MSVC debug) - name: Build app (MSVC debug)
if: steps.check-sha.outputs.cache-hit != 'true' if: steps.check-sha.outputs.cache-hit != 'true'

View File

@ -15,7 +15,7 @@ CPU_ISET_4510 = $0400
CPU_NONE = CPU_ISET_NONE CPU_NONE = CPU_ISET_NONE
CPU_6502 = CPU_ISET_6502 CPU_6502 = CPU_ISET_6502
CPU_6502X = CPU_ISET_6502|CPU_ISET_6502X CPU_6502X = CPU_ISET_6502|CPU_ISET_6502X
CPU_6502DTV = CPU_ISET_6502|CPU_ISET_6502X|CPU_ISET_6502DTV CPU_6502DTV = CPU_ISET_6502|CPU_ISET_6502DTV
CPU_65SC02 = CPU_ISET_6502|CPU_ISET_65SC02 CPU_65SC02 = CPU_ISET_6502|CPU_ISET_65SC02
CPU_65C02 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02 CPU_65C02 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02
CPU_65816 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65816 CPU_65816 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65816

View File

@ -259,30 +259,44 @@ SND_INTERRUPT = TIMER7_INTERRUPT
INTRST = $FD80 INTRST = $FD80
INTSET = $FD81 INTSET = $FD81
MAGRDY0 = $FD84 MAGRDY0 = $FD84
MAGRDY1 = $FD85 MAGRDY1 = $FD85
AUDIN = $FD86 AUDIN = $FD86
SYSCTL1 = $FD87 SYSCTL1 = $FD87
MIKEYHREV = $FD88 MIKEYHREV = $FD88
MIKEYSREV = $FD89 MIKEYSREV = $FD89
IODIR = $FD8A
IODAT = $FD8B IODIR = $FD8A
TxIntEnable = %10000000 IODAT = $FD8B
RxIntEnable = %01000000 ; IODIR and IODAT bit definitions
TxParEnable = %00010000 AUDIN_BIT = $10 ; Note that there is also the address AUDIN
ResetErr = %00001000 READ_ENABLE = $10 ; Same bit for AUDIN_BIT
TxOpenColl = %00000100 RESTLESS = $08
TxBreak = %00000010 NOEXP = $04 ; If set, redeye is not connected
ParEven = %00000001 CART_ADDR_DATA = $02
TxReady = %10000000 CART_POWER_OFF = $02 ; Same bit for CART_ADDR_DATA
RxReady = %01000000 EXTERNAL_POWER = $01
TxEmpty = %00100000
RxParityErr = %00010000 SERCTL = $FD8C
RxOverrun = %00001000 ; SERCTL bit definitions for write operations
RxFrameErr = %00000100 TXINTEN = $80
RxBreak = %00000010 RXINTEN = $40
ParityBit = %00000001 PAREN = $10
SERCTL = $FD8C RESETERR = $08
TXOPEN = $04
TXBRK = $02
PAREVEN = $01
; SERCTL bit definitions for read operations
TXRDY = $80
RXRDY = $40
TXEMPTY = $20
PARERR = $10
OVERRUN = $08
FRAMERR = $04
RXBRK = $02
PARBIT = $01
SERDAT = $FD8D SERDAT = $FD8D
SDONEACK = $FD90 SDONEACK = $FD90
CPUSLEEP = $FD91 CPUSLEEP = $FD91

21
cfg/vic20-asm-32k.cfg Normal file
View File

@ -0,0 +1,21 @@
# Assembly program configuration for expanded VICs (>= +8K).
FEATURES {
STARTADDRESS: default = $1201;
}
SYMBOLS {
__LOADADDR__: type = import;
}
MEMORY {
ZP: file = "", start = $0002, size = $001A, define = yes;
LOADADDR: file = %O, start = %S - 2, size = $0002;
MAIN: file = %O, start = %S, size = $8000 - %S;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, optional = yes;
LOADADDR: load = LOADADDR, type = ro;
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
BSS: load = MAIN, type = bss, optional = yes, define = yes;
}

21
cfg/vic20-asm-3k.cfg Normal file
View File

@ -0,0 +1,21 @@
# Assembly program configuration for expanded VICs (+3K only).
FEATURES {
STARTADDRESS: default = $0401;
}
SYMBOLS {
__LOADADDR__: type = import;
}
MEMORY {
ZP: file = "", start = $0002, size = $001A, define = yes;
LOADADDR: file = %O, start = %S - 2, size = $0002;
MAIN: file = %O, start = %S, size = $1E00 - %S;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, optional = yes;
LOADADDR: load = LOADADDR, type = ro;
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
BSS: load = MAIN, type = bss, optional = yes, define = yes;
}

View File

@ -1,3 +1,5 @@
# Assembly program configuration for unexpanded VICs.
FEATURES { FEATURES {
STARTADDRESS: default = $1001; STARTADDRESS: default = $1001;
} }
@ -7,7 +9,7 @@ SYMBOLS {
MEMORY { MEMORY {
ZP: file = "", start = $0002, size = $001A, define = yes; ZP: file = "", start = $0002, size = $001A, define = yes;
LOADADDR: file = %O, start = %S - 2, size = $0002; LOADADDR: file = %O, start = %S - 2, size = $0002;
MAIN: file = %O, start = %S, size = $0DF3 - %S; MAIN: file = %O, start = %S, size = $1E00 - %S;
} }
SEGMENTS { SEGMENTS {
ZEROPAGE: load = ZP, type = zp, optional = yes; ZEROPAGE: load = ZP, type = zp, optional = yes;

View File

@ -452,10 +452,15 @@ The names in the parentheses denote the symbols to be used for static linking of
(RTS/CTS) and does interrupt driven receives. Speeds faster than 9600 baud (RTS/CTS) and does interrupt driven receives. Speeds faster than 9600 baud
aren't reachable because the ROM and ProDOS IRQ handlers are too slow. aren't reachable because the ROM and ProDOS IRQ handlers are too slow.
Software flow control (XON/XOFF) is not supported. Software flow control (XON/XOFF) is not supported.
Note that because of the peculiarities of the 6551 chip transmits are not Note that because of the peculiarities of the 6551 chip transmits are not
interrupt driven, and the transceiver blocks if the receiver asserts interrupt driven, and the transceiver blocks if the receiver asserts
flow control because of a full buffer. flow control because of a full buffer.
Note that using the driver at SER_BAUD_115200 will disable IRQs. It will be up
to the users to use the serial port, either by re-enabling IRQs themselves,
or by directly poll-reading the ACIA DATA register without the help of ser_get().
The driver defaults to slot 2. Call <tt/ser_apple2_slot()/ prior to The driver defaults to slot 2. Call <tt/ser_apple2_slot()/ prior to
<tt/ser_open()/ in order to select a different slot. <tt/ser_apple2_slot()/ <tt/ser_open()/ in order to select a different slot. <tt/ser_apple2_slot()/
succeeds for all Apple&nbsp;II slots, but <tt/ser_open()/ fails with succeeds for all Apple&nbsp;II slots, but <tt/ser_open()/ fails with

View File

@ -453,10 +453,15 @@ The names in the parentheses denote the symbols to be used for static linking of
(RTS/CTS) and does interrupt driven receives. Speeds faster than 9600 baud (RTS/CTS) and does interrupt driven receives. Speeds faster than 9600 baud
aren't reachable because the ROM and ProDOS IRQ handlers are too slow. aren't reachable because the ROM and ProDOS IRQ handlers are too slow.
Software flow control (XON/XOFF) is not supported. Software flow control (XON/XOFF) is not supported.
Note that because of the peculiarities of the 6551 chip transmits are not Note that because of the peculiarities of the 6551 chip transmits are not
interrupt driven, and the transceiver blocks if the receiver asserts interrupt driven, and the transceiver blocks if the receiver asserts
flow control because of a full buffer. flow control because of a full buffer.
Note that using the driver at SER_BAUD_115200 will disable IRQs. It will be up
to the users to use the serial port, either by re-enabling IRQs themselves,
or by directly poll-reading the ACIA DATA register without the help of ser_get().
The driver defaults to slot 2. Call <tt/ser_apple2_slot()/ prior to The driver defaults to slot 2. Call <tt/ser_apple2_slot()/ prior to
<tt/ser_open()/ in order to select a different slot. <tt/ser_apple2_slot()/ <tt/ser_open()/ in order to select a different slot. <tt/ser_apple2_slot()/
succeeds for all Apple&nbsp;II slots, but <tt/ser_open()/ fails with succeeds for all Apple&nbsp;II slots, but <tt/ser_open()/ fails with

View File

@ -829,49 +829,42 @@ names like "Loop". Here is an example:
bne @Loop ; ERROR: Unknown identifier! bne @Loop ; ERROR: Unknown identifier!
</verb></tscreen> </verb></tscreen>
<sect1>Unnamed labels<p> <sect1>Unnamed labels<p>
If you really want to write messy code, there are also unnamed labels. These If you really want to write messy code, there are also unnamed labels. To define
labels do not have a name (you guessed that already, didn't you?). A colon is an unnamed label, use either <tt>@:</tt> (<tt>.LOCALCHAR</tt> is respected if it
used to mark the absence of the name. is set) or sole <tt>:</tt>.
Unnamed labels may be accessed by using the colon plus several minus or plus To reference an unnamed label, use <tt>@</tt> (<tt>.LOCALCHAR</tt> is respected
characters as a label designator. Using the '-' characters will create a back if it is set) or <tt>:</tt> with several <tt>-</tt> or <tt>+</tt> characters.
reference (use the n'th label backwards), using '+' will create a forward The <tt>-</tt> characters will create a back reference (n'th label backwards),
reference (use the n'th label in forward direction). An example will help to the <tt>+</tt> will create a forward reference (n'th label in forward direction).
understand this: As an alternative, angle brackets <tt>&lt;</tt> and <tt>&gt;</tt> may be used
instead of <tt>-</tt> and <tt>+</tt> with the same meaning.
Example:
<tscreen><verb> <tscreen><verb>
: lda (ptr1),y ; #1 cpy #0
cmp (ptr2),y beq @++
bne :+ ; -> #2 @:
tax sta $2007
beq :+++ ; -> #4 dey
iny bne @-
bne :- ; -> #1 @:
inc ptr1+1 rts
inc ptr2+1
bne :- ; -> #1
: bcs :+ ; #2 -> #3
ldx #$FF
rts
: ldx #$01 ; #3
: rts ; #4
</verb></tscreen> </verb></tscreen>
As you can see from the example, unnamed labels will make even short Unnamed labels may make even short sections of code hard to understand, because
sections of code hard to understand, because you have to count labels you have to count labels to find branch targets. It's better to prefer the
to find branch targets (this is the reason why I for my part do "cheap" local labels. Nevertheless, unnamed labels are convenient in some
prefer the "cheap" local labels). Nevertheless, unnamed labels are situations, so it's up to your discretion.
convenient in some situations, so it's your decision.
<em/Note:/ <ref id="scopes" name="Scopes"> organize named symbols, not <em/Note:/ <ref id="scopes" name="Scopes"> organize named symbols, not
unnamed ones, so scopes don't have an effect on unnamed labels. unnamed ones, so scopes don't have an effect on unnamed labels.
<sect1>Using macros to define labels and constants<p> <sect1>Using macros to define labels and constants<p>
While there are drawbacks with this approach, it may be handy in a few rare While there are drawbacks with this approach, it may be handy in a few rare

View File

@ -66,34 +66,16 @@ HSType: .res 1 ; Flow-control type
RecvBuf: .res 256 ; Receive buffers: 256 bytes RecvBuf: .res 256 ; Receive buffers: 256 bytes
SendBuf: .res 256 ; Send buffers: 256 bytes SendBuf: .res 256 ; Send buffers: 256 bytes
CurClockSource: .res 1 ; Whether to use BRG or RTxC for clock
.data .data
Opened: .byte $00 ; 1 when opened Opened: .byte $00 ; 1 when opened
Channel: .byte $00 ; Channel B by default Channel: .byte $00 ; Channel B by default
CurChanIrqFlags:.byte INTR_PENDING_RX_EXT_B CurChanIrqFlags:.byte $00
SerFlagOrig: .byte $00 SerFlagOrig: .byte $00
; Tables used to translate cc65 RS232 params into register values
; (Ref page 5-18 and 5-19)
BaudLowTable: .byte $7E ; SER_BAUD_300
.byte $5E ; SER_BAUD_1200
.byte $2E ; SER_BAUD_2400
.byte $16 ; SER_BAUD_4800
.byte $0A ; SER_BAUD_9600
.byte $04 ; SER_BAUD_19200
.byte $01 ; SER_BAUD_38400
.byte $00 ; SER_BAUD_57600
BaudHighTable: .byte $01 ; SER_BAUD_300
.byte $00 ; SER_BAUD_1200
.byte $00 ; SER_BAUD_2400
.byte $00 ; SER_BAUD_4800
.byte $00 ; SER_BAUD_9600
.byte $00 ; SER_BAUD_19200
.byte $00 ; SER_BAUD_38400
.byte $00 ; SER_BAUD_57600
RxBitTable: .byte %00000000 ; SER_BITS_5, in WR_RX_CTRL (WR3) RxBitTable: .byte %00000000 ; SER_BITS_5, in WR_RX_CTRL (WR3)
.byte %10000000 ; SER_BITS_6 (Ref page 5-7) .byte %10000000 ; SER_BITS_6 (Ref page 5-7)
.byte %01000000 ; SER_BITS_7 .byte %01000000 ; SER_BITS_7
@ -106,29 +88,65 @@ TxBitTable: .byte %00000000 ; SER_BITS_5, in WR_TX_CTRL (WR5)
.rodata .rodata
ClockMultiplier:.byte %01000000 ; Clock x16 (300-57600bps, WR4, ref page 5-8)
.byte %10000000 ; Clock x32 (115200bps, ref page 5-8)
ClockSource: .byte %01010000 ; Use baud rate generator (ch. B) (WR11, page 5-17)
.byte %00000000 ; Use RTxC (115200bps) (ch. B)
.byte %11010000 ; Use baud rate generator (ch. A)
.byte %10000000 ; Use RTxC (115200bps) (ch. A)
BrgEnabled: .byte %00000001 ; Baud rate generator on (WR14, page 5-19)
.byte %00000000 ; BRG Off
ChanIrqFlags: .byte %00000101 ; ANDed (RX/special IRQ, ch. B) (page 5-25)
.byte %00101000 ; ANDed (RX/special IRQ, ch. A)
ChanIrqMask: .byte %00000111 ; Ch. B IRQ flags mask
.byte %00111000 ; Ch. A IRQ flags mask
BaudTable: ; bit7 = 1 means setting is invalid BaudTable: ; bit7 = 1 means setting is invalid
; Otherwise refers to the index in ; Indexes cc65 RS232 SER_BAUD enum
; Baud(Low/High)Table ; into WR12/13 register values
.byte $FF ; SER_BAUD_45_5 ; (Ref page 5-18 and 5-19)
.byte $FF ; SER_BAUD_50 .word $FFFF ; SER_BAUD_45_5
.byte $FF ; SER_BAUD_75 .word $FFFF ; SER_BAUD_50
.byte $FF ; SER_BAUD_110 .word $FFFF ; SER_BAUD_75
.byte $FF ; SER_BAUD_134_5 .word $FFFF ; SER_BAUD_110
.byte $FF ; SER_BAUD_150 .word $FFFF ; SER_BAUD_134_5
.byte $00 ; SER_BAUD_300 .word $FFFF ; SER_BAUD_150
.byte $FF ; SER_BAUD_600 .word $017E ; SER_BAUD_300
.byte $01 ; SER_BAUD_1200 .word $FFFF ; SER_BAUD_600
.byte $FF ; SER_BAUD_1800 .word $005E ; SER_BAUD_1200
.byte $02 ; SER_BAUD_2400 .word $FFFF ; SER_BAUD_1800
.byte $FF ; SER_BAUD_3600 .word $002E ; SER_BAUD_2400
.byte $03 ; SER_BAUD_4800 .word $FFFF ; SER_BAUD_3600
.byte $FF ; SER_BAUD_7200 .word $0016 ; SER_BAUD_4800
.byte $04 ; SER_BAUD_9600 .word $FFFF ; SER_BAUD_7200
.byte $05 ; SER_BAUD_19200 .word $000A ; SER_BAUD_9600
.byte $06 ; SER_BAUD_38400 .word $0004 ; SER_BAUD_19200
.byte $07 ; SER_BAUD_57600 .word $0001 ; SER_BAUD_38400
.byte $FF ; SER_BAUD_115200 .word $0000 ; SER_BAUD_57600
.byte $FF ; SER_BAUD_230400 .word $0000 ; SER_BAUD_115200 (constant unused at that speed)
.word $FFFF ; SER_BAUD_230400
; About the speed selection: either we use the baud rate generator:
; - Load the time constants from BaudTable into WR12/WR13
; - Setup the TX/RX clock source to BRG (ClockSource into WR11)
; - Setup the clock multiplier (WR4)
; - Enable the baud rate generator (WR14)
; In this case, the baud rate will be:
; rate = crystal_clock/(2+BRG_time_constant))/(2*clock_multiplier)
; Example: (3686400/(2+0x0004)) / (2*16) = 19200 bps
;
; Or we don't use the baud rate generator:
; - Setup the TX/RX clock source to RTxC
; - Setup the clock multiplier
; - Disable the baud rate generator
; - WR12 and 13 are ignored
; In this case, the baud rate will be:
; rate = crystal_clock/clock_multiplier
; Example: 3686400/32 = 115200 bps
StopTable: .byte %00000100 ; SER_STOP_1, in WR_TX_RX_CTRL (WR4) StopTable: .byte %00000100 ; SER_STOP_1, in WR_TX_RX_CTRL (WR4)
.byte %00001100 ; SER_STOP_2 (Ref page 5-8) .byte %00001100 ; SER_STOP_2 (Ref page 5-8)
@ -156,6 +174,7 @@ SER_FLAG := $E10104
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
; Channels ; Channels
CHANNEL_B = 0 CHANNEL_B = 0
CHANNEL_A = 1 CHANNEL_A = 1
@ -180,7 +199,6 @@ RX_CTRL_OFF = %11111110 ; ANDed,Rx disabled
WR_TX_RX_CTRL = 4 WR_TX_RX_CTRL = 4
RR_TX_RX_STATUS = 4 RR_TX_RX_STATUS = 4
TX_RX_CLOCK_MUL = %01000000 ; Clock x16 (Ref page 5-8)
WR_TX_CTRL = 5 ; (Ref page 5-9) WR_TX_CTRL = 5 ; (Ref page 5-9)
RR_TX_STATUS = 5 ; Corresponding status register RR_TX_STATUS = 5 ; Corresponding status register
@ -197,15 +215,11 @@ MASTER_IRQ_MIE_RST = %00001010 ; STA'd
MASTER_IRQ_SET = %00011001 ; STA'd MASTER_IRQ_SET = %00011001 ; STA'd
WR_CLOCK_CTRL = 11 ; (Ref page 5-17) WR_CLOCK_CTRL = 11 ; (Ref page 5-17)
CLOCK_CTRL_CH_A = %11010000
CLOCK_CTRL_CH_B = %01010000
WR_BAUDL_CTRL = 12 ; (Ref page 5-18) WR_BAUDL_CTRL = 12 ; (Ref page 5-18)
WR_BAUDH_CTRL = 13 ; (Ref page 5-19) WR_BAUDH_CTRL = 13 ; (Ref page 5-19)
WR_MISC_CTRL = 14 ; (Ref page 5-19) WR_MISC_CTRL = 14 ; (Ref page 5-19)
MISC_CTRL_RATE_GEN_ON = %00000001 ; ORed
MISC_CTRL_RATE_GEN_OFF = %11111110 ; ANDed
WR_IRQ_CTRL = 15 ; (Ref page 5-20) WR_IRQ_CTRL = 15 ; (Ref page 5-20)
IRQ_CLEANUP_EIRQ = %00001000 IRQ_CLEANUP_EIRQ = %00001000
@ -220,13 +234,8 @@ IRQ_RX = %00100000
IRQ_SPECIAL = %01100000 IRQ_SPECIAL = %01100000
RR_INTR_PENDING_STATUS = 3 ; (Ref page 5-25) RR_INTR_PENDING_STATUS = 3 ; (Ref page 5-25)
INTR_PENDING_RX_EXT_A = %00101000 ; ANDed (RX or special IRQ)
INTR_PENDING_RX_EXT_B = %00000101 ; ANDed (RX or special IRQ)
INTR_IS_RX = %00100100 ; ANDed (RX IRQ, channel A or B) INTR_IS_RX = %00100100 ; ANDed (RX IRQ, channel A or B)
SER_FLAG_CH_A = %00111000
SER_FLAG_CH_B = %00000111
.code .code
; Read register value to A. ; Read register value to A.
@ -329,6 +338,15 @@ IIgs:
: txa ; Promote char return value : txa ; Promote char return value
rts rts
getClockSource:
.assert SER_PARAMS::BAUDRATE = 0, error
lda (ptr1) ; Baudrate index - cc65 value
cmp #SER_BAUD_115200
lda #$00
adc #$00
sta CurClockSource ; 0 = BRG, 1 = RTxC
rts
;---------------------------------------------------------------------------- ;----------------------------------------------------------------------------
; SER_OPEN: A pointer to a ser_params structure is passed in ptr1. ; SER_OPEN: A pointer to a ser_params structure is passed in ptr1.
; Must return an SER_ERR_xx code in a/x. ; Must return an SER_ERR_xx code in a/x.
@ -360,11 +378,13 @@ SER_OPEN:
ldy #RR_INIT_STATUS ; Hit rr0 once to sync up ldy #RR_INIT_STATUS ; Hit rr0 once to sync up
jsr readSSCReg jsr readSSCReg
ldy #WR_MISC_CTRL ; Turn everything off ldy #WR_MISC_CTRL ; WR14: Turn everything off
lda #$00 lda #$00
jsr writeSCCReg jsr writeSCCReg
ldy #SER_PARAMS::STOPBITS jsr getClockSource ; Should we use BRG or RTxC?
ldy #SER_PARAMS::STOPBITS ; WR4 setup: clock mult., stop & parity
lda (ptr1),y ; Stop bits lda (ptr1),y ; Stop bits
tay tay
lda StopTable,y ; Get value lda StopTable,y ; Get value
@ -377,36 +397,33 @@ SER_OPEN:
ora ParityTable,y ; Get value ora ParityTable,y ; Get value
bmi InvParam bmi InvParam
ora #TX_RX_CLOCK_MUL ldy CurClockSource ; Clock multiplier
ora ClockMultiplier,y
ldy #WR_TX_RX_CTRL ; Setup stop & parity bits ldy #WR_TX_RX_CTRL
jsr writeSCCReg jsr writeSCCReg ; End of WR4 setup
ldy CurClockSource ; WR11 setup: clock source
cpx #CHANNEL_B cpx #CHANNEL_B
bne ClockA beq SetClock
ClockB: iny ; Shift to get correct ClockSource val
iny ; depending on our channel
SetClock:
lda ClockSource,y
ldy #WR_CLOCK_CTRL ldy #WR_CLOCK_CTRL
lda #CLOCK_CTRL_CH_B jsr writeSCCReg ; End of WR11 setup
jsr writeSCCReg
lda #INTR_PENDING_RX_EXT_B ; Store which IRQ bits we'll check lda ChanIrqFlags,x ; Store which IRQ bits we'll check
sta CurChanIrqFlags
bra SetBaud
ClockA:
ldy #WR_CLOCK_CTRL
lda #CLOCK_CTRL_CH_A
jsr writeSCCReg
lda #INTR_PENDING_RX_EXT_A ; Store which IRQ bits we'll check
sta CurChanIrqFlags sta CurChanIrqFlags
SetBaud: SetBaud:
ldy #SER_PARAMS::BAUDRATE .assert SER_PARAMS::BAUDRATE = 0, error
lda (ptr1),y ; Baudrate index - cc65 value lda (ptr1) ; Baudrate index - cc65 value
asl
tay tay
lda BaudTable,y ; Get chip value from Low/High tables lda BaudTable,y ; Get low byte of register value
bpl BaudOK ; Verify baudrate is supported bpl BaudOK ; Verify baudrate is supported
InvParam: InvParam:
@ -415,59 +432,57 @@ InvParam:
bra SetupOut bra SetupOut
BaudOK: BaudOK:
tay phy ; WR12 setup: BRG time constant, low byte
ldy #WR_BAUDL_CTRL ; Setting WR12 & 13 is useless if we're using
lda BaudLowTable,y ; Get low byte jsr writeSCCReg ; RTxC, but doing it anyway makes code smaller
phy
ldy #WR_BAUDL_CTRL
jsr writeSCCReg
ply ply
lda BaudHighTable,y ; Get high byte iny
lda BaudTable,y ; WR13 setup: BRG time constant, high byte
ldy #WR_BAUDH_CTRL ldy #WR_BAUDH_CTRL
jsr writeSCCReg jsr writeSCCReg
ldy CurClockSource ; WR14 setup: BRG enabling
lda BrgEnabled,y
ldy #WR_MISC_CTRL ; Time to turn this thing on ldy #WR_MISC_CTRL ; Time to turn this thing on
lda #MISC_CTRL_RATE_GEN_ON
jsr writeSCCReg jsr writeSCCReg
ldy #SER_PARAMS::DATABITS ldy #SER_PARAMS::DATABITS ; WR3 setup: RX data bits
lda (ptr1),y ; Data bits lda (ptr1),y
tay tay
lda RxBitTable,y ; Data bits for RX lda RxBitTable,y
ora #RX_CTRL_ON ; and turn RX on ora #RX_CTRL_ON ; and turn receiver on
phy phy
ldy #WR_RX_CTRL ldy #WR_RX_CTRL
jsr writeSCCReg jsr writeSCCReg ; End of WR3 setup
ply ply
lda TxBitTable,y ; Data bits for TX lda TxBitTable,y ; WR5 setup: TX data bits
ora #TX_CTRL_ON ; and turn TX on ora #TX_CTRL_ON ; and turn transmitter on
and #TX_DTR_ON and #TX_DTR_ON ; and turn DTR on
sta RtsOff ; Save value for flow control sta RtsOff ; Save value for flow control
ora #TX_RTS_ON ora #TX_RTS_ON ; and turn RTS on
ldy #WR_TX_CTRL ldy #WR_TX_CTRL
jsr writeSCCReg jsr writeSCCReg ; End of WR5 setup
ldy #WR_IRQ_CTRL ldy #WR_IRQ_CTRL ; WR15 setup: IRQ
lda #IRQ_CLEANUP_EIRQ lda #IRQ_CLEANUP_EIRQ
jsr writeSCCReg jsr writeSCCReg
ldy #WR_INIT_CTRL ; Clear ext status (write twice) ldy #WR_INIT_CTRL ; WR0 setup: clear existing IRQs
lda #INIT_CTRL_CLEAR_EIRQ lda #INIT_CTRL_CLEAR_EIRQ
jsr writeSCCReg jsr writeSCCReg ; Clear (write twice)
jsr writeSCCReg jsr writeSCCReg
ldy #WR_TX_RX_MODE_CTRL ; Activate RX IRQ ldy #WR_TX_RX_MODE_CTRL ; WR1 setup: Activate RX IRQ
lda #TX_RX_MODE_RXIRQ lda #TX_RX_MODE_RXIRQ
jsr writeSCCReg jsr writeSCCReg
lda SCCBREG ; Activate master IRQ lda SCCBREG ; WR9 setup: Activate master IRQ
ldy #WR_MASTER_IRQ_RST ldy #WR_MASTER_IRQ_RST
lda #MASTER_IRQ_SET lda #MASTER_IRQ_SET
jsr writeSCCReg jsr writeSCCReg
@ -475,14 +490,7 @@ BaudOK:
lda SER_FLAG ; Get SerFlag's current value lda SER_FLAG ; Get SerFlag's current value
sta SerFlagOrig ; and save it sta SerFlagOrig ; and save it
cpx #CHANNEL_B ora ChanIrqMask,x ; Tell firmware which channel IRQs we want
bne IntA
IntB:
ora #SER_FLAG_CH_B ; Inform firmware we want channel B IRQs
bra StoreFlag
IntA:
ora #SER_FLAG_CH_A ; Inform firmware we want channel A IRQs
StoreFlag:
sta SER_FLAG sta SER_FLAG
ldy #$01 ; Mark port opened ldy #$01 ; Mark port opened

View File

@ -121,7 +121,7 @@ BaudTable: ; Table used to translate RS232 baudrate param
.byte $0F ; SER_BAUD_19200 .byte $0F ; SER_BAUD_19200
.byte $FF ; SER_BAUD_38400 .byte $FF ; SER_BAUD_38400
.byte $FF ; SER_BAUD_57600 .byte $FF ; SER_BAUD_57600
.byte $FF ; SER_BAUD_115200 .byte $00 ; SER_BAUD_115200
.byte $FF ; SER_BAUD_230400 .byte $FF ; SER_BAUD_230400
BitTable: ; Table used to translate RS232 databits param BitTable: ; Table used to translate RS232 databits param
@ -302,6 +302,7 @@ HandshakeOK:
lda (ptr1),y ; Baudrate index lda (ptr1),y ; Baudrate index
tay tay
lda BaudTable,y ; Get 6551 value lda BaudTable,y ; Get 6551 value
sta tmp2 ; Backup for IRQ setting
bpl BaudOK ; Check that baudrate is supported bpl BaudOK ; Check that baudrate is supported
lda #SER_ERR_BAUD_UNAVAIL lda #SER_ERR_BAUD_UNAVAIL
@ -332,8 +333,13 @@ BaudOK: sta tmp1
ora #%00000001 ; Set DTR active ora #%00000001 ; Set DTR active
sta RtsOff ; Store value to easily handle flow control later sta RtsOff ; Store value to easily handle flow control later
ora #%00001000 ; Enable receive interrupts (RTS low)
sta ACIA_CMD,x ora #%00001010 ; Disable interrupts and set RTS low
ldy tmp2 ; Don't enable IRQs if 115200bps
beq :+
and #%11111101 ; Enable receive IRQs
: sta ACIA_CMD,x
; Done ; Done
stx Index ; Mark port as open stx Index ; Mark port as open

View File

@ -68,7 +68,7 @@ MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$2
; Disable the TX/RX IRQ; set to 8E1. ; Disable the TX/RX IRQ; set to 8E1.
lda #%00011101 lda #PAREN|RESETERR|TXOPEN|PAREVEN ; #%00011101
sta SERCTL sta SERCTL
; Clear all pending interrupts. ; Clear all pending interrupts.

View File

@ -73,7 +73,12 @@ SER_UNINSTALL:
; Must return an SER_ERR_xx code in a/x. ; Must return an SER_ERR_xx code in a/x.
SER_CLOSE: SER_CLOSE:
; Disable interrupts ; Disable interrupts and stop timer 4 (serial)
lda #TXOPEN|RESETERR
sta SERCTL
stz TIM4CTLA ; Disable count and no reload
stz SerialStat ; Reset status
; Done, return an error code ; Done, return an error code
lda #SER_ERR_OK lda #SER_ERR_OK
.assert SER_ERR_OK = 0, error .assert SER_ERR_OK = 0, error
@ -108,17 +113,17 @@ SER_OPEN:
stz TxPtrIn stz TxPtrIn
stz TxPtrOut stz TxPtrOut
; clock = 8 * 15625
lda #%00011000
sta TIM4CTLA
ldy #SER_PARAMS::BAUDRATE ldy #SER_PARAMS::BAUDRATE
lda (ptr1),y lda (ptr1),y
; Source period is 1 us
ldy #%00011000 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_1
ldx #1 ldx #1
cmp #SER_BAUD_62500 cmp #SER_BAUD_62500
beq setbaudrate beq setbaudrate
ldx #2 ldx #3
cmp #SER_BAUD_31250 cmp #SER_BAUD_31250
beq setbaudrate beq setbaudrate
@ -134,6 +139,10 @@ SER_OPEN:
cmp #SER_BAUD_2400 cmp #SER_BAUD_2400
beq setbaudrate beq setbaudrate
ldx #68
cmp #SER_BAUD_1800
beq setbaudrate
ldx #103 ldx #103
cmp #SER_BAUD_1200 cmp #SER_BAUD_1200
beq setbaudrate beq setbaudrate
@ -142,65 +151,22 @@ SER_OPEN:
cmp #SER_BAUD_600 cmp #SER_BAUD_600
beq setbaudrate beq setbaudrate
; clock = 6 * 15625 ; Source period is 8 us
ldx #%00011010 ldy #%00011011 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_8
stx TIM4CTLA
ldx #12 ldx #51
cmp #SER_BAUD_7200
beq setbaudrate
ldx #25
cmp #SER_BAUD_3600
beq setbaudrate
ldx #207
stx TIM4BKUP
; clock = 4 * 15625
ldx #%00011100
cmp #SER_BAUD_300 cmp #SER_BAUD_300
beq setprescaler
; clock = 6 * 15625
ldx #%00011110
cmp #SER_BAUD_150
beq setprescaler
; clock = 1 * 15625
ldx #%00011111
stx TIM4CTLA
cmp #SER_BAUD_75
beq baudsuccess
ldx #141
cmp #SER_BAUD_110
beq setbaudrate
; clock = 2 * 15625
ldx #%00011010
stx TIM4CTLA
ldx #68
cmp #SER_BAUD_1800
beq setbaudrate
; clock = 6 * 15625
ldx #%00011110
stx TIM4CTLA
ldx #231
cmp #SER_BAUD_134_5
beq setbaudrate beq setbaudrate
lda #SER_ERR_BAUD_UNAVAIL lda #SER_ERR_BAUD_UNAVAIL
ldx #0 ; return value is char ldx #0 ; return value is char
rts rts
setprescaler:
stx TIM4CTLA
bra baudsuccess
setbaudrate: setbaudrate:
sty TIM4CTLA
stx TIM4BKUP stx TIM4BKUP
baudsuccess:
ldx #TxOpenColl|ParEven ldx #TXOPEN|PAREVEN
stx contrl stx contrl
ldy #SER_PARAMS::DATABITS ; Databits ldy #SER_PARAMS::DATABITS ; Databits
lda (ptr1),y lda (ptr1),y
@ -218,15 +184,15 @@ baudsuccess:
beq checkhs beq checkhs
cmp #SER_PAR_SPACE cmp #SER_PAR_SPACE
bne @L0 bne @L0
ldx #TxOpenColl ldx #TXOPEN
stx contrl stx contrl
bra checkhs bra checkhs
@L0: @L0:
ldx #TxParEnable|TxOpenColl|ParEven ldx #PAREN|TXOPEN|PAREVEN
stx contrl stx contrl
cmp #SER_PAR_EVEN cmp #SER_PAR_EVEN
beq checkhs beq checkhs
ldx #TxParEnable|TxOpenColl ldx #PAREN|TXOPEN
stx contrl stx contrl
checkhs: checkhs:
ldx contrl ldx contrl
@ -234,15 +200,27 @@ checkhs:
ldy #SER_PARAMS::HANDSHAKE ; Handshake ldy #SER_PARAMS::HANDSHAKE ; Handshake
lda (ptr1),y lda (ptr1),y
cmp #SER_HS_NONE cmp #SER_HS_NONE
beq redeye_ok
cmp #SER_HS_SW ; Software handshake will check for connected redeye
bne invparameter bne invparameter
lda IODAT
and #NOEXP ; Check if redeye bit flag is unset
beq redeye_ok
lda #SER_ERR_NO_DEVICE ; ComLynx cable is not inserted
ldx #0
rts
redeye_ok:
lda SERDAT lda SERDAT
lda contrl lda contrl
ora #RxIntEnable|ResetErr ora #RXINTEN|RESETERR ; Turn on interrupts for receive
sta SERCTL sta SERCTL
lda #SER_ERR_OK lda #SER_ERR_OK
.assert SER_ERR_OK = 0, error .assert SER_ERR_OK = 0, error
tax tax
rts rts
invparameter: invparameter:
lda #SER_ERR_INIT_FAILED lda #SER_ERR_INIT_FAILED
ldx #0 ; return value is char ldx #0 ; return value is char
@ -264,8 +242,8 @@ GetByte:
ldy RxPtrOut ldy RxPtrOut
lda RxBuffer,y lda RxBuffer,y
inc RxPtrOut inc RxPtrOut
sta (ptr1)
ldx #$00 ldx #$00
sta (ptr1,x)
txa ; Return code = 0 txa ; Return code = 0
rts rts
@ -279,24 +257,26 @@ SER_PUT:
ina ina
cmp TxPtrOut cmp TxPtrOut
bne PutByte bne PutByte
lda #SER_ERR_OVERFLOW lda #SER_ERR_OVERFLOW
ldx #0 ; return value is char ldx #0 ; return value is char
rts rts
PutByte: PutByte:
ldy TxPtrIn ldy TxPtrIn
txa txa
sta TxBuffer,y sta TxBuffer,y
inc TxPtrIn inc TxPtrIn
bit TxDone bit TxDone ; Check bit 7 of TxDone (TXINTEN)
bmi @L1 bmi @L1 ; Was TXINTEN already set?
php php
sei sei
lda contrl lda contrl ; contrl does not include RXINTEN setting
ora #TxIntEnable|ResetErr ora #TXINTEN|RESETERR
sta SERCTL ; Allow TX-IRQ to hang RX-IRQ sta SERCTL ; Allow TX-IRQ to hang RX-IRQ (no receive while transmitting)
sta TxDone sta TxDone
plp plp ; Restore processor and interrupt enable
@L1: @L1:
lda #SER_ERR_OK lda #SER_ERR_OK
.assert SER_ERR_OK = 0, error .assert SER_ERR_OK = 0, error
@ -308,9 +288,9 @@ PutByte:
; Must return an SER_ERR_xx code in a/x. ; Must return an SER_ERR_xx code in a/x.
SER_STATUS: SER_STATUS:
ldy SerialStat lda SerialStat
sta (ptr1)
ldx #$00 ldx #$00
sta (ptr1,x)
txa ; Return code = 0 txa ; Return code = 0
rts rts
@ -342,48 +322,56 @@ SER_IRQ:
@L0: @L0:
bit TxDone bit TxDone
bmi @tx_irq ; Transmit in progress bmi @tx_irq ; Transmit in progress
ldx SERDAT
lda SERCTL ldx SERDAT ; Read received data
and #RxParityErr|RxOverrun|RxFrameErr|RxBreak lda contrl
beq @rx_irq and #PAREN ; Parity enabled implies SER_PAR_EVEN or SER_PAR_ODD
tay
ora #OVERRUN|FRAMERR|RXBRK
and SERCTL ; Check presence of relevant error flags in SERCTL
beq @rx_irq ; No errors so far
tsb SerialStat ; Save error condition tsb SerialStat ; Save error condition
bit #RxBreak bit #RXBRK ; Check for break signal
beq @noBreak beq @noBreak
stz TxPtrIn ; Break received - drop buffers stz TxPtrIn ; Break received - drop buffers
stz TxPtrOut stz TxPtrOut
stz RxPtrIn stz RxPtrIn
stz RxPtrOut stz RxPtrOut
@noBreak: @noBreak:
lda contrl bra @exit0
ora #RxIntEnable|ResetErr
sta SERCTL
lda #$10
sta INTRST
bra @IRQexit
@rx_irq: @rx_irq:
tya
bne @2 ; Parity was enabled so no marker bit check needed
lda contrl lda contrl
ora #RxIntEnable|ResetErr eor SERCTL ; Should match current parity bit
sta SERCTL and #PARBIT ; Check for mark or space value
bne @exit0
@2:
txa txa
ldx RxPtrIn ldx RxPtrIn
sta RxBuffer,x sta RxBuffer,x
txa txa
inx inx
@cont0:
cpx RxPtrOut cpx RxPtrOut
beq @1 beq @1
stx RxPtrIn stx RxPtrIn
lda #SERIAL_INTERRUPT
sta INTRST
bra @IRQexit bra @IRQexit
@1: @1:
sta RxPtrIn sta RxPtrIn
lda #$80 lda #$80
tsb SerialStat tsb SerialStat
bra @exit0
@tx_irq: @tx_irq:
ldx TxPtrOut ; Has all bytes been sent? ldx TxPtrOut ; Have all bytes been sent?
cpx TxPtrIn cpx TxPtrIn
beq @allSent beq @allSent
@ -393,24 +381,24 @@ SER_IRQ:
@exit1: @exit1:
lda contrl lda contrl
ora #TxIntEnable|ResetErr ora #TXINTEN|RESETERR
sta SERCTL sta SERCTL
lda #SERIAL_INTERRUPT
sta INTRST
bra @IRQexit bra @IRQexit
@allSent: @allSent:
lda SERCTL ; All bytes sent lda SERCTL ; All bytes sent
bit #TxEmpty bit #TXEMPTY
beq @exit1 beq @exit1
bvs @exit1 bvs @exit1
stz TxDone stz TxDone
@exit0:
lda contrl lda contrl
ora #RxIntEnable|ResetErr ora #RXINTEN|RESETERR ; Re-enable receive interrupt
sta SERCTL sta SERCTL
@IRQexit:
lda #SERIAL_INTERRUPT lda #SERIAL_INTERRUPT
sta INTRST sta INTRST
@IRQexit:
clc clc
rts rts

View File

@ -40,14 +40,14 @@ cont1:
bra loop1 bra loop1
read_byte: read_byte:
bit SERCTL bit SERCTL ; Check for RXRDY ($40)
bvc read_byte bvc read_byte
lda SERDAT lda SERDAT
rts rts
_UpLoaderIRQ: _UpLoaderIRQ:
lda INTSET lda INTSET
and #$10 and #SERIAL_INTERRUPT
bne @L0 bne @L0
clc clc
rts rts
@ -69,7 +69,7 @@ again:
; last action : clear interrupt ; last action : clear interrupt
; ;
exit: exit:
lda #$10 lda #SERIAL_INTERRUPT
sta INTRST sta INTRST
clc clc
rts rts

View File

@ -9,11 +9,21 @@
.import __MAIN_START__ .import __MAIN_START__
.import startup .import startup
.macpack cpu
.segment "EXEHDR" .segment "EXEHDR"
.byte $73, $69, $6D, $36, $35 ; 'sim65' .byte $73, $69, $6D, $36, $35 ; 'sim65'
.byte 2 ; header version .byte 2 ; header version
.byte .defined(__SIM65C02__) ; CPU type .if (.cpu .bitand ::CPU_ISET_6502X)
.byte 2
.elseif (.cpu .bitand ::CPU_ISET_65C02)
.byte 1
.elseif (.cpu .bitand ::CPU_ISET_6502)
.byte 0
.else
.error Unknow CPU type.
.endif
.byte sp ; sp address .byte sp ; sp address
.addr __MAIN_START__ ; load address .addr __MAIN_START__ ; load address
.addr startup ; reset address .addr startup ; reset address

View File

@ -707,6 +707,24 @@ static void OneLine (void)
NextTok (); NextTok ();
} }
/* Handle @-style unnamed labels */
if (CurTok.Tok == TOK_ULABEL) {
if (CurTok.IVal != 0) {
Error ("Invalid unnamed label definition");
}
ULabDef ();
NextTok ();
/* Skip the colon. If NoColonLabels is enabled, allow labels without
** a colon if there is no whitespace before the identifier.
*/
if (CurTok.Tok == TOK_COLON) {
NextTok ();
} else if (CurTok.WS || !NoColonLabels) {
Error ("':' expected");
}
}
/* If the first token on the line is an identifier, check for a macro or /* If the first token on the line is an identifier, check for a macro or
** an instruction. ** an instruction.
*/ */

View File

@ -1124,17 +1124,33 @@ Again:
/* Local symbol? */ /* Local symbol? */
if (C == LocalStart) { if (C == LocalStart) {
/* Read the identifier. */ NextChar ();
ReadIdent ();
/* Start character alone is not enough */ if (IsIdChar (C)) {
if (SB_GetLen (&CurTok.SVal) == 1) { /* Read a local identifier */
Error ("Invalid cheap local symbol"); CurTok.Tok = TOK_LOCAL_IDENT;
goto Again; SB_AppendChar (&CurTok.SVal, LocalStart);
ReadIdent ();
} else {
/* Read an unnamed label */
CurTok.IVal = 0;
CurTok.Tok = TOK_ULABEL;
if (C == '-' || C == '<') {
int PrevC = C;
do {
--CurTok.IVal;
NextChar ();
} while (C == PrevC);
} else if (C == '+' || C == '>') {
int PrevC = C;
do {
++CurTok.IVal;
NextChar ();
} while (C == PrevC);
}
} }
/* A local identifier */
CurTok.Tok = TOK_LOCAL_IDENT;
return; return;
} }
@ -1314,22 +1330,30 @@ CharAgain:
break; break;
case '-': case '-':
case '<':
{
int PrevC = C;
CurTok.IVal = 0; CurTok.IVal = 0;
do { do {
--CurTok.IVal; --CurTok.IVal;
NextChar (); NextChar ();
} while (C == '-'); } while (C == PrevC);
CurTok.Tok = TOK_ULABEL; CurTok.Tok = TOK_ULABEL;
break; break;
}
case '+': case '+':
case '>':
{
int PrevC = C;
CurTok.IVal = 0; CurTok.IVal = 0;
do { do {
++CurTok.IVal; ++CurTok.IVal;
NextChar (); NextChar ();
} while (C == '+'); } while (C == PrevC);
CurTok.Tok = TOK_ULABEL; CurTok.Tok = TOK_ULABEL;
break; break;
}
case '=': case '=':
NextChar (); NextChar ();

View File

@ -71,7 +71,7 @@ typedef enum token_t {
TOK_REG, /* Sweet16 R.. register (in sweet16 mode) */ TOK_REG, /* Sweet16 R.. register (in sweet16 mode) */
TOK_ASSIGN, /* := */ TOK_ASSIGN, /* := */
TOK_ULABEL, /* :++ or :-- */ TOK_ULABEL, /* An unnamed label */
TOK_EQ, /* = */ TOK_EQ, /* = */
TOK_NE, /* <> */ TOK_NE, /* <> */

View File

@ -107,8 +107,12 @@ ExprNode* ULabRef (int Which)
int Index; int Index;
ULabel* L; ULabel* L;
/* Which can never be 0 */ /* Which should not be 0 */
PRECONDITION (Which != 0); if (Which == 0) {
Error ("Invalid unnamed label reference");
/* We must return something valid */
return GenCurrentPC();
}
/* Get the index of the referenced label */ /* Get the index of the referenced label */
if (Which > 0) { if (Which > 0) {

File diff suppressed because it is too large Load Diff

View File

@ -3272,7 +3272,7 @@ static void parsesub (ExprDesc* Expr)
/* The right hand side is constant. Check left hand side. */ /* The right hand side is constant. Check left hand side. */
if (ED_IsQuasiConst (Expr)) { if (ED_IsQuasiConst (Expr)) {
/* We can't do all 'ptr1 - ptr2' constantly at the moment */ /* We can't do all 'ptr1 - ptr2' constantly at the moment */
if (Expr->Sym == Expr2.Sym) { if (ED_GetLoc (Expr) == ED_GetLoc (&Expr2) && Expr->Sym == Expr2.Sym) {
Expr->IVal = (Expr->IVal - Expr2.IVal) / rscale; Expr->IVal = (Expr->IVal - Expr2.IVal) / rscale;
/* Get rid of unneeded flags etc. */ /* Get rid of unneeded flags etc. */
ED_MakeConstAbsInt (Expr, Expr->IVal); ED_MakeConstAbsInt (Expr, Expr->IVal);

View File

@ -231,9 +231,11 @@ static int findToken (const char * const *tokenTbl, const char *token)
/* takes as input table of tokens and token, returns position in table or -1 if not found */ /* takes as input table of tokens and token, returns position in table or -1 if not found */
int i; int i;
for (i = 0; tokenTbl[i][0]; i++) { if (token != NULL) {
if (strcmp (tokenTbl[i], token) == 0) { for (i = 0; tokenTbl[i][0]; i++) {
return i; if (strcmp (tokenTbl[i], token) == 0) {
return i;
}
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -47,7 +47,8 @@
/* Supported CPUs */ /* Supported CPUs */
typedef enum CPUType { typedef enum CPUType {
CPU_6502, CPU_6502,
CPU_65C02 CPU_65C02,
CPU_6502X
} CPUType; } CPUType;
/* Current CPU */ /* Current CPU */

View File

@ -177,10 +177,16 @@ static unsigned char ReadProgramFile (void)
/* Get the CPU type from the file header */ /* Get the CPU type from the file header */
if ((Val = fgetc(F)) != EOF) { if ((Val = fgetc(F)) != EOF) {
if (Val != CPU_6502 && Val != CPU_65C02) { switch (Val) {
case CPU_6502:
case CPU_65C02:
case CPU_6502X:
CPU = Val;
break;
default:
Error ("'%s': Invalid CPU type", ProgramFile); Error ("'%s': Invalid CPU type", ProgramFile);
} }
CPU = Val;
} }
/* Get the address of sp from the file header */ /* Get the address of sp from the file header */

View File

@ -12,23 +12,25 @@ endif
WORKDIR = ../testwrk/asm WORKDIR = ../testwrk/asm
SUBDIRS = cpudetect opcodes listing val err misc
.PHONY: all continue mostlyclean clean .PHONY: all continue mostlyclean clean
all: mostlyclean continue all: mostlyclean continue
define CALL_template continue: mostlyclean
@$(MAKE) -C cpudetect all
@$(MAKE) -C opcodes all
@$(MAKE) -C listing all
@$(MAKE) -C val all
@$(MAKE) -C err all
@$(MAKE) -C misc all
continue:: mostlyclean:
@$(MAKE) -C $1 all @$(MAKE) -C cpudetect clean
@$(MAKE) -C opcodes clean
mostlyclean:: @$(MAKE) -C listing clean
@$(MAKE) -C $1 clean @$(MAKE) -C val clean
@$(MAKE) -C err clean
endef @$(MAKE) -C misc clean
$(foreach subdir,$(SUBDIRS),$(eval $(call CALL_template,$(subdir))))
clean: mostlyclean clean: mostlyclean
@$(call RMDIR,$(WORKDIR)) @$(call RMDIR,$(WORKDIR))

View File

@ -0,0 +1,25 @@
; Test new-style (@:) and legacy-style (:) unnamed labels.
; Make sure that they have identical behavior.
.ORG $0000
@: nop
: nop
.ASSERT @<< = $0000, error
.ASSERT @-- = $0000, error
.ASSERT :<< = $0000, error
.ASSERT :-- = $0000, error
.ASSERT @< = $0001, error
.ASSERT @- = $0001, error
.ASSERT :< = $0001, error
.ASSERT :- = $0001, error
.ASSERT @> = $0002, error
.ASSERT @+ = $0002, error
.ASSERT :> = $0002, error
.ASSERT :+ = $0002, error
.ASSERT @>> = $0003, error
.ASSERT @++ = $0003, error
.ASSERT :>> = $0003, error
.ASSERT :++ = $0003, error
@: nop
: nop