mirror of https://github.com/cc65/cc65.git
Compare commits
37 Commits
5105fdaffa
...
f789316f86
Author | SHA1 | Date |
---|---|---|
Evgeny Vrublevsky | f789316f86 | |
Evgeny Vrublevsky | 270f3544b5 | |
Evgeny Vrublevsky | c500cb9086 | |
mrdudz | b993d88339 | |
Bob Andrews | 25967e65b5 | |
Bob Andrews | a372ead4de | |
Bob Andrews | 081d18f7d7 | |
Bob Andrews | a293920fb3 | |
Bob Andrews | 60c75bdb54 | |
Sven Michael Klose | 1fe12f112e | |
Sven Michael Klose | a887b29ffb | |
acqn | 731f349b24 | |
acqn | 98767741ce | |
acqn | 9b2d27d1e1 | |
acqn | 23aa562094 | |
Bob Andrews | 5c3ff714ae | |
Colin Leroy-Mira | 86317711e0 | |
Colin Leroy-Mira | 8b71fafb84 | |
Colin Leroy-Mira | 3fd78208ba | |
Colin Leroy-Mira | 7a12399b39 | |
Sven Michael Klose | 294b034920 | |
Stefan | ab0eb4fe58 | |
Stefan | 8d4946b3f4 | |
Sven Michael Klose | 3a7bd53956 | |
Sven Michael Klose | 8173c850fd | |
Bob Andrews | 4bde3afd80 | |
Alex Thissen | 7d6f3d24d4 | |
Alex Thissen | 8b172e05bc | |
Alex Thissen | 1deb9e52ae | |
Alex Thissen | acff429eb8 | |
Alex Thissen | 6cf8ee8eb5 | |
Alex Thissen | 65bce9ecde | |
Alex Thissen | 014f85f226 | |
Alex Thissen | 788ae82d30 | |
Carlo Bramini | b04d79b1da | |
mrdudz | 3dfe033000 | |
mrdudz | 5acfb02794 |
|
@ -19,7 +19,7 @@ jobs:
|
|||
- shell: bash
|
||||
run: git config --global core.autocrlf input
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Do some simple style checks
|
||||
shell: bash
|
||||
|
@ -44,7 +44,7 @@ jobs:
|
|||
shell: bash
|
||||
run: make -j2 doc
|
||||
- name: Upload a documents snapshot.
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: docs
|
||||
path: ./html
|
||||
|
@ -62,10 +62,10 @@ jobs:
|
|||
run: git config --global core.autocrlf input
|
||||
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Build app (x86 debug)
|
||||
run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug -property:Platform=Win32
|
||||
|
|
|
@ -18,10 +18,10 @@ jobs:
|
|||
run: git config --global core.autocrlf input
|
||||
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Build app (debug)
|
||||
run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug
|
||||
|
@ -44,7 +44,7 @@ jobs:
|
|||
- shell: bash
|
||||
run: git config --global core.autocrlf input
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Do some simple style checks
|
||||
shell: bash
|
||||
|
@ -86,18 +86,18 @@ jobs:
|
|||
mv cc65.zip cc65-snapshot-win32.zip
|
||||
|
||||
- name: Upload a 32-bit Snapshot Zip
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cc65-snapshot-win32
|
||||
path: cc65-snapshot-win32.zip
|
||||
- name: Upload a 64-bit Snapshot Zip
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cc65-snapshot-win64
|
||||
path: cc65-snapshot-win64.zip
|
||||
|
||||
- name: Get the online documents repo.
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: cc65/doc
|
||||
# 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.
|
||||
run: 7z a cc65-snapshot-docs.zip ./html/*.*
|
||||
- name: Upload a Documents Snapshot Zip
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cc65-snapshot-docs
|
||||
path: cc65-snapshot-docs.zip
|
||||
|
|
|
@ -30,7 +30,7 @@ jobs:
|
|||
run: mkdir ~/.cache-sha
|
||||
|
||||
- name: Cache SHA
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
id: check-sha
|
||||
with:
|
||||
path: ~/.cache-sha
|
||||
|
@ -43,11 +43,11 @@ jobs:
|
|||
|
||||
- name: Checkout source
|
||||
if: steps.check-sha.outputs.cache-hit != 'true'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
if: steps.check-sha.outputs.cache-hit != 'true'
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Build app (MSVC debug)
|
||||
if: steps.check-sha.outputs.cache-hit != 'true'
|
||||
|
|
|
@ -15,7 +15,7 @@ CPU_ISET_4510 = $0400
|
|||
CPU_NONE = CPU_ISET_NONE
|
||||
CPU_6502 = CPU_ISET_6502
|
||||
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_65C02 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02
|
||||
CPU_65816 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65816
|
||||
|
|
|
@ -259,30 +259,44 @@ SND_INTERRUPT = TIMER7_INTERRUPT
|
|||
|
||||
INTRST = $FD80
|
||||
INTSET = $FD81
|
||||
|
||||
MAGRDY0 = $FD84
|
||||
MAGRDY1 = $FD85
|
||||
AUDIN = $FD86
|
||||
SYSCTL1 = $FD87
|
||||
MIKEYHREV = $FD88
|
||||
MIKEYSREV = $FD89
|
||||
IODIR = $FD8A
|
||||
IODAT = $FD8B
|
||||
TxIntEnable = %10000000
|
||||
RxIntEnable = %01000000
|
||||
TxParEnable = %00010000
|
||||
ResetErr = %00001000
|
||||
TxOpenColl = %00000100
|
||||
TxBreak = %00000010
|
||||
ParEven = %00000001
|
||||
TxReady = %10000000
|
||||
RxReady = %01000000
|
||||
TxEmpty = %00100000
|
||||
RxParityErr = %00010000
|
||||
RxOverrun = %00001000
|
||||
RxFrameErr = %00000100
|
||||
RxBreak = %00000010
|
||||
ParityBit = %00000001
|
||||
SERCTL = $FD8C
|
||||
|
||||
IODIR = $FD8A
|
||||
IODAT = $FD8B
|
||||
; IODIR and IODAT bit definitions
|
||||
AUDIN_BIT = $10 ; Note that there is also the address AUDIN
|
||||
READ_ENABLE = $10 ; Same bit for AUDIN_BIT
|
||||
RESTLESS = $08
|
||||
NOEXP = $04 ; If set, redeye is not connected
|
||||
CART_ADDR_DATA = $02
|
||||
CART_POWER_OFF = $02 ; Same bit for CART_ADDR_DATA
|
||||
EXTERNAL_POWER = $01
|
||||
|
||||
SERCTL = $FD8C
|
||||
; SERCTL bit definitions for write operations
|
||||
TXINTEN = $80
|
||||
RXINTEN = $40
|
||||
PAREN = $10
|
||||
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
|
||||
SDONEACK = $FD90
|
||||
CPUSLEEP = $FD91
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
# Assembly program configuration for unexpanded VICs.
|
||||
|
||||
FEATURES {
|
||||
STARTADDRESS: default = $1001;
|
||||
}
|
||||
|
@ -7,7 +9,7 @@ SYMBOLS {
|
|||
MEMORY {
|
||||
ZP: file = "", start = $0002, size = $001A, define = yes;
|
||||
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 {
|
||||
ZEROPAGE: load = ZP, type = zp, optional = yes;
|
||||
|
|
|
@ -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
|
||||
aren't reachable because the ROM and ProDOS IRQ handlers are too slow.
|
||||
Software flow control (XON/XOFF) is not supported.
|
||||
|
||||
Note that because of the peculiarities of the 6551 chip transmits are not
|
||||
interrupt driven, and the transceiver blocks if the receiver asserts
|
||||
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
|
||||
<tt/ser_open()/ in order to select a different slot. <tt/ser_apple2_slot()/
|
||||
succeeds for all Apple II slots, but <tt/ser_open()/ fails with
|
||||
|
|
|
@ -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
|
||||
aren't reachable because the ROM and ProDOS IRQ handlers are too slow.
|
||||
Software flow control (XON/XOFF) is not supported.
|
||||
|
||||
Note that because of the peculiarities of the 6551 chip transmits are not
|
||||
interrupt driven, and the transceiver blocks if the receiver asserts
|
||||
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
|
||||
<tt/ser_open()/ in order to select a different slot. <tt/ser_apple2_slot()/
|
||||
succeeds for all Apple II slots, but <tt/ser_open()/ fails with
|
||||
|
|
|
@ -829,49 +829,42 @@ names like "Loop". Here is an example:
|
|||
bne @Loop ; ERROR: Unknown identifier!
|
||||
</verb></tscreen>
|
||||
|
||||
|
||||
<sect1>Unnamed labels<p>
|
||||
|
||||
If you really want to write messy code, there are also unnamed labels. These
|
||||
labels do not have a name (you guessed that already, didn't you?). A colon is
|
||||
used to mark the absence of the name.
|
||||
If you really want to write messy code, there are also unnamed labels. To define
|
||||
an unnamed label, use either <tt>@:</tt> (<tt>.LOCALCHAR</tt> is respected if it
|
||||
is set) or sole <tt>:</tt>.
|
||||
|
||||
Unnamed labels may be accessed by using the colon plus several minus or plus
|
||||
characters as a label designator. Using the '-' characters will create a back
|
||||
reference (use the n'th label backwards), using '+' will create a forward
|
||||
reference (use the n'th label in forward direction). An example will help to
|
||||
understand this:
|
||||
To reference an unnamed label, use <tt>@</tt> (<tt>.LOCALCHAR</tt> is respected
|
||||
if it is set) or <tt>:</tt> with several <tt>-</tt> or <tt>+</tt> characters.
|
||||
The <tt>-</tt> characters will create a back reference (n'th label backwards),
|
||||
the <tt>+</tt> will create a forward reference (n'th label in forward direction).
|
||||
As an alternative, angle brackets <tt><</tt> and <tt>></tt> may be used
|
||||
instead of <tt>-</tt> and <tt>+</tt> with the same meaning.
|
||||
|
||||
Example:
|
||||
|
||||
<tscreen><verb>
|
||||
: lda (ptr1),y ; #1
|
||||
cmp (ptr2),y
|
||||
bne :+ ; -> #2
|
||||
tax
|
||||
beq :+++ ; -> #4
|
||||
iny
|
||||
bne :- ; -> #1
|
||||
inc ptr1+1
|
||||
inc ptr2+1
|
||||
bne :- ; -> #1
|
||||
|
||||
: bcs :+ ; #2 -> #3
|
||||
ldx #$FF
|
||||
rts
|
||||
|
||||
: ldx #$01 ; #3
|
||||
: rts ; #4
|
||||
cpy #0
|
||||
beq @++
|
||||
@:
|
||||
sta $2007
|
||||
dey
|
||||
bne @-
|
||||
@:
|
||||
rts
|
||||
</verb></tscreen>
|
||||
|
||||
As you can see from the example, unnamed labels will make even short
|
||||
sections of code hard to understand, because you have to count labels
|
||||
to find branch targets (this is the reason why I for my part do
|
||||
prefer the "cheap" local labels). Nevertheless, unnamed labels are
|
||||
convenient in some situations, so it's your decision.
|
||||
Unnamed labels may make even short sections of code hard to understand, because
|
||||
you have to count labels to find branch targets. It's better to prefer the
|
||||
"cheap" local labels. Nevertheless, unnamed labels are convenient in some
|
||||
situations, so it's up to your discretion.
|
||||
|
||||
<em/Note:/ <ref id="scopes" name="Scopes"> organize named symbols, not
|
||||
unnamed ones, so scopes don't have an effect on unnamed labels.
|
||||
|
||||
|
||||
|
||||
<sect1>Using macros to define labels and constants<p>
|
||||
|
||||
While there are drawbacks with this approach, it may be handy in a few rare
|
||||
|
|
|
@ -66,34 +66,16 @@ HSType: .res 1 ; Flow-control type
|
|||
RecvBuf: .res 256 ; Receive buffers: 256 bytes
|
||||
SendBuf: .res 256 ; Send buffers: 256 bytes
|
||||
|
||||
CurClockSource: .res 1 ; Whether to use BRG or RTxC for clock
|
||||
|
||||
.data
|
||||
|
||||
Opened: .byte $00 ; 1 when opened
|
||||
Channel: .byte $00 ; Channel B by default
|
||||
CurChanIrqFlags:.byte INTR_PENDING_RX_EXT_B
|
||||
CurChanIrqFlags:.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)
|
||||
.byte %10000000 ; SER_BITS_6 (Ref page 5-7)
|
||||
.byte %01000000 ; SER_BITS_7
|
||||
|
@ -106,29 +88,65 @@ TxBitTable: .byte %00000000 ; SER_BITS_5, in WR_TX_CTRL (WR5)
|
|||
|
||||
.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
|
||||
; Otherwise refers to the index in
|
||||
; Baud(Low/High)Table
|
||||
.byte $FF ; SER_BAUD_45_5
|
||||
.byte $FF ; SER_BAUD_50
|
||||
.byte $FF ; SER_BAUD_75
|
||||
.byte $FF ; SER_BAUD_110
|
||||
.byte $FF ; SER_BAUD_134_5
|
||||
.byte $FF ; SER_BAUD_150
|
||||
.byte $00 ; SER_BAUD_300
|
||||
.byte $FF ; SER_BAUD_600
|
||||
.byte $01 ; SER_BAUD_1200
|
||||
.byte $FF ; SER_BAUD_1800
|
||||
.byte $02 ; SER_BAUD_2400
|
||||
.byte $FF ; SER_BAUD_3600
|
||||
.byte $03 ; SER_BAUD_4800
|
||||
.byte $FF ; SER_BAUD_7200
|
||||
.byte $04 ; SER_BAUD_9600
|
||||
.byte $05 ; SER_BAUD_19200
|
||||
.byte $06 ; SER_BAUD_38400
|
||||
.byte $07 ; SER_BAUD_57600
|
||||
.byte $FF ; SER_BAUD_115200
|
||||
.byte $FF ; SER_BAUD_230400
|
||||
; Indexes cc65 RS232 SER_BAUD enum
|
||||
; into WR12/13 register values
|
||||
; (Ref page 5-18 and 5-19)
|
||||
.word $FFFF ; SER_BAUD_45_5
|
||||
.word $FFFF ; SER_BAUD_50
|
||||
.word $FFFF ; SER_BAUD_75
|
||||
.word $FFFF ; SER_BAUD_110
|
||||
.word $FFFF ; SER_BAUD_134_5
|
||||
.word $FFFF ; SER_BAUD_150
|
||||
.word $017E ; SER_BAUD_300
|
||||
.word $FFFF ; SER_BAUD_600
|
||||
.word $005E ; SER_BAUD_1200
|
||||
.word $FFFF ; SER_BAUD_1800
|
||||
.word $002E ; SER_BAUD_2400
|
||||
.word $FFFF ; SER_BAUD_3600
|
||||
.word $0016 ; SER_BAUD_4800
|
||||
.word $FFFF ; SER_BAUD_7200
|
||||
.word $000A ; SER_BAUD_9600
|
||||
.word $0004 ; SER_BAUD_19200
|
||||
.word $0001 ; SER_BAUD_38400
|
||||
.word $0000 ; SER_BAUD_57600
|
||||
.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)
|
||||
.byte %00001100 ; SER_STOP_2 (Ref page 5-8)
|
||||
|
@ -156,6 +174,7 @@ SER_FLAG := $E10104
|
|||
|
||||
; ------------------------------------------------------------------------
|
||||
; Channels
|
||||
|
||||
CHANNEL_B = 0
|
||||
CHANNEL_A = 1
|
||||
|
||||
|
@ -180,7 +199,6 @@ RX_CTRL_OFF = %11111110 ; ANDed,Rx disabled
|
|||
|
||||
WR_TX_RX_CTRL = 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)
|
||||
RR_TX_STATUS = 5 ; Corresponding status register
|
||||
|
@ -197,15 +215,11 @@ MASTER_IRQ_MIE_RST = %00001010 ; STA'd
|
|||
MASTER_IRQ_SET = %00011001 ; STA'd
|
||||
|
||||
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_BAUDH_CTRL = 13 ; (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)
|
||||
IRQ_CLEANUP_EIRQ = %00001000
|
||||
|
@ -220,13 +234,8 @@ IRQ_RX = %00100000
|
|||
IRQ_SPECIAL = %01100000
|
||||
|
||||
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)
|
||||
|
||||
SER_FLAG_CH_A = %00111000
|
||||
SER_FLAG_CH_B = %00000111
|
||||
|
||||
.code
|
||||
|
||||
; Read register value to A.
|
||||
|
@ -329,6 +338,15 @@ IIgs:
|
|||
: txa ; Promote char return value
|
||||
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.
|
||||
; 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
|
||||
jsr readSSCReg
|
||||
|
||||
ldy #WR_MISC_CTRL ; Turn everything off
|
||||
ldy #WR_MISC_CTRL ; WR14: Turn everything off
|
||||
lda #$00
|
||||
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
|
||||
tay
|
||||
lda StopTable,y ; Get value
|
||||
|
@ -377,36 +397,33 @@ SER_OPEN:
|
|||
ora ParityTable,y ; Get value
|
||||
bmi InvParam
|
||||
|
||||
ora #TX_RX_CLOCK_MUL
|
||||
ldy CurClockSource ; Clock multiplier
|
||||
ora ClockMultiplier,y
|
||||
|
||||
ldy #WR_TX_RX_CTRL ; Setup stop & parity bits
|
||||
jsr writeSCCReg
|
||||
ldy #WR_TX_RX_CTRL
|
||||
jsr writeSCCReg ; End of WR4 setup
|
||||
|
||||
ldy CurClockSource ; WR11 setup: clock source
|
||||
cpx #CHANNEL_B
|
||||
bne ClockA
|
||||
ClockB:
|
||||
beq SetClock
|
||||
iny ; Shift to get correct ClockSource val
|
||||
iny ; depending on our channel
|
||||
|
||||
SetClock:
|
||||
lda ClockSource,y
|
||||
ldy #WR_CLOCK_CTRL
|
||||
lda #CLOCK_CTRL_CH_B
|
||||
jsr writeSCCReg
|
||||
jsr writeSCCReg ; End of WR11 setup
|
||||
|
||||
lda #INTR_PENDING_RX_EXT_B ; 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
|
||||
lda ChanIrqFlags,x ; Store which IRQ bits we'll check
|
||||
sta CurChanIrqFlags
|
||||
|
||||
SetBaud:
|
||||
ldy #SER_PARAMS::BAUDRATE
|
||||
lda (ptr1),y ; Baudrate index - cc65 value
|
||||
.assert SER_PARAMS::BAUDRATE = 0, error
|
||||
lda (ptr1) ; Baudrate index - cc65 value
|
||||
asl
|
||||
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
|
||||
|
||||
InvParam:
|
||||
|
@ -415,59 +432,57 @@ InvParam:
|
|||
bra SetupOut
|
||||
|
||||
BaudOK:
|
||||
tay
|
||||
|
||||
lda BaudLowTable,y ; Get low byte
|
||||
|
||||
phy
|
||||
ldy #WR_BAUDL_CTRL
|
||||
jsr writeSCCReg
|
||||
phy ; WR12 setup: BRG time constant, low byte
|
||||
ldy #WR_BAUDL_CTRL ; Setting WR12 & 13 is useless if we're using
|
||||
jsr writeSCCReg ; RTxC, but doing it anyway makes code smaller
|
||||
ply
|
||||
|
||||
lda BaudHighTable,y ; Get high byte
|
||||
iny
|
||||
lda BaudTable,y ; WR13 setup: BRG time constant, high byte
|
||||
ldy #WR_BAUDH_CTRL
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy CurClockSource ; WR14 setup: BRG enabling
|
||||
lda BrgEnabled,y
|
||||
ldy #WR_MISC_CTRL ; Time to turn this thing on
|
||||
lda #MISC_CTRL_RATE_GEN_ON
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy #SER_PARAMS::DATABITS
|
||||
lda (ptr1),y ; Data bits
|
||||
ldy #SER_PARAMS::DATABITS ; WR3 setup: RX data bits
|
||||
lda (ptr1),y
|
||||
tay
|
||||
lda RxBitTable,y ; Data bits for RX
|
||||
ora #RX_CTRL_ON ; and turn RX on
|
||||
lda RxBitTable,y
|
||||
ora #RX_CTRL_ON ; and turn receiver on
|
||||
|
||||
phy
|
||||
ldy #WR_RX_CTRL
|
||||
jsr writeSCCReg
|
||||
jsr writeSCCReg ; End of WR3 setup
|
||||
ply
|
||||
|
||||
lda TxBitTable,y ; Data bits for TX
|
||||
ora #TX_CTRL_ON ; and turn TX on
|
||||
and #TX_DTR_ON
|
||||
lda TxBitTable,y ; WR5 setup: TX data bits
|
||||
ora #TX_CTRL_ON ; and turn transmitter on
|
||||
and #TX_DTR_ON ; and turn DTR on
|
||||
|
||||
sta RtsOff ; Save value for flow control
|
||||
|
||||
ora #TX_RTS_ON
|
||||
ora #TX_RTS_ON ; and turn RTS on
|
||||
|
||||
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
|
||||
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
|
||||
jsr writeSCCReg
|
||||
jsr writeSCCReg ; Clear (write twice)
|
||||
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
|
||||
jsr writeSCCReg
|
||||
|
||||
lda SCCBREG ; Activate master IRQ
|
||||
lda SCCBREG ; WR9 setup: Activate master IRQ
|
||||
ldy #WR_MASTER_IRQ_RST
|
||||
lda #MASTER_IRQ_SET
|
||||
jsr writeSCCReg
|
||||
|
@ -475,14 +490,7 @@ BaudOK:
|
|||
lda SER_FLAG ; Get SerFlag's current value
|
||||
sta SerFlagOrig ; and save it
|
||||
|
||||
cpx #CHANNEL_B
|
||||
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:
|
||||
ora ChanIrqMask,x ; Tell firmware which channel IRQs we want
|
||||
sta SER_FLAG
|
||||
|
||||
ldy #$01 ; Mark port opened
|
||||
|
|
|
@ -121,7 +121,7 @@ BaudTable: ; Table used to translate RS232 baudrate param
|
|||
.byte $0F ; SER_BAUD_19200
|
||||
.byte $FF ; SER_BAUD_38400
|
||||
.byte $FF ; SER_BAUD_57600
|
||||
.byte $FF ; SER_BAUD_115200
|
||||
.byte $00 ; SER_BAUD_115200
|
||||
.byte $FF ; SER_BAUD_230400
|
||||
|
||||
BitTable: ; Table used to translate RS232 databits param
|
||||
|
@ -302,6 +302,7 @@ HandshakeOK:
|
|||
lda (ptr1),y ; Baudrate index
|
||||
tay
|
||||
lda BaudTable,y ; Get 6551 value
|
||||
sta tmp2 ; Backup for IRQ setting
|
||||
bpl BaudOK ; Check that baudrate is supported
|
||||
|
||||
lda #SER_ERR_BAUD_UNAVAIL
|
||||
|
@ -332,8 +333,13 @@ BaudOK: sta tmp1
|
|||
|
||||
ora #%00000001 ; Set DTR active
|
||||
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
|
||||
stx Index ; Mark port as open
|
||||
|
|
|
@ -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.
|
||||
|
||||
lda #%00011101
|
||||
lda #PAREN|RESETERR|TXOPEN|PAREVEN ; #%00011101
|
||||
sta SERCTL
|
||||
|
||||
; Clear all pending interrupts.
|
||||
|
|
|
@ -73,7 +73,12 @@ SER_UNINSTALL:
|
|||
; Must return an SER_ERR_xx code in a/x.
|
||||
|
||||
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
|
||||
lda #SER_ERR_OK
|
||||
.assert SER_ERR_OK = 0, error
|
||||
|
@ -108,17 +113,17 @@ SER_OPEN:
|
|||
stz TxPtrIn
|
||||
stz TxPtrOut
|
||||
|
||||
; clock = 8 * 15625
|
||||
lda #%00011000
|
||||
sta TIM4CTLA
|
||||
ldy #SER_PARAMS::BAUDRATE
|
||||
lda (ptr1),y
|
||||
|
||||
; Source period is 1 us
|
||||
ldy #%00011000 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_1
|
||||
|
||||
ldx #1
|
||||
cmp #SER_BAUD_62500
|
||||
beq setbaudrate
|
||||
|
||||
ldx #2
|
||||
ldx #3
|
||||
cmp #SER_BAUD_31250
|
||||
beq setbaudrate
|
||||
|
||||
|
@ -134,6 +139,10 @@ SER_OPEN:
|
|||
cmp #SER_BAUD_2400
|
||||
beq setbaudrate
|
||||
|
||||
ldx #68
|
||||
cmp #SER_BAUD_1800
|
||||
beq setbaudrate
|
||||
|
||||
ldx #103
|
||||
cmp #SER_BAUD_1200
|
||||
beq setbaudrate
|
||||
|
@ -142,65 +151,22 @@ SER_OPEN:
|
|||
cmp #SER_BAUD_600
|
||||
beq setbaudrate
|
||||
|
||||
; clock = 6 * 15625
|
||||
ldx #%00011010
|
||||
stx TIM4CTLA
|
||||
; Source period is 8 us
|
||||
ldy #%00011011 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_8
|
||||
|
||||
ldx #12
|
||||
cmp #SER_BAUD_7200
|
||||
beq setbaudrate
|
||||
|
||||
ldx #25
|
||||
cmp #SER_BAUD_3600
|
||||
beq setbaudrate
|
||||
|
||||
ldx #207
|
||||
stx TIM4BKUP
|
||||
|
||||
; clock = 4 * 15625
|
||||
ldx #%00011100
|
||||
ldx #51
|
||||
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
|
||||
|
||||
lda #SER_ERR_BAUD_UNAVAIL
|
||||
ldx #0 ; return value is char
|
||||
rts
|
||||
setprescaler:
|
||||
stx TIM4CTLA
|
||||
bra baudsuccess
|
||||
|
||||
setbaudrate:
|
||||
sty TIM4CTLA
|
||||
stx TIM4BKUP
|
||||
baudsuccess:
|
||||
ldx #TxOpenColl|ParEven
|
||||
|
||||
ldx #TXOPEN|PAREVEN
|
||||
stx contrl
|
||||
ldy #SER_PARAMS::DATABITS ; Databits
|
||||
lda (ptr1),y
|
||||
|
@ -218,15 +184,15 @@ baudsuccess:
|
|||
beq checkhs
|
||||
cmp #SER_PAR_SPACE
|
||||
bne @L0
|
||||
ldx #TxOpenColl
|
||||
ldx #TXOPEN
|
||||
stx contrl
|
||||
bra checkhs
|
||||
@L0:
|
||||
ldx #TxParEnable|TxOpenColl|ParEven
|
||||
ldx #PAREN|TXOPEN|PAREVEN
|
||||
stx contrl
|
||||
cmp #SER_PAR_EVEN
|
||||
beq checkhs
|
||||
ldx #TxParEnable|TxOpenColl
|
||||
ldx #PAREN|TXOPEN
|
||||
stx contrl
|
||||
checkhs:
|
||||
ldx contrl
|
||||
|
@ -234,15 +200,27 @@ checkhs:
|
|||
ldy #SER_PARAMS::HANDSHAKE ; Handshake
|
||||
lda (ptr1),y
|
||||
cmp #SER_HS_NONE
|
||||
beq redeye_ok
|
||||
cmp #SER_HS_SW ; Software handshake will check for connected redeye
|
||||
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 contrl
|
||||
ora #RxIntEnable|ResetErr
|
||||
ora #RXINTEN|RESETERR ; Turn on interrupts for receive
|
||||
sta SERCTL
|
||||
lda #SER_ERR_OK
|
||||
.assert SER_ERR_OK = 0, error
|
||||
tax
|
||||
rts
|
||||
|
||||
invparameter:
|
||||
lda #SER_ERR_INIT_FAILED
|
||||
ldx #0 ; return value is char
|
||||
|
@ -264,8 +242,8 @@ GetByte:
|
|||
ldy RxPtrOut
|
||||
lda RxBuffer,y
|
||||
inc RxPtrOut
|
||||
sta (ptr1)
|
||||
ldx #$00
|
||||
sta (ptr1,x)
|
||||
txa ; Return code = 0
|
||||
rts
|
||||
|
||||
|
@ -279,24 +257,26 @@ SER_PUT:
|
|||
ina
|
||||
cmp TxPtrOut
|
||||
bne PutByte
|
||||
|
||||
lda #SER_ERR_OVERFLOW
|
||||
ldx #0 ; return value is char
|
||||
rts
|
||||
|
||||
PutByte:
|
||||
ldy TxPtrIn
|
||||
txa
|
||||
sta TxBuffer,y
|
||||
inc TxPtrIn
|
||||
|
||||
bit TxDone
|
||||
bmi @L1
|
||||
bit TxDone ; Check bit 7 of TxDone (TXINTEN)
|
||||
bmi @L1 ; Was TXINTEN already set?
|
||||
php
|
||||
sei
|
||||
lda contrl
|
||||
ora #TxIntEnable|ResetErr
|
||||
sta SERCTL ; Allow TX-IRQ to hang RX-IRQ
|
||||
lda contrl ; contrl does not include RXINTEN setting
|
||||
ora #TXINTEN|RESETERR
|
||||
sta SERCTL ; Allow TX-IRQ to hang RX-IRQ (no receive while transmitting)
|
||||
sta TxDone
|
||||
plp
|
||||
plp ; Restore processor and interrupt enable
|
||||
@L1:
|
||||
lda #SER_ERR_OK
|
||||
.assert SER_ERR_OK = 0, error
|
||||
|
@ -308,9 +288,9 @@ PutByte:
|
|||
; Must return an SER_ERR_xx code in a/x.
|
||||
|
||||
SER_STATUS:
|
||||
ldy SerialStat
|
||||
lda SerialStat
|
||||
sta (ptr1)
|
||||
ldx #$00
|
||||
sta (ptr1,x)
|
||||
txa ; Return code = 0
|
||||
rts
|
||||
|
||||
|
@ -342,48 +322,56 @@ SER_IRQ:
|
|||
@L0:
|
||||
bit TxDone
|
||||
bmi @tx_irq ; Transmit in progress
|
||||
ldx SERDAT
|
||||
lda SERCTL
|
||||
and #RxParityErr|RxOverrun|RxFrameErr|RxBreak
|
||||
beq @rx_irq
|
||||
|
||||
ldx SERDAT ; Read received data
|
||||
lda contrl
|
||||
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
|
||||
bit #RxBreak
|
||||
bit #RXBRK ; Check for break signal
|
||||
beq @noBreak
|
||||
|
||||
stz TxPtrIn ; Break received - drop buffers
|
||||
stz TxPtrOut
|
||||
stz RxPtrIn
|
||||
stz RxPtrOut
|
||||
@noBreak:
|
||||
lda contrl
|
||||
ora #RxIntEnable|ResetErr
|
||||
sta SERCTL
|
||||
lda #$10
|
||||
sta INTRST
|
||||
bra @IRQexit
|
||||
bra @exit0
|
||||
|
||||
@rx_irq:
|
||||
tya
|
||||
bne @2 ; Parity was enabled so no marker bit check needed
|
||||
|
||||
lda contrl
|
||||
ora #RxIntEnable|ResetErr
|
||||
sta SERCTL
|
||||
eor SERCTL ; Should match current parity bit
|
||||
and #PARBIT ; Check for mark or space value
|
||||
bne @exit0
|
||||
|
||||
@2:
|
||||
txa
|
||||
ldx RxPtrIn
|
||||
sta RxBuffer,x
|
||||
txa
|
||||
inx
|
||||
|
||||
@cont0:
|
||||
cpx RxPtrOut
|
||||
beq @1
|
||||
stx RxPtrIn
|
||||
lda #SERIAL_INTERRUPT
|
||||
sta INTRST
|
||||
bra @IRQexit
|
||||
|
||||
@1:
|
||||
sta RxPtrIn
|
||||
lda #$80
|
||||
tsb SerialStat
|
||||
bra @exit0
|
||||
|
||||
@tx_irq:
|
||||
ldx TxPtrOut ; Has all bytes been sent?
|
||||
ldx TxPtrOut ; Have all bytes been sent?
|
||||
cpx TxPtrIn
|
||||
beq @allSent
|
||||
|
||||
|
@ -393,24 +381,24 @@ SER_IRQ:
|
|||
|
||||
@exit1:
|
||||
lda contrl
|
||||
ora #TxIntEnable|ResetErr
|
||||
ora #TXINTEN|RESETERR
|
||||
sta SERCTL
|
||||
lda #SERIAL_INTERRUPT
|
||||
sta INTRST
|
||||
bra @IRQexit
|
||||
|
||||
@allSent:
|
||||
lda SERCTL ; All bytes sent
|
||||
bit #TxEmpty
|
||||
bit #TXEMPTY
|
||||
beq @exit1
|
||||
bvs @exit1
|
||||
stz TxDone
|
||||
|
||||
@exit0:
|
||||
lda contrl
|
||||
ora #RxIntEnable|ResetErr
|
||||
ora #RXINTEN|RESETERR ; Re-enable receive interrupt
|
||||
sta SERCTL
|
||||
|
||||
@IRQexit:
|
||||
lda #SERIAL_INTERRUPT
|
||||
sta INTRST
|
||||
@IRQexit:
|
||||
clc
|
||||
rts
|
||||
|
|
|
@ -40,14 +40,14 @@ cont1:
|
|||
bra loop1
|
||||
|
||||
read_byte:
|
||||
bit SERCTL
|
||||
bit SERCTL ; Check for RXRDY ($40)
|
||||
bvc read_byte
|
||||
lda SERDAT
|
||||
rts
|
||||
|
||||
_UpLoaderIRQ:
|
||||
lda INTSET
|
||||
and #$10
|
||||
and #SERIAL_INTERRUPT
|
||||
bne @L0
|
||||
clc
|
||||
rts
|
||||
|
@ -69,7 +69,7 @@ again:
|
|||
; last action : clear interrupt
|
||||
;
|
||||
exit:
|
||||
lda #$10
|
||||
lda #SERIAL_INTERRUPT
|
||||
sta INTRST
|
||||
clc
|
||||
rts
|
||||
|
|
|
@ -9,11 +9,21 @@
|
|||
.import __MAIN_START__
|
||||
.import startup
|
||||
|
||||
.macpack cpu
|
||||
|
||||
.segment "EXEHDR"
|
||||
|
||||
.byte $73, $69, $6D, $36, $35 ; 'sim65'
|
||||
.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
|
||||
.addr __MAIN_START__ ; load address
|
||||
.addr startup ; reset address
|
||||
|
|
|
@ -707,6 +707,24 @@ static void OneLine (void)
|
|||
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
|
||||
** an instruction.
|
||||
*/
|
||||
|
|
|
@ -1124,17 +1124,33 @@ Again:
|
|||
/* Local symbol? */
|
||||
if (C == LocalStart) {
|
||||
|
||||
/* Read the identifier. */
|
||||
ReadIdent ();
|
||||
NextChar ();
|
||||
|
||||
/* Start character alone is not enough */
|
||||
if (SB_GetLen (&CurTok.SVal) == 1) {
|
||||
Error ("Invalid cheap local symbol");
|
||||
goto Again;
|
||||
if (IsIdChar (C)) {
|
||||
/* Read a local identifier */
|
||||
CurTok.Tok = TOK_LOCAL_IDENT;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1314,22 +1330,30 @@ CharAgain:
|
|||
break;
|
||||
|
||||
case '-':
|
||||
case '<':
|
||||
{
|
||||
int PrevC = C;
|
||||
CurTok.IVal = 0;
|
||||
do {
|
||||
--CurTok.IVal;
|
||||
NextChar ();
|
||||
} while (C == '-');
|
||||
} while (C == PrevC);
|
||||
CurTok.Tok = TOK_ULABEL;
|
||||
break;
|
||||
}
|
||||
|
||||
case '+':
|
||||
case '>':
|
||||
{
|
||||
int PrevC = C;
|
||||
CurTok.IVal = 0;
|
||||
do {
|
||||
++CurTok.IVal;
|
||||
NextChar ();
|
||||
} while (C == '+');
|
||||
} while (C == PrevC);
|
||||
CurTok.Tok = TOK_ULABEL;
|
||||
break;
|
||||
}
|
||||
|
||||
case '=':
|
||||
NextChar ();
|
||||
|
|
|
@ -71,7 +71,7 @@ typedef enum token_t {
|
|||
TOK_REG, /* Sweet16 R.. register (in sweet16 mode) */
|
||||
|
||||
TOK_ASSIGN, /* := */
|
||||
TOK_ULABEL, /* :++ or :-- */
|
||||
TOK_ULABEL, /* An unnamed label */
|
||||
|
||||
TOK_EQ, /* = */
|
||||
TOK_NE, /* <> */
|
||||
|
|
|
@ -107,8 +107,12 @@ ExprNode* ULabRef (int Which)
|
|||
int Index;
|
||||
ULabel* L;
|
||||
|
||||
/* Which can never be 0 */
|
||||
PRECONDITION (Which != 0);
|
||||
/* Which should not be 0 */
|
||||
if (Which == 0) {
|
||||
Error ("Invalid unnamed label reference");
|
||||
/* We must return something valid */
|
||||
return GenCurrentPC();
|
||||
}
|
||||
|
||||
/* Get the index of the referenced label */
|
||||
if (Which > 0) {
|
||||
|
|
1048
src/cc65/declare.c
1048
src/cc65/declare.c
File diff suppressed because it is too large
Load Diff
|
@ -3272,7 +3272,7 @@ static void parsesub (ExprDesc* Expr)
|
|||
/* The right hand side is constant. Check left hand side. */
|
||||
if (ED_IsQuasiConst (Expr)) {
|
||||
/* 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;
|
||||
/* Get rid of unneeded flags etc. */
|
||||
ED_MakeConstAbsInt (Expr, Expr->IVal);
|
||||
|
|
|
@ -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 */
|
||||
int i;
|
||||
|
||||
for (i = 0; tokenTbl[i][0]; i++) {
|
||||
if (strcmp (tokenTbl[i], token) == 0) {
|
||||
return i;
|
||||
if (token != NULL) {
|
||||
for (i = 0; tokenTbl[i][0]; i++) {
|
||||
if (strcmp (tokenTbl[i], token) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2703
src/sim65/6502.c
2703
src/sim65/6502.c
File diff suppressed because it is too large
Load Diff
|
@ -47,7 +47,8 @@
|
|||
/* Supported CPUs */
|
||||
typedef enum CPUType {
|
||||
CPU_6502,
|
||||
CPU_65C02
|
||||
CPU_65C02,
|
||||
CPU_6502X
|
||||
} CPUType;
|
||||
|
||||
/* Current CPU */
|
||||
|
|
|
@ -177,10 +177,16 @@ static unsigned char ReadProgramFile (void)
|
|||
|
||||
/* Get the CPU type from the file header */
|
||||
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);
|
||||
}
|
||||
CPU = Val;
|
||||
}
|
||||
|
||||
/* Get the address of sp from the file header */
|
||||
|
|
|
@ -12,23 +12,25 @@ endif
|
|||
|
||||
WORKDIR = ../testwrk/asm
|
||||
|
||||
SUBDIRS = cpudetect opcodes listing val err misc
|
||||
|
||||
.PHONY: all continue mostlyclean clean
|
||||
|
||||
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::
|
||||
@$(MAKE) -C $1 all
|
||||
|
||||
mostlyclean::
|
||||
@$(MAKE) -C $1 clean
|
||||
|
||||
endef
|
||||
|
||||
$(foreach subdir,$(SUBDIRS),$(eval $(call CALL_template,$(subdir))))
|
||||
mostlyclean:
|
||||
@$(MAKE) -C cpudetect clean
|
||||
@$(MAKE) -C opcodes clean
|
||||
@$(MAKE) -C listing clean
|
||||
@$(MAKE) -C val clean
|
||||
@$(MAKE) -C err clean
|
||||
@$(MAKE) -C misc clean
|
||||
|
||||
clean: mostlyclean
|
||||
@$(call RMDIR,$(WORKDIR))
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue