From dd2972d6999aa93891d9e13cbcbe0673a0e49ab5 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 28 Feb 2016 22:23:40 +0100 Subject: [PATCH 001/707] initial commit from old source --- libsrc/atari/cpeekchar.s | 41 ++++++++++++++++++++++ libsrc/atmos/cpeekchar.s | 36 +++++++++++++++++++ libsrc/c128/cpeekchar.s | 74 +++++++++++++++++++++++++++++++++++++++ libsrc/c128/cpeekcol.s | 67 +++++++++++++++++++++++++++++++++++ libsrc/cbm/cpeekchar.s | 39 +++++++++++++++++++++ libsrc/cbm/cpeekcol.s | 21 +++++++++++ libsrc/cbm510/cpeekchar.s | 32 +++++++++++++++++ libsrc/cbm510/cpeekcol.s | 31 ++++++++++++++++ libsrc/cbm610/cpeekchar.s | 45 ++++++++++++++++++++++++ libsrc/nes/cpeekchar.s | 40 +++++++++++++++++++++ 10 files changed, 426 insertions(+) create mode 100644 libsrc/atari/cpeekchar.s create mode 100644 libsrc/atmos/cpeekchar.s create mode 100644 libsrc/c128/cpeekchar.s create mode 100644 libsrc/c128/cpeekcol.s create mode 100644 libsrc/cbm/cpeekchar.s create mode 100644 libsrc/cbm/cpeekcol.s create mode 100644 libsrc/cbm510/cpeekchar.s create mode 100644 libsrc/cbm510/cpeekcol.s create mode 100644 libsrc/cbm610/cpeekchar.s create mode 100644 libsrc/nes/cpeekchar.s diff --git a/libsrc/atari/cpeekchar.s b/libsrc/atari/cpeekchar.s new file mode 100644 index 000000000..b551ed0df --- /dev/null +++ b/libsrc/atari/cpeekchar.s @@ -0,0 +1,41 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + .import mul40 + .importzp ptr4 + + .include "atari/atari.inc" + + .segment "CODE" + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + + lda ROWCRS + jsr mul40 ; destroys tmp4 + clc + adc SAVMSC ; add start of screen memory + sta ptr4 + txa + adc SAVMSC+1 + sta ptr4+1 + + ldy COLCRS + lda (ptr4),y ; get char + tax + + ;; convert to asc + + ;; ugly hack here to make tetris fx work :=P + lda #' ' + cpx #0 + beq @l + lda #0 +@l: + ldx #0 + rts diff --git a/libsrc/atmos/cpeekchar.s b/libsrc/atmos/cpeekchar.s new file mode 100644 index 000000000..a1d6d4474 --- /dev/null +++ b/libsrc/atmos/cpeekchar.s @@ -0,0 +1,36 @@ + + .include "atmos.inc" + +.import _gotoxy +.export _cpeekchar,_cpeekcharxy + +_cpeekcharxy: + + jsr _gotoxy ; Will pop x parameter + +_cpeekchar: + + ldy CURS_Y + ldx ScrTabLo,y + stx @l+1 + ldx ScrTabHi,y + stx @l+2 + ldx CURS_X +@l: + lda $bb80,x +;; inc COORDX_TEXT + ldx #0 + rts + + ; FIXME: is that table available elsewhere? +.rodata +ScrTabLo: + .repeat 28, Line + .byte <(SCREEN + Line * 40) + .endrep + +ScrTabHi: + .repeat 28, Line + .byte >(SCREEN + Line * 40) + .endrep + diff --git a/libsrc/c128/cpeekchar.s b/libsrc/c128/cpeekchar.s new file mode 100644 index 000000000..e6e7e4a12 --- /dev/null +++ b/libsrc/c128/cpeekchar.s @@ -0,0 +1,74 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + + .import plot,popa + + + .include "zeropage.inc" + .include "c128/c128.inc" + + .segment "CODE" + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + + lda MODE + bmi @c80 + + ldy CURS_X + lda (SCREEN_PTR),y ; get char + +@return: + ; convert to asc + and #$7f + + ; 0 - $1f +$40 + ; $20 - $3f + ; $40 - $7e +$80 + + cmp #$1f + bcs @sk1 +;; clc + adc #$40 + rts + +@sk1: + cmp #$40 + bcc @end + clc + adc #$80 +@end: + ldx #0 + rts + +@c80: + lda SCREEN_PTR + ldy SCREEN_PTR+1 + clc + adc CURS_X + bcc @s + iny +@s: + ; get byte from vdc mem + ldx #VDC_DATA_LO + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + sta VDC_DATA_REG + dex + tya + stx VDC_ADDR_REG + sta VDC_DATA_REG + + ldx #VDC_DATA_RW + stx VDC_ADDR_REG +@L1: bit VDC_ADDR_REG + bpl @L1 + lda VDC_DATA_REG + jmp @return diff --git a/libsrc/c128/cpeekcol.s b/libsrc/c128/cpeekcol.s new file mode 100644 index 000000000..95f31c7cb --- /dev/null +++ b/libsrc/c128/cpeekcol.s @@ -0,0 +1,67 @@ + + .export _cpeekcol + .export _cpeekcolxy + + .import _gotoxy + + .include "c128/c128.inc" + + .segment "CODE" + +_cpeekcolxy: + + jsr _gotoxy ; Set cursor + +_cpeekcol: + + bit MODE + bmi @c80 + + ldy CURS_X + lda (CRAM_PTR),y ; get col + and #$0f + ldx #0 + rts + +@c80: + lda CRAM_PTR + ldy CRAM_PTR+1 + clc + adc CURS_X + bcc @s + iny +@s: + ; get byte from vdc mem + ldx #VDC_DATA_LO + stx VDC_ADDR_REG +@L0: bit VDC_ADDR_REG + bpl @L0 + sta VDC_DATA_REG + dex + ;;tya + stx VDC_ADDR_REG + sty VDC_DATA_REG + + ldx #VDC_DATA_RW + stx VDC_ADDR_REG +@L1: bit VDC_ADDR_REG + bpl @L1 + lda VDC_DATA_REG + + + and #$0f + +; translate vdc->vic colour + +vdctovic: + ldy #16 +@L2: cmp $CE5C-1,y + beq @L3 + dey + bne @L2 +@L3: + dey + tya + + ldx #0 + rts diff --git a/libsrc/cbm/cpeekchar.s b/libsrc/cbm/cpeekchar.s new file mode 100644 index 000000000..e8ebcdbc3 --- /dev/null +++ b/libsrc/cbm/cpeekchar.s @@ -0,0 +1,39 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + + .include "cbm/cbm.inc" + + .segment "CODE" + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + + ldy CURS_X + lda (SCREEN_PTR),y ; get char + ldx #0 + + and #$7f + + ; 0 - $1f +$40 + ; $20 - $3f + ; $40 - $7e +$80 + + cmp #$1f + bcs @sk1 +;; clc + adc #$40 + rts + +@sk1: + cmp #$40 + bcc @end + clc + adc #$80 +@end: + rts diff --git a/libsrc/cbm/cpeekcol.s b/libsrc/cbm/cpeekcol.s new file mode 100644 index 000000000..0e88daf04 --- /dev/null +++ b/libsrc/cbm/cpeekcol.s @@ -0,0 +1,21 @@ + + .export _cpeekcol + .export _cpeekcolxy + + .import _gotoxy + + .include "cc65/conio.inc" + + .segment "CODE" + +_cpeekcolxy: + + jsr _gotoxy ; Set cursor + +_cpeekcol: + + ldy CURS_X + lda (CRAM_PTR),y ; get color + and #$0f + ldx #0 + rts diff --git a/libsrc/cbm510/cpeekchar.s b/libsrc/cbm510/cpeekchar.s new file mode 100644 index 000000000..dc5963d2b --- /dev/null +++ b/libsrc/cbm510/cpeekchar.s @@ -0,0 +1,32 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + + .include "cbm510/cbm510.inc" + + .segment "CODE" + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + lda #0 + ldx #0 + rts + + ;; ?!?! + + ldx IndReg + ldy #$0F + sty IndReg + + ldy CURS_X + lda (SCREEN_PTR),y ; get char + + stx IndReg + + ldx #0 + rts diff --git a/libsrc/cbm510/cpeekcol.s b/libsrc/cbm510/cpeekcol.s new file mode 100644 index 000000000..332d0aaf8 --- /dev/null +++ b/libsrc/cbm510/cpeekcol.s @@ -0,0 +1,31 @@ + + .export _cpeekcol + .export _cpeekcolxy + + .import _gotoxy + + .include "cbm510/cbm510.inc" + + .segment "CODE" + +_cpeekcolxy: + + jsr _gotoxy ; Set cursor + +_cpeekcol: + + lda #0 + ldx #0 + rts + + ;; why the HELL doesnt this work ?!? + lda #$0F + ldy CURS_X + sei + ldx IndReg + sta IndReg + lda (CRAM_PTR),y ; get color + stx IndReg + cli + ldx #0 + rts diff --git a/libsrc/cbm610/cpeekchar.s b/libsrc/cbm610/cpeekchar.s new file mode 100644 index 000000000..8cf4bd57d --- /dev/null +++ b/libsrc/cbm610/cpeekchar.s @@ -0,0 +1,45 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + + .include "cbm610/cbm610.inc" + + .segment "CODE" + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + + ldx IndReg + ldy #$0F + sty IndReg + + ldy CURS_X + lda (CharPtr),y ; get char + ; convert to asc + and #$7f + + ; 0 - $1f +$40 + ; $20 - $3f + ; $40 - $7e +$80 + + cmp #$1f + bcs @sk1 +;; clc + adc #$40 + jmp @end + +@sk1: + cmp #$40 + bcc @end + clc + adc #$80 + +@end: + stx IndReg + ldx #0 + rts diff --git a/libsrc/nes/cpeekchar.s b/libsrc/nes/cpeekchar.s new file mode 100644 index 000000000..292a4591f --- /dev/null +++ b/libsrc/nes/cpeekchar.s @@ -0,0 +1,40 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + .import ppubuf_waitempty + + .include "nes.inc" + + .segment "CODE" + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + + ; wait until all console data has been written + jsr ppubuf_waitempty + + ldy SCREEN_PTR+1 + ldx SCREEN_PTR + +; waiting for vblank is incredibly slow :// +vwait: +; lda $2002 ;wait +; bpl vwait + + lda #0 + sty $2006 + stx $2006 + ldy $2007 ; first read is invalid + ldy $2007 ; get data + sta $2006 + sta $2006 + + tya + and #$7f ; ?!?! + rts + From b523f070f3933e060f927d7d76026159b7355377 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sat, 17 Jun 2017 03:01:31 +0200 Subject: [PATCH 002/707] fixed a few things, compiles again :) --- asminc/c128.inc | 9 +++++++-- libsrc/atari/cpeekchar.s | 2 +- libsrc/c128/cpeekchar.s | 18 +++++++++--------- libsrc/c128/cpeekcol.s | 18 +++++++++--------- libsrc/cbm/cpeekchar.s | 39 --------------------------------------- libsrc/cbm/cpeekcol.s | 21 --------------------- libsrc/cbm510/cpeekchar.s | 5 +++-- libsrc/cbm510/cpeekcol.s | 3 ++- libsrc/cbm610/cpeekchar.s | 3 ++- 9 files changed, 33 insertions(+), 85 deletions(-) delete mode 100644 libsrc/cbm/cpeekchar.s delete mode 100644 libsrc/cbm/cpeekcol.s diff --git a/asminc/c128.inc b/asminc/c128.inc index e6c89b07b..e17bae4ce 100644 --- a/asminc/c128.inc +++ b/asminc/c128.inc @@ -163,8 +163,13 @@ SID_Read3 := $D41C ; --------------------------------------------------------------------------- ; I/O: VDC (128 only) -VDC_INDEX := $D600 -VDC_DATA := $D601 +VDC_INDEX := $D600 ; VDC address +VDC_DATA := $D601 ; VDC data + +VDC_DATA_HI := 18 +VDC_DATA_LO := 19 +VDC_CSET := 28 +VDC_DATA_RW := 31 ; --------------------------------------------------------------------------- ; I/O: CIAs diff --git a/libsrc/atari/cpeekchar.s b/libsrc/atari/cpeekchar.s index b551ed0df..6697ce230 100644 --- a/libsrc/atari/cpeekchar.s +++ b/libsrc/atari/cpeekchar.s @@ -6,7 +6,7 @@ .import mul40 .importzp ptr4 - .include "atari/atari.inc" + .include "atari.inc" .segment "CODE" diff --git a/libsrc/c128/cpeekchar.s b/libsrc/c128/cpeekchar.s index e6e7e4a12..cf82dd529 100644 --- a/libsrc/c128/cpeekchar.s +++ b/libsrc/c128/cpeekchar.s @@ -8,7 +8,7 @@ .include "zeropage.inc" - .include "c128/c128.inc" + .include "c128.inc" .segment "CODE" @@ -57,18 +57,18 @@ _cpeekchar: @s: ; get byte from vdc mem ldx #VDC_DATA_LO - stx VDC_ADDR_REG -@L0: bit VDC_ADDR_REG + stx VDC_INDEX +@L0: bit VDC_INDEX bpl @L0 - sta VDC_DATA_REG + sta VDC_DATA dex tya - stx VDC_ADDR_REG - sta VDC_DATA_REG + stx VDC_INDEX + sta VDC_DATA ldx #VDC_DATA_RW - stx VDC_ADDR_REG -@L1: bit VDC_ADDR_REG + stx VDC_INDEX +@L1: bit VDC_INDEX bpl @L1 - lda VDC_DATA_REG + lda VDC_DATA jmp @return diff --git a/libsrc/c128/cpeekcol.s b/libsrc/c128/cpeekcol.s index 95f31c7cb..d96563574 100644 --- a/libsrc/c128/cpeekcol.s +++ b/libsrc/c128/cpeekcol.s @@ -4,7 +4,7 @@ .import _gotoxy - .include "c128/c128.inc" + .include "c128.inc" .segment "CODE" @@ -33,20 +33,20 @@ _cpeekcol: @s: ; get byte from vdc mem ldx #VDC_DATA_LO - stx VDC_ADDR_REG -@L0: bit VDC_ADDR_REG + stx VDC_INDEX +@L0: bit VDC_INDEX bpl @L0 - sta VDC_DATA_REG + sta VDC_DATA dex ;;tya - stx VDC_ADDR_REG - sty VDC_DATA_REG + stx VDC_INDEX + sty VDC_DATA ldx #VDC_DATA_RW - stx VDC_ADDR_REG -@L1: bit VDC_ADDR_REG + stx VDC_INDEX +@L1: bit VDC_INDEX bpl @L1 - lda VDC_DATA_REG + lda VDC_DATA and #$0f diff --git a/libsrc/cbm/cpeekchar.s b/libsrc/cbm/cpeekchar.s deleted file mode 100644 index e8ebcdbc3..000000000 --- a/libsrc/cbm/cpeekchar.s +++ /dev/null @@ -1,39 +0,0 @@ - - .export _cpeekchar - .export _cpeekcharxy - - .import _gotoxy - - .include "cbm/cbm.inc" - - .segment "CODE" - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor - -_cpeekchar: - - ldy CURS_X - lda (SCREEN_PTR),y ; get char - ldx #0 - - and #$7f - - ; 0 - $1f +$40 - ; $20 - $3f - ; $40 - $7e +$80 - - cmp #$1f - bcs @sk1 -;; clc - adc #$40 - rts - -@sk1: - cmp #$40 - bcc @end - clc - adc #$80 -@end: - rts diff --git a/libsrc/cbm/cpeekcol.s b/libsrc/cbm/cpeekcol.s deleted file mode 100644 index 0e88daf04..000000000 --- a/libsrc/cbm/cpeekcol.s +++ /dev/null @@ -1,21 +0,0 @@ - - .export _cpeekcol - .export _cpeekcolxy - - .import _gotoxy - - .include "cc65/conio.inc" - - .segment "CODE" - -_cpeekcolxy: - - jsr _gotoxy ; Set cursor - -_cpeekcol: - - ldy CURS_X - lda (CRAM_PTR),y ; get color - and #$0f - ldx #0 - rts diff --git a/libsrc/cbm510/cpeekchar.s b/libsrc/cbm510/cpeekchar.s index dc5963d2b..11787fe1e 100644 --- a/libsrc/cbm510/cpeekchar.s +++ b/libsrc/cbm510/cpeekchar.s @@ -3,8 +3,9 @@ .export _cpeekcharxy .import _gotoxy - - .include "cbm510/cbm510.inc" + + .include "cbm510.inc" + .include "extzp.inc" .segment "CODE" diff --git a/libsrc/cbm510/cpeekcol.s b/libsrc/cbm510/cpeekcol.s index 332d0aaf8..bbe7c5632 100644 --- a/libsrc/cbm510/cpeekcol.s +++ b/libsrc/cbm510/cpeekcol.s @@ -4,7 +4,8 @@ .import _gotoxy - .include "cbm510/cbm510.inc" + .include "cbm510.inc" + .include "extzp.inc" .segment "CODE" diff --git a/libsrc/cbm610/cpeekchar.s b/libsrc/cbm610/cpeekchar.s index 8cf4bd57d..217532ab5 100644 --- a/libsrc/cbm610/cpeekchar.s +++ b/libsrc/cbm610/cpeekchar.s @@ -4,7 +4,8 @@ .import _gotoxy - .include "cbm610/cbm610.inc" + .include "cbm610.inc" + .include "extzp.inc" .segment "CODE" From dd14f15f948b9684afe4c352a0a10d5a6777eadf Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sat, 17 Jun 2017 03:46:53 +0200 Subject: [PATCH 003/707] added fixed files for c64/c16/plus4/vic20/pet --- libsrc/c16/cpeekchar.s | 39 ++++++++++++ libsrc/c16/cpeekcol.s | 21 +++++++ libsrc/c64/cpeekchar.s | 39 ++++++++++++ libsrc/c64/cpeekcol.s | 21 +++++++ libsrc/c64/soft80_cpeekchar.s | 113 ++++++++++++++++++++++++++++++++++ libsrc/c64/soft80_cpeekcol.s | 21 +++++++ libsrc/pet/cpeekchar.s | 39 ++++++++++++ libsrc/plus4/cpeekchar.s | 39 ++++++++++++ libsrc/plus4/cpeekcol.s | 21 +++++++ libsrc/vic20/cpeekchar.s | 39 ++++++++++++ libsrc/vic20/cpeekcol.s | 21 +++++++ 11 files changed, 413 insertions(+) create mode 100644 libsrc/c16/cpeekchar.s create mode 100644 libsrc/c16/cpeekcol.s create mode 100644 libsrc/c64/cpeekchar.s create mode 100644 libsrc/c64/cpeekcol.s create mode 100644 libsrc/c64/soft80_cpeekchar.s create mode 100644 libsrc/c64/soft80_cpeekcol.s create mode 100644 libsrc/pet/cpeekchar.s create mode 100644 libsrc/plus4/cpeekchar.s create mode 100644 libsrc/plus4/cpeekcol.s create mode 100644 libsrc/vic20/cpeekchar.s create mode 100644 libsrc/vic20/cpeekcol.s diff --git a/libsrc/c16/cpeekchar.s b/libsrc/c16/cpeekchar.s new file mode 100644 index 000000000..5d89570f1 --- /dev/null +++ b/libsrc/c16/cpeekchar.s @@ -0,0 +1,39 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + + .include "c16.inc" + + .segment "CODE" + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + + ldy CURS_X + lda (SCREEN_PTR),y ; get char + ldx #0 + + and #$7f + + ; 0 - $1f +$40 + ; $20 - $3f + ; $40 - $7e +$80 + + cmp #$1f + bcs @sk1 +;; clc + adc #$40 + rts + +@sk1: + cmp #$40 + bcc @end + clc + adc #$80 +@end: + rts diff --git a/libsrc/c16/cpeekcol.s b/libsrc/c16/cpeekcol.s new file mode 100644 index 000000000..41fed7b9f --- /dev/null +++ b/libsrc/c16/cpeekcol.s @@ -0,0 +1,21 @@ + + .export _cpeekcol + .export _cpeekcolxy + + .import _gotoxy + + .include "c16.inc" + + .segment "CODE" + +_cpeekcolxy: + + jsr _gotoxy ; Set cursor + +_cpeekcol: + + ldy CURS_X + lda (CRAM_PTR),y ; get color + ;and #$0f is this ok? + ldx #0 + rts diff --git a/libsrc/c64/cpeekchar.s b/libsrc/c64/cpeekchar.s new file mode 100644 index 000000000..33d0284e7 --- /dev/null +++ b/libsrc/c64/cpeekchar.s @@ -0,0 +1,39 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + + .include "c64.inc" + + .segment "CODE" + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + + ldy CURS_X + lda (SCREEN_PTR),y ; get char + ldx #0 + + and #$7f + + ; 0 - $1f +$40 + ; $20 - $3f + ; $40 - $7e +$80 + + cmp #$1f + bcs @sk1 +;; clc + adc #$40 + rts + +@sk1: + cmp #$40 + bcc @end + clc + adc #$80 +@end: + rts diff --git a/libsrc/c64/cpeekcol.s b/libsrc/c64/cpeekcol.s new file mode 100644 index 000000000..60fb45c7b --- /dev/null +++ b/libsrc/c64/cpeekcol.s @@ -0,0 +1,21 @@ + + .export _cpeekcol + .export _cpeekcolxy + + .import _gotoxy + + .include "c64.inc" + + .segment "CODE" + +_cpeekcolxy: + + jsr _gotoxy ; Set cursor + +_cpeekcol: + + ldy CURS_X + lda (CRAM_PTR),y ; get color + and #$0f + ldx #0 + rts diff --git a/libsrc/c64/soft80_cpeekchar.s b/libsrc/c64/soft80_cpeekchar.s new file mode 100644 index 000000000..21a9fc5e7 --- /dev/null +++ b/libsrc/c64/soft80_cpeekchar.s @@ -0,0 +1,113 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + .import soft80_hi_charset + .import soft80_lo_charset + + .include "c64.inc" + + .macpack longbranch + + .segment "CODE" + +readdirect: +; sei +; dec $01 ;; assumed = $36 +; dec $01 ;; assumed = $36 + lda (SCREEN_PTR),y +; inc $01 +; inc $01 +; cli + rts + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + +;;rts + sei + ;;dec $01 ;; assumed = $36 + ;;dec $01 ;; assumed = $36 + lda #$34 + sta $01 + + lda CURS_X + and #$01 + + jne @l1a + +;; inc $d020 + +;;jmp * + + ldx #0 +@l2aa: + ldy #0 + +;; stx $d020 + + .repeat 8,line +;; jsr readdirect + lda (SCREEN_PTR),y + and #$f0 + sta $e100,y + cmp soft80_hi_charset+(line*$80),x +; cmp #0 + bne @l2b + .if (line < 7) + iny + .endif + .endrepeat + + +@backok: +;inc $d020 +; inc $01 +; inc $01 + lda #$36 + sta $01 + cli + txa + ; sec +; sbc #$20 + ldx #$00 + rts +@l2b: +;jmp * + inx + cpx #$80 + jne @l2aa +@backerr: + ;; inc $01 +;; inc $01 + lda #$36 + sta $01 + cli + ldx #0 + txa + rts + +@l1a: + ldx #0 +@l1aa: + ldy #0 + .repeat 8,line +;; jsr readdirect + lda (SCREEN_PTR),y + and #$0f + eor soft80_lo_charset+(line*$80),x + bne @l2bb + .if line < 7 + iny + .endif + .endrepeat + jmp @backok +@l2bb: + inx + cpx #$80 + bne @l1aa + jmp @backerr diff --git a/libsrc/c64/soft80_cpeekcol.s b/libsrc/c64/soft80_cpeekcol.s new file mode 100644 index 000000000..9891ab28a --- /dev/null +++ b/libsrc/c64/soft80_cpeekcol.s @@ -0,0 +1,21 @@ + + .export _cpeekcol + .export _cpeekcolxy + + .import _gotoxy + + .include "c64.inc" + + .segment "CODE" + +_cpeekcolxy: + + jsr _gotoxy ; Set cursor + +_cpeekcol: + + ldy #0 + lda (CRAM_PTR),y ; get char + and #$0f + ldx #0 + rts diff --git a/libsrc/pet/cpeekchar.s b/libsrc/pet/cpeekchar.s new file mode 100644 index 000000000..c846beb56 --- /dev/null +++ b/libsrc/pet/cpeekchar.s @@ -0,0 +1,39 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + + .include "pet.inc" + + .segment "CODE" + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + + ldy CURS_X + lda (SCREEN_PTR),y ; get char + ldx #0 + + and #$7f + + ; 0 - $1f +$40 + ; $20 - $3f + ; $40 - $7e +$80 + + cmp #$1f + bcs @sk1 +;; clc + adc #$40 + rts + +@sk1: + cmp #$40 + bcc @end + clc + adc #$80 +@end: + rts diff --git a/libsrc/plus4/cpeekchar.s b/libsrc/plus4/cpeekchar.s new file mode 100644 index 000000000..1d47c6d64 --- /dev/null +++ b/libsrc/plus4/cpeekchar.s @@ -0,0 +1,39 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + + .include "plus4.inc" + + .segment "CODE" + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + + ldy CURS_X + lda (SCREEN_PTR),y ; get char + ldx #0 + + and #$7f + + ; 0 - $1f +$40 + ; $20 - $3f + ; $40 - $7e +$80 + + cmp #$1f + bcs @sk1 +;; clc + adc #$40 + rts + +@sk1: + cmp #$40 + bcc @end + clc + adc #$80 +@end: + rts diff --git a/libsrc/plus4/cpeekcol.s b/libsrc/plus4/cpeekcol.s new file mode 100644 index 000000000..0f3258eb3 --- /dev/null +++ b/libsrc/plus4/cpeekcol.s @@ -0,0 +1,21 @@ + + .export _cpeekcol + .export _cpeekcolxy + + .import _gotoxy + + .include "plus4.inc" + + .segment "CODE" + +_cpeekcolxy: + + jsr _gotoxy ; Set cursor + +_cpeekcol: + + ldy CURS_X + lda (CRAM_PTR),y ; get color + ;and #$0f is this ok? + ldx #0 + rts diff --git a/libsrc/vic20/cpeekchar.s b/libsrc/vic20/cpeekchar.s new file mode 100644 index 000000000..fae7ec1b4 --- /dev/null +++ b/libsrc/vic20/cpeekchar.s @@ -0,0 +1,39 @@ + + .export _cpeekchar + .export _cpeekcharxy + + .import _gotoxy + + .include "vic20.inc" + + .segment "CODE" + +_cpeekcharxy: + + jsr _gotoxy ; Set cursor + +_cpeekchar: + + ldy CURS_X + lda (SCREEN_PTR),y ; get char + ldx #0 + + and #$7f + + ; 0 - $1f +$40 + ; $20 - $3f + ; $40 - $7e +$80 + + cmp #$1f + bcs @sk1 +;; clc + adc #$40 + rts + +@sk1: + cmp #$40 + bcc @end + clc + adc #$80 +@end: + rts diff --git a/libsrc/vic20/cpeekcol.s b/libsrc/vic20/cpeekcol.s new file mode 100644 index 000000000..59bf057ff --- /dev/null +++ b/libsrc/vic20/cpeekcol.s @@ -0,0 +1,21 @@ + + .export _cpeekcol + .export _cpeekcolxy + + .import _gotoxy + + .include "vic20.inc" + + .segment "CODE" + +_cpeekcolxy: + + jsr _gotoxy ; Set cursor + +_cpeekcol: + + ldy CURS_X + lda (CRAM_PTR),y ; get color + and #$0f + ldx #0 + rts From 3bd4d05598cab5855a287a0ec47932cae6c9755b Mon Sep 17 00:00:00 2001 From: Richard Halkyard Date: Sun, 27 Oct 2019 10:22:35 -0500 Subject: [PATCH 004/707] TGI driver and matching linker config for Plus/4 --- cfg/plus4-hires.cfg | 57 +++ doc/plus4.sgml | 20 +- include/cbm264.h | 19 +- include/plus4.h | 2 +- libsrc/plus4/cgetc.s | 5 + libsrc/plus4/crt0.s | 7 +- libsrc/plus4/libref.s | 3 +- libsrc/plus4/tgi/ted-hi.s | 883 +++++++++++++++++++++++++++++++++ libsrc/plus4/tgi_stat_stddrv.s | 14 + libsrc/plus4/tgi_stddrv.s | 13 + samples/Makefile | 24 +- samples/tgidemo.c | 4 +- 12 files changed, 1040 insertions(+), 11 deletions(-) create mode 100644 cfg/plus4-hires.cfg create mode 100644 libsrc/plus4/tgi/ted-hi.s create mode 100644 libsrc/plus4/tgi_stat_stddrv.s create mode 100644 libsrc/plus4/tgi_stddrv.s diff --git a/cfg/plus4-hires.cfg b/cfg/plus4-hires.cfg new file mode 100644 index 000000000..f3040a2db --- /dev/null +++ b/cfg/plus4-hires.cfg @@ -0,0 +1,57 @@ +# 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; + __RESERVED_C000__: type = weak, value = 8000; # Reserve 8000 bytes for hi-res bitmap +} +MEMORY { + # Memory reserved for bitmap + RESERVED: file = "", define = yes, start = $C000, size = __RESERVED_C000__; + + 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__; +} diff --git a/doc/plus4.sgml b/doc/plus4.sgml index 11468bb33..c74854ffb 100644 --- a/doc/plus4.sgml +++ b/doc/plus4.sgml @@ -164,8 +164,26 @@ The names in the parentheses denote the symbols to be used for static linking of Graphics drivers

-No graphics drivers are currently available for the Plus/4. + + + 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

Extended memory drivers

diff --git a/include/cbm264.h b/include/cbm264.h index 5e8a242a7..5b8b3d6ff 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -112,7 +112,24 @@ #define COLOR_LIGHTBLUE (BCOLOR_LIGHTBLUE | CATTR_LUMA7) #define COLOR_GRAY3 (BCOLOR_WHITE | CATTR_LUMA5) - +/* TGI color defines */ +#define TGI_COLOR_BLACK COLOR_BLACK +#define TGI_COLOR_WHITE COLOR_WHITE +#define TGI_COLOR_RED COLOR_RED +#define TGI_COLOR_CYAN COLOR_CYAN +#define TGI_COLOR_VIOLET COLOR_VIOLET +#define TGI_COLOR_PURPLE COLOR_PURPLE +#define TGI_COLOR_GREEN COLOR_GREEN +#define TGI_COLOR_BLUE COLOR_BLUE +#define TGI_COLOR_YELLOW COLOR_YELLOW +#define TGI_COLOR_ORANGE COLOR_ORANGE +#define TGI_COLOR_BROWN COLOR_BROWN +#define TGI_COLOR_LIGHTRED COLOR_LIGHTRED +#define TGI_COLOR_GRAY1 COLOR_GRAY1 +#define TGI_COLOR_GRAY2 COLOR_GRAY2 +#define TGI_COLOR_LIGHTGREEN COLOR_LIGHTGREEN +#define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE +#define TGI_COLOR_GRAY3 COLOR_GRAY3 /* Masks for joy_read */ #define JOY_UP_MASK 0x01 diff --git a/include/plus4.h b/include/plus4.h index c8aaf2eaf..7ff73fc94 100644 --- a/include/plus4.h +++ b/include/plus4.h @@ -57,7 +57,7 @@ /* The addresses of the static drivers */ extern void plus4_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ extern void plus4_stdser_ser[]; - +extern void ted_hi_tgi[]; /* End of plus4.h */ diff --git a/libsrc/plus4/cgetc.s b/libsrc/plus4/cgetc.s index 62863c06e..8c8bb0082 100644 --- a/libsrc/plus4/cgetc.s +++ b/libsrc/plus4/cgetc.s @@ -18,11 +18,16 @@ _cgetc: lda KEY_COUNT ; Get number of characters ora FKEY_COUNT ; Or with number of function key chars bne L2 ; Jump if there are already chars waiting + lda #%00100000 + bit $FF06 + bne L2 ; always disable cursor if in bitmap mode + ; Switch on the cursor if needed ldy CURS_X lda (CRAM_PTR),y ; Get current char pha ; And save it + lda CHARCOLOR sta (CRAM_PTR),y diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index 2262b4c42..268914ef8 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -9,8 +9,7 @@ .import callirq_y, initlib, donelib .import callmain, zerobss .import __INTERRUPTOR_COUNT__ - .import __MAIN_START__, __MAIN_SIZE__ ; Linker generated - .import __STACKSIZE__ ; Linker generated + .import __HIMEM__ ; Linker generated .importzp ST .include "zeropage.inc" @@ -52,8 +51,8 @@ L1: lda sp,x tsx stx spsave ; Save system stk ptr - lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) + lda #<__HIMEM__ + ldx #>__HIMEM__ sta sp stx sp+1 diff --git a/libsrc/plus4/libref.s b/libsrc/plus4/libref.s index 0bda1e7e8..62c78b8c5 100644 --- a/libsrc/plus4/libref.s +++ b/libsrc/plus4/libref.s @@ -2,8 +2,9 @@ ; Oliver Schmidt, 2013-05-31 ; - .export joy_libref, ser_libref + .export joy_libref, ser_libref, tgi_libref .import _exit joy_libref := _exit ser_libref := _exit +tgi_libref := _exit diff --git a/libsrc/plus4/tgi/ted-hi.s b/libsrc/plus4/tgi/ted-hi.s new file mode 100644 index 000000000..e3207600a --- /dev/null +++ b/libsrc/plus4/tgi/ted-hi.s @@ -0,0 +1,883 @@ +; +; 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 + 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 + 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=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: + +; Calculate a pointer to the representation of the character in the +; character ROM + +; ldx #((>(CHARROM + $0800)) >> 3) +; ldy #0 +; lda (TEXT),y +; bmi @L1 +; ldx #((>(CHARROM + $0000)) >> 3) +; @L1: stx ptr4+1 +; asl a +; rol ptr4+1 +; asl a +; rol ptr4+1 +; asl a +; rol ptr4+1 +; sta ptr4 + + + + + + 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 diff --git a/libsrc/plus4/tgi_stat_stddrv.s b/libsrc/plus4/tgi_stat_stddrv.s new file mode 100644 index 000000000..dc918eb8b --- /dev/null +++ b/libsrc/plus4/tgi_stat_stddrv.s @@ -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 diff --git a/libsrc/plus4/tgi_stddrv.s b/libsrc/plus4/tgi_stddrv.s new file mode 100644 index 000000000..eac16905d --- /dev/null +++ b/libsrc/plus4/tgi_stddrv.s @@ -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" diff --git a/samples/Makefile b/samples/Makefile index 69efbe43b..fd75695cd 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -94,6 +94,7 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) DIR2ATR ?= dir2atr DISK_c64 = samples.d64 + DISK_plus4 = samples.d64 DISK_apple2 = samples.dsk DISK_apple2enh = samples.dsk DISK_atari = samples.atr @@ -111,6 +112,9 @@ LDFLAGS_mandelbrot_apple2enh = --start-addr 0x4000 LDFLAGS_tgidemo_apple2 = --start-addr 0x4000 LDFLAGS_tgidemo_apple2enh = --start-addr 0x4000 +LDFLAGS_mandelbrot_plus4 = -C plus4-hires.cfg +LDFLAGS_tgidemo_plus4 = -C plus4-hires.cfg + # The Apple ][ needs the start address adjusted for the mousedemo LDFLAGS_mousedemo_apple2 = --start-addr 0x4000 @@ -168,6 +172,16 @@ EXELIST_c64 = \ sieve \ tgidemo +EXELIST_plus4 = \ + ascii \ + enumdevdir \ + gunzip65 \ + hello \ + mandelbrot \ + plasma \ + sieve \ + tgidemo + EXELIST_apple2 = \ ascii \ diodemo \ @@ -228,7 +242,15 @@ multdemo: multidemo.o ovrldemo: overlaydemo.o $(LD) $(LDFLAGS) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(SYS).lib -OVERLAYLIST := $(foreach I,1 2 3,multdemo.$I ovrldemo.$I) +OVERLAYLIST := + +ifneq ($(filter ovrldemo,$(EXELIST_$(SYS))),) +OVERLAYLIST += $(foreach I,1 2 3,ovrldemo.$I) +endif + +ifneq ($(filter multdemo,$(EXELIST_$(SYS))),) +OVERLAYLIST += $(foreach I,1 2 3,multdemo.$I) +endif # -------------------------------------------------------------------------- # Rule to make a CBM disk with all samples. Needs the c1541 program that comes diff --git a/samples/tgidemo.c b/samples/tgidemo.c index de743314e..23b10a540 100644 --- a/samples/tgidemo.c +++ b/samples/tgidemo.c @@ -12,8 +12,8 @@ # define DYN_DRV 1 #endif -#define COLOR_BACK TGI_COLOR_BLACK -#define COLOR_FORE TGI_COLOR_WHITE +#define COLOR_BACK 0 +#define COLOR_FORE 1 /*****************************************************************************/ From 89c8a988bfb72023824cf8ef8b528d2ad22dcff4 Mon Sep 17 00:00:00 2001 From: Richard Halkyard Date: Tue, 29 Oct 2019 22:44:29 -0500 Subject: [PATCH 005/707] Use Kernal locations for serial buffer ptrs --- libsrc/plus4/ser/plus4-stdser.s | 39 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/libsrc/plus4/ser/plus4-stdser.s b/libsrc/plus4/ser/plus4-stdser.s index bb44a4cf9..9cdde2fc1 100644 --- a/libsrc/plus4/ser/plus4-stdser.s +++ b/libsrc/plus4/ser/plus4-stdser.s @@ -64,15 +64,15 @@ ACIA_STATUS := ACIA+1 ; Status register ACIA_CMD := ACIA+2 ; Command register ACIA_CTRL := ACIA+3 ; Control register +RecvHead := $07D1 ; Head of receive buffer +RecvTail := $07D2 ; Tail of receive buffer +RecvFreeCnt := $07D3 ; Number of bytes in receive buffer ;---------------------------------------------------------------------------- ; ; Global variables ; .bss -RecvHead: .res 1 ; Head of receive buffer -RecvTail: .res 1 ; Tail of receive buffer -RecvFreeCnt: .res 1 ; Number of bytes in receive buffer SendHead: .res 1 ; Head of send buffer SendTail: .res 1 ; Tail of send buffer SendFreeCnt: .res 1 ; Number of bytes in send buffer @@ -353,26 +353,27 @@ SER_IOCTL: ; SER_IRQ: - lda ACIA_STATUS ; Check ACIA status for receive interrupt - and #$08 - beq @L9 ; Jump if no ACIA interrupt (carry still clear) - lda ACIA_DATA ; Get byte from ACIA - ldx RecvFreeCnt ; Check if we have free space left - beq @L1 ; Jump if no space in receive buffer - ldy RecvTail ; Load buffer pointer - sta RecvBuf,y ; Store received byte in buffer - inc RecvTail ; Increment buffer pointer - dec RecvFreeCnt ; Decrement free space counter - cpx #33 ; Check for buffer space low - bcc @L1 ; Assert flow control if buffer space low + lda ACIA_STATUS ;(4) ;status ;check for byte received + and #$08 ;(2) + beq @L9 ;(2*) + +@L1: lda ACIA_DATA ;(4) data ;get byte and put into receive buffer + ldy RecvTail ;(4) + ldx RecvFreeCnt ;(4) + beq @L3 ;(2*) Jump if no space in receive buffer + sta RecvBuf,y ;(5) + inc RecvTail ;(6) + dec RecvFreeCnt ;(6) + cpx #33 ;(2) check for buffer space low + bcc @L2 ;(2*) rts ; Return with carry set (interrupt handled) ; Assert flow control if buffer space too low -@L1: lda RtsOff - sta ACIA_CMD - sta Stopped - sec ; Interrupt handled +@L2: lda RtsOff ;(3) assert flow control if buffer space too low + sta ACIA_CMD ;(4) command + sta Stopped ;(3) +@L3: sec ; Interrupt handled @L9: rts ;---------------------------------------------------------------------------- From bf4c9c3c8c9d94e1ad404b69cd60e37e2b421b4a Mon Sep 17 00:00:00 2001 From: Richard Halkyard Date: Tue, 29 Oct 2019 22:45:22 -0500 Subject: [PATCH 006/707] Fix handling of IRQs that occur when ROM is active --- libsrc/plus4/crt0.s | 51 +++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index 268914ef8..610bc3116 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -64,6 +64,15 @@ L1: lda sp,x sta ENABLE_RAM stx $FFFE ; Install interrupt handler sty $FFFF + ldx IRQVec + ldy IRQVec+1 + stx IRQInd+1 + sty IRQInd+2 + ldx #IRQStub + stx IRQVec + sty IRQVec+1 + cli ; Allow interrupts ; Clear the BSS data. @@ -94,6 +103,13 @@ _exit: pha ; Save the return code lda #0 sta irqcount ; Disable custom IRQ handlers + sei + ldx IRQInd+1 + ldy IRQInd+2 + stx IRQVec + sty IRQVec+1 + cli + ; Copy back the zero-page stuff. ldx #zpspace-1 @@ -121,9 +137,13 @@ L2: lda zpsave,x ; IRQ handler. The handler in the ROM enables the Kernal, and jumps to ; $CE00, where the ROM code checks for a BRK or IRQ, and branches via the ; indirect vectors at $314/$316. -; To make our stub as fast as possible, we skip the whole part of the ROM -; handler, and jump to the indirect vectors directly. We do also call our -; own interrupt handlers if we have any; so, they need not use $314. +; +; When RAM is banked in, we skip the whole part of the ROM handler, and jump to +; the indirect vectors directly, after calling our own interrupt handlers. +; +; When ROM is banked in, a stub installed in the $314 indirect vector ensures +; that our interrupt handlers are still called (otherwise, interrupts that are +; not serviced by the ROM handler may cause a deadlock). .segment "LOWCODE" @@ -138,15 +158,6 @@ IRQ: cld ; Just to be sure and #$10 ; Test for BRK bit bne dobreak -; It's an IRQ; and, RAM is enabled. If we have handlers, call them. We will use -; a flag here instead of loading __INTERRUPTOR_COUNT__ directly, since the -; condes function is not reentrant. The irqcount flag will be set/reset from -; the main code, to avoid races. - - ldy irqcount - beq @L1 - jsr callirq_y ; Call the IRQ functions - ; Since the ROM handler will end with an RTI, we have to fake an IRQ return ; on the stack, so that we get control of the CPU after the ROM handler, ; and can switch back to RAM. @@ -160,7 +171,7 @@ IRQ: cld ; Just to be sure pha ; Push faked X register pha ; Push faked Y register sta ENABLE_ROM ; Switch to ROM - jmp (IRQVec) ; Jump indirect to Kernal IRQ handler + jmp (IRQVec) ; Jump indirect to IRQ stub irq_ret: sta ENABLE_RAM ; Switch back to RAM @@ -182,6 +193,20 @@ nohandler: sta ENABLE_ROM jmp (BRKVec) ; Jump indirect to the break vector + +; IRQ stub called by the Kernal IRQ handler, via $314. +; 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 From 917e5d4f011ecea4111348f301d9ae53380099cd Mon Sep 17 00:00:00 2001 From: Richard Halkyard Date: Thu, 31 Oct 2019 11:01:00 -0500 Subject: [PATCH 007/707] Code-style fixes as per PR feedback --- cfg/plus4-hires.cfg | 2 +- libsrc/plus4/crt0.s | 34 +++++---- libsrc/plus4/ser/plus4-stdser.s | 34 ++++----- libsrc/plus4/tgi/ted-hi.s | 127 +++++++++++++------------------- 4 files changed, 88 insertions(+), 109 deletions(-) diff --git a/cfg/plus4-hires.cfg b/cfg/plus4-hires.cfg index f3040a2db..054e8c7f5 100644 --- a/cfg/plus4-hires.cfg +++ b/cfg/plus4-hires.cfg @@ -38,7 +38,7 @@ SEGMENTS { # 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; + HIBSS: load = HIRAM, type = bss, optional = yes, define = yes; } FEATURES { CONDES: type = constructor, diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index 610bc3116..539c12641 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -58,20 +58,20 @@ L1: lda sp,x ; Set up the IRQ vector in the banked RAM; and, switch off the ROM. - ldx #IRQ + lda #IRQ sei ; No ints, handler not yet in place sta ENABLE_RAM - stx $FFFE ; Install interrupt handler - sty $FFFF - ldx IRQVec - ldy IRQVec+1 - stx IRQInd+1 - sty IRQInd+2 - ldx #IRQStub - stx IRQVec - sty IRQVec+1 + sta $FFFE ; Install interrupt handler + stx $FFFF + lda IRQVec + ldx IRQVec+1 + sta IRQInd+1 + stx IRQInd+2 + lda #IRQStub + sta IRQVec + stx IRQVec+1 cli ; Allow interrupts @@ -194,18 +194,20 @@ nohandler: jmp (BRKVec) ; Jump indirect to the break vector -; IRQ stub called by the Kernal IRQ handler, via $314. +; 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 + cld ; Just to be sure sta ENABLE_RAM ldy irqcount beq @L1 - jsr callirq_y ; Call the IRQ functions + jsr callirq_y ; Call the IRQ functions @L1: sta ENABLE_ROM - jmp (IRQInd+1) ; Jump to the saved IRQ vector + jmp (IRQInd+1) ; Jump to the saved IRQ vector ; ------------------------------------------------------------------------ ; Data diff --git a/libsrc/plus4/ser/plus4-stdser.s b/libsrc/plus4/ser/plus4-stdser.s index 9cdde2fc1..ceb997214 100644 --- a/libsrc/plus4/ser/plus4-stdser.s +++ b/libsrc/plus4/ser/plus4-stdser.s @@ -88,7 +88,7 @@ SendBuf: .res 256 ; Tables used to translate RS232 params into register values -BaudTable: ; bit7 = 1 means setting is invalid +BaudTable: ; Bit7 = 1 means setting is invalid .byte $FF ; SER_BAUD_45_5 .byte $01 ; SER_BAUD_50 .byte $02 ; SER_BAUD_75 @@ -353,26 +353,26 @@ SER_IOCTL: ; SER_IRQ: - lda ACIA_STATUS ;(4) ;status ;check for byte received - and #$08 ;(2) - beq @L9 ;(2*) + lda ACIA_STATUS ; (4) Check for byte received + and #$08 ; (2) + beq @L9 ; (2*) -@L1: lda ACIA_DATA ;(4) data ;get byte and put into receive buffer - ldy RecvTail ;(4) - ldx RecvFreeCnt ;(4) - beq @L3 ;(2*) Jump if no space in receive buffer - sta RecvBuf,y ;(5) - inc RecvTail ;(6) - dec RecvFreeCnt ;(6) - cpx #33 ;(2) check for buffer space low - bcc @L2 ;(2*) + lda ACIA_DATA ; (4) Get byte and put into receive buffer + ldy RecvTail ; (4) + ldx RecvFreeCnt ; (4) + beq @L3 ; (2*) Jump if no space in receive buffer + sta RecvBuf,y ; (5) + inc RecvTail ; (6) + dec RecvFreeCnt ; (6) + cpx #33 ; (2) Check for buffer space low + bcc @L2 ; (2*) rts ; Return with carry set (interrupt handled) ; Assert flow control if buffer space too low -@L2: lda RtsOff ;(3) assert flow control if buffer space too low - sta ACIA_CMD ;(4) command - sta Stopped ;(3) +@L2: lda RtsOff ; (3) + sta ACIA_CMD ; (4) + sta Stopped ; (3) @L3: sec ; Interrupt handled @L9: rts @@ -396,7 +396,7 @@ SER_IRQ: @L2: lda ACIA_STATUS and #$10 bne @L4 - bit tmp1 ;keep trying if must try hard + bit tmp1 ; Keep trying if must try hard bmi @L0 @L3: rts diff --git a/libsrc/plus4/tgi/ted-hi.s b/libsrc/plus4/tgi/ted-hi.s index e3207600a..5a804c304 100644 --- a/libsrc/plus4/tgi/ted-hi.s +++ b/libsrc/plus4/tgi/ted-hi.s @@ -129,11 +129,11 @@ CHARROM := $D000 ; Character rom base address ; 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 +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 +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" @@ -151,7 +151,7 @@ CHRBASE := $0800 ; Base address of text mode data ; INSTALL: -; rts ; fall through +; rts ; Fall through ; ------------------------------------------------------------------------ @@ -216,7 +216,7 @@ INIT: ; DONE: lda $FF12 - ora #%00000100 ; fetch from ROM + ora #%00000100 ; Fetch from ROM sta $FF12 .if LBASE <> CHRBASE @@ -229,7 +229,7 @@ DONE: lda $FF12 .endif lda $FF06 - and #%11011111 ; exit bitmap mode + and #%11011111 ; Exit bitmap mode sta $FF06 rts @@ -306,7 +306,7 @@ CLEAR: ldy #$00 ; SETVIEWPAGE: -; rts ; fall through +; rts ; Fall through ; ------------------------------------------------------------------------ ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n). @@ -472,14 +472,14 @@ GETPIXEL: LINE: -@CHECK: lda X2 ;Make sure x1=y1? - lda Y1 ;Otherwise dy=y1-y2 + bpl @DYPOS ; Is y2>=y1? + lda Y1 ; Otherwise dy=y1-y2 sec sbc Y2 tay - ldx #$88 ;DEY + ldx #$88 ; DEY @DYPOS: sty DY ; 8-bit DY -- FIX ME? stx YINCDEC @@ -524,8 +524,8 @@ LINE: sta CHUNK ldx DY - cpx DX ;Who's bigger: dy or dx? - bcc STEPINX ;If dx, then... + cpx DX ; Who's bigger: dy or dx? + bcc STEPINX ; If dx, then... lda DX+1 bne STEPINX @@ -543,14 +543,14 @@ LINE: ; Y1 AND #$07 STEPINY: lda #00 - sta OLDCHUNK ;So plotting routine will work right + sta OLDCHUNK ; So plotting routine will work right lda CHUNK - lsr ;Strip the bit + 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 + beq YCONT2 ; If dy=0, it's just a point +@CONT: lsr ; Init counter to dy/2 ; ; Main loop ; @@ -562,30 +562,30 @@ YLOOP: sta TEMP eor (POINT),y sta (POINT),y YINCDEC: - iny ;Advance Y coordinate + iny ; Advance Y coordinate cpy #8 - bcc @CONT ;No prob if Y=0..7 + bcc @CONT ; No prob if Y=0..7 jsr FIXY -@CONT: lda TEMP ;Restore A +@CONT: lda TEMP ; Restore A sec sbc DX bcc YFIXX -YCONT: dex ;X is counter +YCONT: dex ; X is counter bne YLOOP -YCONT2: lda (POINT),y ;Plot endpoint +YCONT2: lda (POINT),y ; Plot endpoint eor BITMASK and CHUNK eor (POINT),y sta (POINT),y rts -YFIXX: ;x=x+1 +YFIXX: ; X=x+1 adc DY lsr CHUNK - bne YCONT ;If we pass a column boundary... - ror CHUNK ;then reset CHUNK to $80 + bne YCONT ; If we pass a column boundary... + ror CHUNK ; Then reset CHUNK to $80 sta TEMP2 - lda POINT ;And add 8 to POINT + lda POINT ; And add 8 to POINT adc #8 sta POINT bcc @CONT @@ -603,34 +603,33 @@ YFIXX: ;x=x+1 .bss COUNTHI: - .byte $00 ;Temporary counter - ;only used once + .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 + ror ; Need bit for initialization + sta Y1 ; High byte of counter txa - bne @CONT ;Could be $100 + bne @CONT ; Could be $100 dec COUNTHI @CONT: ror ; ; Main loop ; XLOOP: lsr CHUNK - beq XFIXC ;If we pass a column boundary... + beq XFIXC ; If we pass a column boundary... XCONT1: sbc DY - bcc XFIXY ;Time to step in Y? + bcc XFIXY ; Time to step in Y? XCONT2: dex bne XLOOP - dec COUNTHI ;High bits set? + dec COUNTHI ; High bits set? bpl XLOOP - lsr CHUNK ;Advance to last point - jmp LINEPLOT ;Plot the last chunk + 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. @@ -652,22 +651,22 @@ XFIXC: sta TEMP ; Check to make sure there isn't a high bit, plot chunk, ; and update Y-coordinate. ; -XFIXY: dec Y1 ;Maybe high bit set +XFIXY: dec Y1 ; Maybe high bit set bpl XCONT2 adc DX sta TEMP lda DX+1 - adc #$FF ;Hi byte + adc #$FF ; Hi byte sta Y1 - jsr LINEPLOT ;Plot chunk + jsr LINEPLOT ; Plot chunk lda CHUNK sta OLDCHUNK lda TEMP XINCDEC: - iny ;Y-coord - cpy #8 ;0..7 is ok + iny ; Y-coord + cpy #8 ; 0..7 is ok bcc XCONT2 sta TEMP jsr FIXY @@ -692,11 +691,11 @@ LINEPLOT: ; Plot the line chunk ; Subroutine to fix up pointer when Y decreases through ; zero or increases through 7. ; -FIXY: cpy #255 ;Y=255 or Y=8 +FIXY: cpy #255 ; Y=255 or Y=8 beq @DECPTR -@INCPTR: ;Add 320 to pointer - ldy #0 ;Y increased through 7 +@INCPTR: ; Add 320 to pointer + ldy #0 ; Y increased through 7 lda POINT adc #<320 sta POINT @@ -705,8 +704,8 @@ FIXY: cpy #255 ;Y=255 or Y=8 sta POINT+1 rts -@DECPTR: ;Okay, subtract 320 then - ldy #7 ;Y decreased through 0 +@DECPTR: ; Okay, subtract 320 then + ldy #7 ; Y decreased through 0 lda POINT sec sbc #<320 @@ -815,28 +814,6 @@ TEXTSTYLE: ; OUTTEXT: - -; Calculate a pointer to the representation of the character in the -; character ROM - -; ldx #((>(CHARROM + $0800)) >> 3) -; ldy #0 -; lda (TEXT),y -; bmi @L1 -; ldx #((>(CHARROM + $0000)) >> 3) -; @L1: stx ptr4+1 -; asl a -; rol ptr4+1 -; asl a -; rol ptr4+1 -; asl a -; rol ptr4+1 -; sta ptr4 - - - - - rts ; ------------------------------------------------------------------------ @@ -862,10 +839,10 @@ CALC: lda Y1 ror POINT cmp #$80 ror - ror POINT ; row*64 - adc TEMP2 ; +row*256 + ror POINT ; Row * 64 + adc TEMP2 ; + Row * 256 clc - adc #>VBASE ; +bitmap base + adc #>VBASE ; + Bitmap base sta POINT+1 lda X1 From 2c9c7045229fffc6415a18209da2adc08b390449 Mon Sep 17 00:00:00 2001 From: Richard Halkyard Date: Thu, 31 Oct 2019 11:03:21 -0500 Subject: [PATCH 008/707] Use cl65 for linking samples ld65 doesn't accept a config option (needed for plus4 TGI demos) combined with -t, but cl65 does. --- samples/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index fd75695cd..1577cf955 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -149,9 +149,9 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000 .o: ifeq ($(SYS),vic20) - $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib + $(CL) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib else - $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib + $(CL) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib endif # -------------------------------------------------------------------------- From 44065f5e12a8c45bac5423780c2a7ce41f0d307e Mon Sep 17 00:00:00 2001 From: Richard Halkyard Date: Thu, 31 Oct 2019 11:05:57 -0500 Subject: [PATCH 009/707] Remove unncessary symbol --- cfg/plus4-hires.cfg | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cfg/plus4-hires.cfg b/cfg/plus4-hires.cfg index 054e8c7f5..0426c8d8c 100644 --- a/cfg/plus4-hires.cfg +++ b/cfg/plus4-hires.cfg @@ -9,16 +9,15 @@ SYMBOLS { __EXEHDR__: type = import; __STACKSIZE__: type = weak, value = $0800; # 2k stack __HIMEM__: type = weak, value = $FD00; - __RESERVED_C000__: type = weak, value = 8000; # Reserve 8000 bytes for hi-res bitmap } MEMORY { - # Memory reserved for bitmap - RESERVED: file = "", define = yes, start = $C000, size = __RESERVED_C000__; + # 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__; + 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__; From 0402fbd4b86a086e9a037e1f5eb469de46dc5e94 Mon Sep 17 00:00:00 2001 From: Richard Halkyard Date: Thu, 31 Oct 2019 11:07:33 -0500 Subject: [PATCH 010/707] Fix comment alignment --- libsrc/plus4/ser/plus4-stdser.s | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsrc/plus4/ser/plus4-stdser.s b/libsrc/plus4/ser/plus4-stdser.s index ceb997214..5ce207634 100644 --- a/libsrc/plus4/ser/plus4-stdser.s +++ b/libsrc/plus4/ser/plus4-stdser.s @@ -64,9 +64,9 @@ ACIA_STATUS := ACIA+1 ; Status register ACIA_CMD := ACIA+2 ; Command register ACIA_CTRL := ACIA+3 ; Control register -RecvHead := $07D1 ; Head of receive buffer -RecvTail := $07D2 ; Tail of receive buffer -RecvFreeCnt := $07D3 ; Number of bytes in receive buffer +RecvHead := $07D1 ; Head of receive buffer +RecvTail := $07D2 ; Tail of receive buffer +RecvFreeCnt := $07D3 ; Number of bytes in receive buffer ;---------------------------------------------------------------------------- ; ; Global variables From 74098077d3bb93be8943b45a5c8cdf6810fbd74a Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 24 Jul 2022 03:36:19 +0200 Subject: [PATCH 011/707] bleh --- asminc/c128.inc | 224 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 asminc/c128.inc diff --git a/asminc/c128.inc b/asminc/c128.inc new file mode 100644 index 000000000..749b4168c --- /dev/null +++ b/asminc/c128.inc @@ -0,0 +1,224 @@ +; +; C128 generic definitions. Stolen from Elite128 +; + + +; --------------------------------------------------------------------------- +; Zero page, Commodore stuff + +TXTPTR := $3D ; Pointer into BASIC source code +STATUS := $90 ; Kernal I/O completion status +TIME := $A0 ; 60HZ clock +FNAM_LEN := $B7 ; Length of filename +SECADR := $B9 ; Secondary address +DEVNUM := $BA ; Device number +FNAM := $BB ; Address of filename +FNAM_BANK := $C7 ; Bank for filename +KEY_COUNT := $D0 ; Number of keys in input buffer +FKEY_COUNT := $D1 ; Characters for function key +MODE := $D7 ; 40-/80-column mode (bit 7: 80 columns) +GRAPHM := $D8 ; Graphics mode flags (bits 5-7) +CHARDIS := $D9 ; Bit 2 shadow for location $01 +CURS_X := $EC ; Cursor column +CURS_Y := $EB ; Cursor row +SCREEN_PTR := $E0 ; Pointer to current char in text screen +CRAM_PTR := $E2 ; Pointer to current char in color RAM + +CHARCOLOR := $F1 +RVS := $F3 ; Reverse output flag +SCROLL := $F8 ; Disable scrolling flag + +BASIC_BUF := $0200 ; Location of command-line +BASIC_BUF_LEN = 162 ; Maximum length of command-line + +FETCH := $02A2 ; Fetch subroutine in RAM +FETVEC := $02AA ; Vector patch location for FETCH +STASH := $02AF ; Stash routine in RAM +STAVEC := $02B9 ; Vector patch location for STASH +IRQInd := $02FD ; JMP $0000 -- used as indirect IRQ vector +PALFLAG := $0A03 ; $FF=PAL, $00=NTSC +INIT_STATUS := $0A04 ; Flags: Reset/Restore initiation status +VM2 := $0A2D ; VIC-IIe shadow for $D018 -- graphics mode +FKEY_LEN := $1000 ; Function key lengths +FKEY_TEXT := $100A ; Function key texts + +KBDREPEAT := $028a +KBDREPEATRATE := $028b +KBDREPEATDELAY := $028c + +; --------------------------------------------------------------------------- +; Vectors + +IRQVec := $0314 +BRKVec := $0316 +NMIVec := $0318 +KeyStoreVec := $033C + +; --------------------------------------------------------------------------- +; I/O: VIC + +VIC := $D000 +VIC_SPR0_X := $D000 +VIC_SPR0_Y := $D001 +VIC_SPR1_X := $D002 +VIC_SPR1_Y := $D003 +VIC_SPR2_X := $D004 +VIC_SPR2_Y := $D005 +VIC_SPR3_X := $D006 +VIC_SPR3_Y := $D007 +VIC_SPR4_X := $D008 +VIC_SPR4_Y := $D009 +VIC_SPR5_X := $D00A +VIC_SPR5_Y := $D00B +VIC_SPR6_X := $D00C +VIC_SPR6_Y := $D00D +VIC_SPR7_X := $D00E +VIC_SPR7_Y := $D00F +VIC_SPR_HI_X := $D010 +VIC_SPR_ENA := $D015 +VIC_SPR_EXP_Y := $D017 +VIC_SPR_EXP_X := $D01D +VIC_SPR_MCOLOR := $D01C +VIC_SPR_BG_PRIO := $D01B + +VIC_SPR_MCOLOR0 := $D025 +VIC_SPR_MCOLOR1 := $D026 + +VIC_SPR0_COLOR := $D027 +VIC_SPR1_COLOR := $D028 +VIC_SPR2_COLOR := $D029 +VIC_SPR3_COLOR := $D02A +VIC_SPR4_COLOR := $D02B +VIC_SPR5_COLOR := $D02C +VIC_SPR6_COLOR := $D02D +VIC_SPR7_COLOR := $D02E + +VIC_CTRL1 := $D011 +VIC_CTRL2 := $D016 + +VIC_HLINE := $D012 + +VIC_LPEN_X := $D013 +VIC_LPEN_Y := $D014 + +VIC_VIDEO_ADR := $D018 + +VIC_IRR := $D019 ; Interrupt request register +VIC_IMR := $D01A ; Interrupt mask register + +VIC_BORDERCOLOR := $D020 +VIC_BG_COLOR0 := $D021 +VIC_BG_COLOR1 := $D022 +VIC_BG_COLOR2 := $D023 +VIC_BG_COLOR3 := $D024 + +; 128 stuff: +VIC_KBD_128 := $D02F ; Extended kbd bits (visible in 64 mode) +VIC_CLK_128 := $D030 ; Clock rate register (visible in 64 mode) + + +; --------------------------------------------------------------------------- +; I/O: SID + +SID := $D400 +SID_S1Lo := $D400 +SID_S1Hi := $D401 +SID_PB1Lo := $D402 +SID_PB1Hi := $D403 +SID_Ctl1 := $D404 +SID_AD1 := $D405 +SID_SUR1 := $D406 + +SID_S2Lo := $D407 +SID_S2Hi := $D408 +SID_PB2Lo := $D409 +SID_PB2Hi := $D40A +SID_Ctl2 := $D40B +SID_AD2 := $D40C +SID_SUR2 := $D40D + +SID_S3Lo := $D40E +SID_S3Hi := $D40F +SID_PB3Lo := $D410 +SID_PB3Hi := $D411 +SID_Ctl3 := $D412 +SID_AD3 := $D413 +SID_SUR3 := $D414 + +SID_FltLo := $D415 +SID_FltHi := $D416 +SID_FltCtl := $D417 +SID_Amp := $D418 +SID_ADConv1 := $D419 +SID_ADConv2 := $D41A +SID_Noise := $D41B +SID_Read3 := $D41C + +; --------------------------------------------------------------------------- +; I/O: VDC (128 only) + +VDC_INDEX := $D600 ; register address port +VDC_DATA := $D601 ; data port + +; Registers +VDC_DATA_HI = 18 ; video RAM address (big endian) +VDC_DATA_LO = 19 +VDC_CSET = 28 +VDC_RAM_RW = 31 ; RAM port + +; --------------------------------------------------------------------------- +; I/O: Complex Interface Adapters + +CIA1 := $DC00 +CIA1_PRA := $DC00 ; Port A +CIA1_PRB := $DC01 ; Port B +CIA1_DDRA := $DC02 ; Data direction register for port A +CIA1_DDRB := $DC03 ; Data direction register for port B +CIA1_TA := $DC04 ; 16-bit timer A +CIA1_TB := $DC06 ; 16-bit timer B +CIA1_TOD10 := $DC08 ; Time-of-day tenths of a second +CIA1_TODSEC := $DC09 ; Time-of-day seconds +CIA1_TODMIN := $DC0A ; Time-of-day minutes +CIA1_TODHR := $DC0B ; Time-of-day hours +CIA1_SDR := $DC0C ; Serial data register +CIA1_ICR := $DC0D ; Interrupt control register +CIA1_CRA := $DC0E ; Control register for timer A +CIA1_CRB := $DC0F ; Control register for timer B + +CIA2 := $DD00 +CIA2_PRA := $DD00 +CIA2_PRB := $DD01 +CIA2_DDRA := $DD02 +CIA2_DDRB := $DD03 +CIA2_TA := $DD04 +CIA2_TB := $DD06 +CIA2_TOD10 := $DD08 +CIA2_TODSEC := $DD09 +CIA2_TODMIN := $DD0A +CIA2_TODHR := $DD0B +CIA2_SDR := $DD0C +CIA2_ICR := $DD0D +CIA2_CRA := $DD0E +CIA2_CRB := $DD0F + +; --------------------------------------------------------------------------- +; I/O: MMU + +MMU_CR := $FF00 +MMU_CFG_CC65 := %00001110 ; Bank 0 with kernal ROM +MMU_CFG_RAM0 := %00111111 ; Bank 0 full RAM +MMU_CFG_RAM1 := %01111111 ; Bank 1 full RAM +MMU_CFG_RAM2 := %10111111 ; Bank 2 full RAM +MMU_CFG_RAM3 := %11111111 ; Bank 3 full RAM +MMU_CFG_IFROM := %01010111 ; Bank 1 with Internal Function RAM/ROM +MMU_CFG_EFROM := %01101011 ; Bank 1 with External Function RAM/ROM + +; --------------------------------------------------------------------------- +; Super CPU + +SCPU_VIC_Bank1 := $D075 +SCPU_Slow := $D07A +SCPU_Fast := $D07B +SCPU_EnableRegs := $D07E +SCPU_DisableRegs:= $D07F +SCPU_Detect := $D0BC From 6dae5324ddbea4dcbb19c913109f4bc4d5fbfde5 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 24 Jul 2022 03:59:19 +0200 Subject: [PATCH 012/707] cleanup --- libsrc/c128/cpeekcol.s | 67 ------------------------------------ libsrc/c16/cpeekcol.s | 11 ++---- libsrc/c64/cpeekcol.s | 23 +++++-------- libsrc/c64/soft80_cpeekcol.s | 21 ----------- libsrc/cbm510/cpeekcol.s | 32 ----------------- libsrc/plus4/cpeekcol.s | 23 +++++-------- libsrc/vic20/cpeekcol.s | 23 +++++-------- 7 files changed, 26 insertions(+), 174 deletions(-) delete mode 100644 libsrc/c128/cpeekcol.s delete mode 100644 libsrc/c64/soft80_cpeekcol.s delete mode 100644 libsrc/cbm510/cpeekcol.s diff --git a/libsrc/c128/cpeekcol.s b/libsrc/c128/cpeekcol.s deleted file mode 100644 index d96563574..000000000 --- a/libsrc/c128/cpeekcol.s +++ /dev/null @@ -1,67 +0,0 @@ - - .export _cpeekcol - .export _cpeekcolxy - - .import _gotoxy - - .include "c128.inc" - - .segment "CODE" - -_cpeekcolxy: - - jsr _gotoxy ; Set cursor - -_cpeekcol: - - bit MODE - bmi @c80 - - ldy CURS_X - lda (CRAM_PTR),y ; get col - and #$0f - ldx #0 - rts - -@c80: - lda CRAM_PTR - ldy CRAM_PTR+1 - clc - adc CURS_X - bcc @s - iny -@s: - ; get byte from vdc mem - ldx #VDC_DATA_LO - stx VDC_INDEX -@L0: bit VDC_INDEX - bpl @L0 - sta VDC_DATA - dex - ;;tya - stx VDC_INDEX - sty VDC_DATA - - ldx #VDC_DATA_RW - stx VDC_INDEX -@L1: bit VDC_INDEX - bpl @L1 - lda VDC_DATA - - - and #$0f - -; translate vdc->vic colour - -vdctovic: - ldy #16 -@L2: cmp $CE5C-1,y - beq @L3 - dey - bne @L2 -@L3: - dey - tya - - ldx #0 - rts diff --git a/libsrc/c16/cpeekcol.s b/libsrc/c16/cpeekcol.s index 41fed7b9f..446079ddd 100644 --- a/libsrc/c16/cpeekcol.s +++ b/libsrc/c16/cpeekcol.s @@ -1,18 +1,11 @@ - .export _cpeekcol - .export _cpeekcolxy - - .import _gotoxy + .export _cpeekcolor .include "c16.inc" .segment "CODE" -_cpeekcolxy: - - jsr _gotoxy ; Set cursor - -_cpeekcol: +_cpeekcolor: ldy CURS_X lda (CRAM_PTR),y ; get color diff --git a/libsrc/c64/cpeekcol.s b/libsrc/c64/cpeekcol.s index 60fb45c7b..8e87cff23 100644 --- a/libsrc/c64/cpeekcol.s +++ b/libsrc/c64/cpeekcol.s @@ -1,21 +1,14 @@ - .export _cpeekcol - .export _cpeekcolxy + .export _cpeekcolor - .import _gotoxy + .include "c64.inc" - .include "c64.inc" + .segment "CODE" - .segment "CODE" +_cpeekcolor: -_cpeekcolxy: - - jsr _gotoxy ; Set cursor - -_cpeekcol: - - ldy CURS_X - lda (CRAM_PTR),y ; get color - and #$0f + ldy CURS_X + lda (CRAM_PTR),y ; get color + and #$0f ldx #0 - rts + rts diff --git a/libsrc/c64/soft80_cpeekcol.s b/libsrc/c64/soft80_cpeekcol.s deleted file mode 100644 index 9891ab28a..000000000 --- a/libsrc/c64/soft80_cpeekcol.s +++ /dev/null @@ -1,21 +0,0 @@ - - .export _cpeekcol - .export _cpeekcolxy - - .import _gotoxy - - .include "c64.inc" - - .segment "CODE" - -_cpeekcolxy: - - jsr _gotoxy ; Set cursor - -_cpeekcol: - - ldy #0 - lda (CRAM_PTR),y ; get char - and #$0f - ldx #0 - rts diff --git a/libsrc/cbm510/cpeekcol.s b/libsrc/cbm510/cpeekcol.s deleted file mode 100644 index bbe7c5632..000000000 --- a/libsrc/cbm510/cpeekcol.s +++ /dev/null @@ -1,32 +0,0 @@ - - .export _cpeekcol - .export _cpeekcolxy - - .import _gotoxy - - .include "cbm510.inc" - .include "extzp.inc" - - .segment "CODE" - -_cpeekcolxy: - - jsr _gotoxy ; Set cursor - -_cpeekcol: - - lda #0 - ldx #0 - rts - - ;; why the HELL doesnt this work ?!? - lda #$0F - ldy CURS_X - sei - ldx IndReg - sta IndReg - lda (CRAM_PTR),y ; get color - stx IndReg - cli - ldx #0 - rts diff --git a/libsrc/plus4/cpeekcol.s b/libsrc/plus4/cpeekcol.s index 0f3258eb3..b98b0124e 100644 --- a/libsrc/plus4/cpeekcol.s +++ b/libsrc/plus4/cpeekcol.s @@ -1,21 +1,14 @@ - .export _cpeekcol - .export _cpeekcolxy + .export _cpeekcolor - .import _gotoxy + .include "plus4.inc" - .include "plus4.inc" + .segment "CODE" - .segment "CODE" +_cpeekcolor: -_cpeekcolxy: - - jsr _gotoxy ; Set cursor - -_cpeekcol: - - ldy CURS_X - lda (CRAM_PTR),y ; get color - ;and #$0f is this ok? + ldy CURS_X + lda (CRAM_PTR),y ; get color + ;and #$0f is this ok? ldx #0 - rts + rts diff --git a/libsrc/vic20/cpeekcol.s b/libsrc/vic20/cpeekcol.s index 59bf057ff..31fa4612a 100644 --- a/libsrc/vic20/cpeekcol.s +++ b/libsrc/vic20/cpeekcol.s @@ -1,21 +1,14 @@ - .export _cpeekcol - .export _cpeekcolxy + .export _cpeekcolor - .import _gotoxy + .include "vic20.inc" - .include "vic20.inc" + .segment "CODE" - .segment "CODE" +_cpeekcolor: -_cpeekcolxy: - - jsr _gotoxy ; Set cursor - -_cpeekcol: - - ldy CURS_X - lda (CRAM_PTR),y ; get color - and #$0f + ldy CURS_X + lda (CRAM_PTR),y ; get color + and #$0f ldx #0 - rts + rts From 7890f4102e30bad2d76c8888b6dcd0487598bf95 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 24 Jul 2022 04:14:48 +0200 Subject: [PATCH 013/707] cleanup --- libsrc/c128/cpeekchar.s | 74 ---------------------- libsrc/c64/soft80_cpeekchar.s | 113 ---------------------------------- libsrc/cbm610/cpeekchar.s | 46 -------------- 3 files changed, 233 deletions(-) delete mode 100644 libsrc/c128/cpeekchar.s delete mode 100644 libsrc/c64/soft80_cpeekchar.s delete mode 100644 libsrc/cbm610/cpeekchar.s diff --git a/libsrc/c128/cpeekchar.s b/libsrc/c128/cpeekchar.s deleted file mode 100644 index cf82dd529..000000000 --- a/libsrc/c128/cpeekchar.s +++ /dev/null @@ -1,74 +0,0 @@ - - .export _cpeekchar - .export _cpeekcharxy - - .import _gotoxy - - .import plot,popa - - - .include "zeropage.inc" - .include "c128.inc" - - .segment "CODE" - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor - -_cpeekchar: - - lda MODE - bmi @c80 - - ldy CURS_X - lda (SCREEN_PTR),y ; get char - -@return: - ; convert to asc - and #$7f - - ; 0 - $1f +$40 - ; $20 - $3f - ; $40 - $7e +$80 - - cmp #$1f - bcs @sk1 -;; clc - adc #$40 - rts - -@sk1: - cmp #$40 - bcc @end - clc - adc #$80 -@end: - ldx #0 - rts - -@c80: - lda SCREEN_PTR - ldy SCREEN_PTR+1 - clc - adc CURS_X - bcc @s - iny -@s: - ; get byte from vdc mem - ldx #VDC_DATA_LO - stx VDC_INDEX -@L0: bit VDC_INDEX - bpl @L0 - sta VDC_DATA - dex - tya - stx VDC_INDEX - sta VDC_DATA - - ldx #VDC_DATA_RW - stx VDC_INDEX -@L1: bit VDC_INDEX - bpl @L1 - lda VDC_DATA - jmp @return diff --git a/libsrc/c64/soft80_cpeekchar.s b/libsrc/c64/soft80_cpeekchar.s deleted file mode 100644 index 21a9fc5e7..000000000 --- a/libsrc/c64/soft80_cpeekchar.s +++ /dev/null @@ -1,113 +0,0 @@ - - .export _cpeekchar - .export _cpeekcharxy - - .import _gotoxy - .import soft80_hi_charset - .import soft80_lo_charset - - .include "c64.inc" - - .macpack longbranch - - .segment "CODE" - -readdirect: -; sei -; dec $01 ;; assumed = $36 -; dec $01 ;; assumed = $36 - lda (SCREEN_PTR),y -; inc $01 -; inc $01 -; cli - rts - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor - -_cpeekchar: - -;;rts - sei - ;;dec $01 ;; assumed = $36 - ;;dec $01 ;; assumed = $36 - lda #$34 - sta $01 - - lda CURS_X - and #$01 - - jne @l1a - -;; inc $d020 - -;;jmp * - - ldx #0 -@l2aa: - ldy #0 - -;; stx $d020 - - .repeat 8,line -;; jsr readdirect - lda (SCREEN_PTR),y - and #$f0 - sta $e100,y - cmp soft80_hi_charset+(line*$80),x -; cmp #0 - bne @l2b - .if (line < 7) - iny - .endif - .endrepeat - - -@backok: -;inc $d020 -; inc $01 -; inc $01 - lda #$36 - sta $01 - cli - txa - ; sec -; sbc #$20 - ldx #$00 - rts -@l2b: -;jmp * - inx - cpx #$80 - jne @l2aa -@backerr: - ;; inc $01 -;; inc $01 - lda #$36 - sta $01 - cli - ldx #0 - txa - rts - -@l1a: - ldx #0 -@l1aa: - ldy #0 - .repeat 8,line -;; jsr readdirect - lda (SCREEN_PTR),y - and #$0f - eor soft80_lo_charset+(line*$80),x - bne @l2bb - .if line < 7 - iny - .endif - .endrepeat - jmp @backok -@l2bb: - inx - cpx #$80 - bne @l1aa - jmp @backerr diff --git a/libsrc/cbm610/cpeekchar.s b/libsrc/cbm610/cpeekchar.s deleted file mode 100644 index 217532ab5..000000000 --- a/libsrc/cbm610/cpeekchar.s +++ /dev/null @@ -1,46 +0,0 @@ - - .export _cpeekchar - .export _cpeekcharxy - - .import _gotoxy - - .include "cbm610.inc" - .include "extzp.inc" - - .segment "CODE" - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor - -_cpeekchar: - - ldx IndReg - ldy #$0F - sty IndReg - - ldy CURS_X - lda (CharPtr),y ; get char - ; convert to asc - and #$7f - - ; 0 - $1f +$40 - ; $20 - $3f - ; $40 - $7e +$80 - - cmp #$1f - bcs @sk1 -;; clc - adc #$40 - jmp @end - -@sk1: - cmp #$40 - bcc @end - clc - adc #$80 - -@end: - stx IndReg - ldx #0 - rts From d40def3d2d9b74eb5d326d35367f8f974a70b256 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 24 Jul 2022 04:42:44 +0200 Subject: [PATCH 014/707] cleanup --- libsrc/c16/cpeekcol.s | 14 -------------- libsrc/c64/cpeekcol.s | 14 -------------- libsrc/plus4/cpeekcol.s | 14 -------------- libsrc/vic20/cpeekcol.s | 14 -------------- 4 files changed, 56 deletions(-) delete mode 100644 libsrc/c16/cpeekcol.s delete mode 100644 libsrc/c64/cpeekcol.s delete mode 100644 libsrc/plus4/cpeekcol.s delete mode 100644 libsrc/vic20/cpeekcol.s diff --git a/libsrc/c16/cpeekcol.s b/libsrc/c16/cpeekcol.s deleted file mode 100644 index 446079ddd..000000000 --- a/libsrc/c16/cpeekcol.s +++ /dev/null @@ -1,14 +0,0 @@ - - .export _cpeekcolor - - .include "c16.inc" - - .segment "CODE" - -_cpeekcolor: - - ldy CURS_X - lda (CRAM_PTR),y ; get color - ;and #$0f is this ok? - ldx #0 - rts diff --git a/libsrc/c64/cpeekcol.s b/libsrc/c64/cpeekcol.s deleted file mode 100644 index 8e87cff23..000000000 --- a/libsrc/c64/cpeekcol.s +++ /dev/null @@ -1,14 +0,0 @@ - - .export _cpeekcolor - - .include "c64.inc" - - .segment "CODE" - -_cpeekcolor: - - ldy CURS_X - lda (CRAM_PTR),y ; get color - and #$0f - ldx #0 - rts diff --git a/libsrc/plus4/cpeekcol.s b/libsrc/plus4/cpeekcol.s deleted file mode 100644 index b98b0124e..000000000 --- a/libsrc/plus4/cpeekcol.s +++ /dev/null @@ -1,14 +0,0 @@ - - .export _cpeekcolor - - .include "plus4.inc" - - .segment "CODE" - -_cpeekcolor: - - ldy CURS_X - lda (CRAM_PTR),y ; get color - ;and #$0f is this ok? - ldx #0 - rts diff --git a/libsrc/vic20/cpeekcol.s b/libsrc/vic20/cpeekcol.s deleted file mode 100644 index 31fa4612a..000000000 --- a/libsrc/vic20/cpeekcol.s +++ /dev/null @@ -1,14 +0,0 @@ - - .export _cpeekcolor - - .include "vic20.inc" - - .segment "CODE" - -_cpeekcolor: - - ldy CURS_X - lda (CRAM_PTR),y ; get color - and #$0f - ldx #0 - rts From 193b7b9ee7f75c11c3ce2bbb73a2802146cf09de Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 24 Jul 2022 04:54:34 +0200 Subject: [PATCH 015/707] cleanup --- libsrc/c16/cpeekchar.s | 39 --------------------------------------- libsrc/c64/cpeekchar.s | 39 --------------------------------------- libsrc/cbm510/cpeekchar.s | 33 --------------------------------- libsrc/pet/cpeekchar.s | 39 --------------------------------------- libsrc/plus4/cpeekchar.s | 39 --------------------------------------- libsrc/vic20/cpeekchar.s | 39 --------------------------------------- 6 files changed, 228 deletions(-) delete mode 100644 libsrc/c16/cpeekchar.s delete mode 100644 libsrc/c64/cpeekchar.s delete mode 100644 libsrc/cbm510/cpeekchar.s delete mode 100644 libsrc/pet/cpeekchar.s delete mode 100644 libsrc/plus4/cpeekchar.s delete mode 100644 libsrc/vic20/cpeekchar.s diff --git a/libsrc/c16/cpeekchar.s b/libsrc/c16/cpeekchar.s deleted file mode 100644 index 5d89570f1..000000000 --- a/libsrc/c16/cpeekchar.s +++ /dev/null @@ -1,39 +0,0 @@ - - .export _cpeekchar - .export _cpeekcharxy - - .import _gotoxy - - .include "c16.inc" - - .segment "CODE" - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor - -_cpeekchar: - - ldy CURS_X - lda (SCREEN_PTR),y ; get char - ldx #0 - - and #$7f - - ; 0 - $1f +$40 - ; $20 - $3f - ; $40 - $7e +$80 - - cmp #$1f - bcs @sk1 -;; clc - adc #$40 - rts - -@sk1: - cmp #$40 - bcc @end - clc - adc #$80 -@end: - rts diff --git a/libsrc/c64/cpeekchar.s b/libsrc/c64/cpeekchar.s deleted file mode 100644 index 33d0284e7..000000000 --- a/libsrc/c64/cpeekchar.s +++ /dev/null @@ -1,39 +0,0 @@ - - .export _cpeekchar - .export _cpeekcharxy - - .import _gotoxy - - .include "c64.inc" - - .segment "CODE" - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor - -_cpeekchar: - - ldy CURS_X - lda (SCREEN_PTR),y ; get char - ldx #0 - - and #$7f - - ; 0 - $1f +$40 - ; $20 - $3f - ; $40 - $7e +$80 - - cmp #$1f - bcs @sk1 -;; clc - adc #$40 - rts - -@sk1: - cmp #$40 - bcc @end - clc - adc #$80 -@end: - rts diff --git a/libsrc/cbm510/cpeekchar.s b/libsrc/cbm510/cpeekchar.s deleted file mode 100644 index 11787fe1e..000000000 --- a/libsrc/cbm510/cpeekchar.s +++ /dev/null @@ -1,33 +0,0 @@ - - .export _cpeekchar - .export _cpeekcharxy - - .import _gotoxy - - .include "cbm510.inc" - .include "extzp.inc" - - .segment "CODE" - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor - -_cpeekchar: - lda #0 - ldx #0 - rts - - ;; ?!?! - - ldx IndReg - ldy #$0F - sty IndReg - - ldy CURS_X - lda (SCREEN_PTR),y ; get char - - stx IndReg - - ldx #0 - rts diff --git a/libsrc/pet/cpeekchar.s b/libsrc/pet/cpeekchar.s deleted file mode 100644 index c846beb56..000000000 --- a/libsrc/pet/cpeekchar.s +++ /dev/null @@ -1,39 +0,0 @@ - - .export _cpeekchar - .export _cpeekcharxy - - .import _gotoxy - - .include "pet.inc" - - .segment "CODE" - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor - -_cpeekchar: - - ldy CURS_X - lda (SCREEN_PTR),y ; get char - ldx #0 - - and #$7f - - ; 0 - $1f +$40 - ; $20 - $3f - ; $40 - $7e +$80 - - cmp #$1f - bcs @sk1 -;; clc - adc #$40 - rts - -@sk1: - cmp #$40 - bcc @end - clc - adc #$80 -@end: - rts diff --git a/libsrc/plus4/cpeekchar.s b/libsrc/plus4/cpeekchar.s deleted file mode 100644 index 1d47c6d64..000000000 --- a/libsrc/plus4/cpeekchar.s +++ /dev/null @@ -1,39 +0,0 @@ - - .export _cpeekchar - .export _cpeekcharxy - - .import _gotoxy - - .include "plus4.inc" - - .segment "CODE" - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor - -_cpeekchar: - - ldy CURS_X - lda (SCREEN_PTR),y ; get char - ldx #0 - - and #$7f - - ; 0 - $1f +$40 - ; $20 - $3f - ; $40 - $7e +$80 - - cmp #$1f - bcs @sk1 -;; clc - adc #$40 - rts - -@sk1: - cmp #$40 - bcc @end - clc - adc #$80 -@end: - rts diff --git a/libsrc/vic20/cpeekchar.s b/libsrc/vic20/cpeekchar.s deleted file mode 100644 index fae7ec1b4..000000000 --- a/libsrc/vic20/cpeekchar.s +++ /dev/null @@ -1,39 +0,0 @@ - - .export _cpeekchar - .export _cpeekcharxy - - .import _gotoxy - - .include "vic20.inc" - - .segment "CODE" - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor - -_cpeekchar: - - ldy CURS_X - lda (SCREEN_PTR),y ; get char - ldx #0 - - and #$7f - - ; 0 - $1f +$40 - ; $20 - $3f - ; $40 - $7e +$80 - - cmp #$1f - bcs @sk1 -;; clc - adc #$40 - rts - -@sk1: - cmp #$40 - bcc @end - clc - adc #$80 -@end: - rts From 10c2ce205b77c979ea396eb92bd503d5d9f75281 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 24 Jul 2022 04:59:45 +0200 Subject: [PATCH 016/707] cleanup --- libsrc/atari/cpeekchar.s | 50 ++++++++++++++++++---------------------- libsrc/atmos/cpeekchar.s | 43 +++++++++++++++------------------- libsrc/nes/cpeekchar.s | 40 ++++++++++++++------------------ 3 files changed, 58 insertions(+), 75 deletions(-) diff --git a/libsrc/atari/cpeekchar.s b/libsrc/atari/cpeekchar.s index 6697ce230..c895059db 100644 --- a/libsrc/atari/cpeekchar.s +++ b/libsrc/atari/cpeekchar.s @@ -1,41 +1,35 @@ - .export _cpeekchar - .export _cpeekcharxy + .export _cpeekchar - .import _gotoxy - .import mul40 - .importzp ptr4 + .import mul40 + .importzp ptr4 - .include "atari.inc" + .include "atari.inc" - .segment "CODE" - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor + .segment "CODE" _cpeekchar: - lda ROWCRS - jsr mul40 ; destroys tmp4 - clc - adc SAVMSC ; add start of screen memory - sta ptr4 - txa - adc SAVMSC+1 - sta ptr4+1 + lda ROWCRS + jsr mul40 ; destroys tmp4 + clc + adc SAVMSC ; add start of screen memory + sta ptr4 + txa + adc SAVMSC+1 + sta ptr4+1 - ldy COLCRS - lda (ptr4),y ; get char - tax + ldy COLCRS + lda (ptr4),y ; get char + tax - ;; convert to asc + ;; convert to asc - ;; ugly hack here to make tetris fx work :=P - lda #' ' - cpx #0 + ;; FIXME: ugly hack here to make tetris fx work :=P + lda #' ' + cpx #0 beq @l - lda #0 + lda #0 @l: ldx #0 - rts + rts diff --git a/libsrc/atmos/cpeekchar.s b/libsrc/atmos/cpeekchar.s index a1d6d4474..a03bdb6a7 100644 --- a/libsrc/atmos/cpeekchar.s +++ b/libsrc/atmos/cpeekchar.s @@ -1,36 +1,31 @@ - .include "atmos.inc" + .include "atmos.inc" -.import _gotoxy -.export _cpeekchar,_cpeekcharxy - -_cpeekcharxy: - - jsr _gotoxy ; Will pop x parameter + .export _cpeekchar _cpeekchar: - ldy CURS_Y - ldx ScrTabLo,y - stx @l+1 - ldx ScrTabHi,y - stx @l+2 - ldx CURS_X + ldy CURS_Y + ldx ScrTabLo,y + stx @l+1 + ldx ScrTabHi,y + stx @l+2 + ldx CURS_X @l: - lda $bb80,x -;; inc COORDX_TEXT - ldx #0 - rts + lda $bb80,x +;; inc COORDX_TEXT + ldx #0 + rts - ; FIXME: is that table available elsewhere? + ; FIXME: is that table available elsewhere? .rodata ScrTabLo: - .repeat 28, Line - .byte <(SCREEN + Line * 40) - .endrep + .repeat 28, Line + .byte <(SCREEN + Line * 40) + .endrep ScrTabHi: - .repeat 28, Line - .byte >(SCREEN + Line * 40) - .endrep + .repeat 28, Line + .byte >(SCREEN + Line * 40) + .endrep diff --git a/libsrc/nes/cpeekchar.s b/libsrc/nes/cpeekchar.s index 292a4591f..995e01bc1 100644 --- a/libsrc/nes/cpeekchar.s +++ b/libsrc/nes/cpeekchar.s @@ -1,40 +1,34 @@ - .export _cpeekchar - .export _cpeekcharxy + .export _cpeekchar - .import _gotoxy - .import ppubuf_waitempty + .import ppubuf_waitempty - .include "nes.inc" + .include "nes.inc" - .segment "CODE" - -_cpeekcharxy: - - jsr _gotoxy ; Set cursor + .segment "CODE" _cpeekchar: - ; wait until all console data has been written - jsr ppubuf_waitempty + ; wait until all console data has been written + jsr ppubuf_waitempty + + ldy SCREEN_PTR+1 + ldx SCREEN_PTR - ldy SCREEN_PTR+1 - ldx SCREEN_PTR - ; waiting for vblank is incredibly slow :// vwait: -; lda $2002 ;wait -; bpl vwait +; lda $2002 ;wait +; bpl vwait - lda #0 - sty $2006 + lda #0 + sty $2006 stx $2006 - ldy $2007 ; first read is invalid - ldy $2007 ; get data + ldy $2007 ; first read is invalid + ldy $2007 ; get data sta $2006 sta $2006 tya - and #$7f ; ?!?! - rts + and #$7f ; ?!?! + rts From aeb13b60a71efb71624d63b753bf828acb3fef0b Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 24 Jul 2022 19:10:27 +0200 Subject: [PATCH 017/707] rename --- libsrc/atari/cpeekchar.s | 4 ++-- libsrc/atmos/cpeekchar.s | 4 ++-- libsrc/nes/cpeekchar.s | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libsrc/atari/cpeekchar.s b/libsrc/atari/cpeekchar.s index c895059db..ff502074d 100644 --- a/libsrc/atari/cpeekchar.s +++ b/libsrc/atari/cpeekchar.s @@ -1,5 +1,5 @@ - .export _cpeekchar + .export _cpeekc .import mul40 .importzp ptr4 @@ -8,7 +8,7 @@ .segment "CODE" -_cpeekchar: +_cpeekc: lda ROWCRS jsr mul40 ; destroys tmp4 diff --git a/libsrc/atmos/cpeekchar.s b/libsrc/atmos/cpeekchar.s index a03bdb6a7..2139989c3 100644 --- a/libsrc/atmos/cpeekchar.s +++ b/libsrc/atmos/cpeekchar.s @@ -1,9 +1,9 @@ .include "atmos.inc" - .export _cpeekchar + .export _cpeekc -_cpeekchar: +_cpeekc: ldy CURS_Y ldx ScrTabLo,y diff --git a/libsrc/nes/cpeekchar.s b/libsrc/nes/cpeekchar.s index 995e01bc1..b4e3c34fd 100644 --- a/libsrc/nes/cpeekchar.s +++ b/libsrc/nes/cpeekchar.s @@ -1,5 +1,5 @@ - .export _cpeekchar + .export _cpeekc .import ppubuf_waitempty @@ -7,7 +7,7 @@ .segment "CODE" -_cpeekchar: +_cpeekc: ; wait until all console data has been written jsr ppubuf_waitempty From a998d3490713e29f8ce16ecc7967cede6227a733 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 24 Jul 2022 19:16:15 +0200 Subject: [PATCH 018/707] remove tabs --- libsrc/atmos/cpeekchar.s | 3 +-- libsrc/nes/cpeekchar.s | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libsrc/atmos/cpeekchar.s b/libsrc/atmos/cpeekchar.s index 2139989c3..fba51bf72 100644 --- a/libsrc/atmos/cpeekchar.s +++ b/libsrc/atmos/cpeekchar.s @@ -1,5 +1,5 @@ - .include "atmos.inc" + .include "atmos.inc" .export _cpeekc @@ -28,4 +28,3 @@ ScrTabHi: .repeat 28, Line .byte >(SCREEN + Line * 40) .endrep - diff --git a/libsrc/nes/cpeekchar.s b/libsrc/nes/cpeekchar.s index b4e3c34fd..55230edbc 100644 --- a/libsrc/nes/cpeekchar.s +++ b/libsrc/nes/cpeekchar.s @@ -3,7 +3,7 @@ .import ppubuf_waitempty - .include "nes.inc" + .include "nes.inc" .segment "CODE" From c8df241337756d88526ea3589b0ceaa53c4a10d3 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky Date: Sat, 23 Sep 2023 14:19:11 +0300 Subject: [PATCH 019/707] Add line_continuations feature that works as .LINECONT but in a consistent way with other features. --- src/ca65/feature.c | 2 ++ src/ca65/feature.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/ca65/feature.c b/src/ca65/feature.c index 9f5ca5876..6a38900b5 100644 --- a/src/ca65/feature.c +++ b/src/ca65/feature.c @@ -67,6 +67,7 @@ static const char* const FeatureKeys[FEAT_COUNT] = { "bracket_as_indirect", "string_escapes", "long_jsr_jmp_rts", + "line_continuations", }; @@ -121,6 +122,7 @@ void SetFeature (feature_t Feature, unsigned char On) case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = On; break; case FEAT_STRING_ESCAPES: StringEscapes = On; break; case FEAT_LONG_JSR_JMP_RTS: LongJsrJmpRts = On; break; + case FEAT_LINE_CONTINUATIONS: LineCont = On; break; default: break; } } diff --git a/src/ca65/feature.h b/src/ca65/feature.h index 8eeb62e6f..4d307f74d 100644 --- a/src/ca65/feature.h +++ b/src/ca65/feature.h @@ -69,6 +69,7 @@ typedef enum { FEAT_BRACKET_AS_INDIRECT, FEAT_STRING_ESCAPES, FEAT_LONG_JSR_JMP_RTS, + FEAT_LINE_CONTINUATIONS, /* Special value: Number of features available */ FEAT_COUNT From 850007cb441f89646ee42be047a87e80b30568ca Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky Date: Sat, 23 Sep 2023 18:45:27 +0300 Subject: [PATCH 020/707] Document line_continuations feature. --- doc/ca65.sgml | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index b0ccf6f5e..104c59bbd 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -2867,6 +2867,26 @@ See: , + + Switch on or off line continuations using the backslash character + before a newline. The option is off by default. + Note: Line continuations do not work in a comment. A backslash at the + end of a comment is treated as part of the comment and does not trigger + line continuation. + + Example: + + + .feature line_continuations + ; Allow line continuations + + lda \ + #$20 ; This is legal now + + + For backward compatibility reasons, the .LINECONT + control command + is also supported and enables the same feature. + long_jsr_jmp_rts Affects 65816 mode only. @@ -3371,26 +3391,6 @@ See: ,

- - Switch on or off line continuations using the backslash character - before a newline. The option is off by default. - Note: Line continuations do not work in a comment. A backslash at the - end of a comment is treated as part of the comment and does not trigger - line continuation. - The command can be followed by a '+' or '-' character to switch the - option on or off respectively. - - Example: - - - .linecont + ; Allow line continuations - - lda \ - #$20 ; This is legal now - - - .LIST

Enable output to the listing. The command can be followed by a boolean @@ -4489,9 +4489,9 @@ different: Macros defined with may not span more than a line. You may use line continuation (see ) to spread the definition over - more than one line for increased readability, but the macro itself - may not contain an end-of-line token. + id="line_continuations" name="line_continuations">) to spread the + definition over more than one line for increased readability, but the + macro itself may not contain an end-of-line token. Macros defined with share the name space with classic macros, but they are detected and replaced From 3b7af398a989e876b1e7afb48d6b6a81fcfcb7c9 Mon Sep 17 00:00:00 2001 From: acqn Date: Wed, 15 Nov 2023 21:32:24 +0800 Subject: [PATCH 021/707] Fixed initialization of union when it has an anonymous bit-field as the first member declaration. --- src/cc65/initdata.c | 38 ++++++++++++++++++++------------------ test/val/bitfield-union.c | 9 +++++++-- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/cc65/initdata.c b/src/cc65/initdata.c index e9442737c..5401e577c 100644 --- a/src/cc65/initdata.c +++ b/src/cc65/initdata.c @@ -511,18 +511,20 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) /* This may be an anonymous bit-field, in which case it doesn't ** have an initializer. */ - if (SymIsBitField (TagSym) && (IsAnonName (TagSym->Name))) { - /* Account for the data and output it if we have at least a full - ** byte. We may have more if there was storage unit overlap, for - ** example two consecutive 7 bit fields. Those would be packed - ** into 2 bytes. - */ - SI.ValBits += TagSym->Type->A.B.Width; - CHECK (SI.ValBits <= CHAR_BIT * sizeof(SI.BitVal)); - /* TODO: Generalize this so any type can be used. */ - CHECK (SI.ValBits <= LONG_BITS); - while (SI.ValBits >= CHAR_BITS) { - DefineBitFieldData (&SI); + if (SymIsBitField (TagSym) && IsAnonName (TagSym->Name)) { + if (!IsTypeUnion (T)) { + /* Account for the data and output it if we have at least a full + ** byte. We may have more if there was storage unit overlap, for + ** example two consecutive 7 bit fields. Those would be packed + ** into 2 bytes. + */ + SI.ValBits += TagSym->Type->A.B.Width; + CHECK (SI.ValBits <= CHAR_BIT * sizeof(SI.BitVal)); + /* TODO: Generalize this so any type can be used. */ + CHECK (SI.ValBits <= LONG_BITS); + while (SI.ValBits >= CHAR_BITS) { + DefineBitFieldData (&SI); + } } /* Avoid consuming the comma if any */ goto NextMember; @@ -628,15 +630,15 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers) /* Skip the comma next round */ SkipComma = 1; -NextMember: - /* Next member. For unions, only the first one can be initialized */ + /* For unions, only the first named member can be initialized */ if (IsTypeUnion (T)) { - /* Union */ TagSym = 0; - } else { - /* Struct */ - TagSym = TagSym->NextSym; + continue; } + +NextMember: + /* Next member */ + TagSym = TagSym->NextSym; } if (HasCurly) { diff --git a/test/val/bitfield-union.c b/test/val/bitfield-union.c index 1fd201456..4c01d2183 100644 --- a/test/val/bitfield-union.c +++ b/test/val/bitfield-union.c @@ -1,5 +1,5 @@ /* - Copyright 2020 The cc65 Authors + Copyright 2020-2023 The cc65 Authors This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,6 +25,7 @@ #include typedef union { + const unsigned int : 1; unsigned int bf; struct { @@ -38,8 +39,12 @@ static unsigned char failures = 0; int main (void) { - bitfield_t bitfield = {0}; + bitfield_t bitfield = { 42 }; + printf ("Bitfield: %u\n", bitfield.bf); + if (bitfield.bf != 42) failures++; + + bitfield.bf ^= 42; printf ("Bitfield: %u\n", bitfield.bf); if (bitfield.bf != 0) failures++; From 6434176909002b3183a7c82d2909d8c740407bf4 Mon Sep 17 00:00:00 2001 From: acqn Date: Wed, 29 Nov 2023 12:27:01 +0800 Subject: [PATCH 022/707] Fixed constness of bit-fields. --- src/cc65/datatype.c | 4 ++-- src/cc65/datatype.h | 4 ++-- src/cc65/symtab.c | 1 + test/err/bug2018-bitfield.c | 14 ++++++++++++++ 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 test/err/bug2018-bitfield.c diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 81727e491..9e0652526 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -497,8 +497,8 @@ Type* NewPointerTo (const Type* T) Type* NewBitFieldOf (const Type* T, unsigned BitOffs, unsigned BitWidth) -/* Return a type string that is "T : BitWidth" aligned on BitOffs. The type -** string is allocated on the heap and may be freed after use. +/* Return a type string that is "unqualified T : BitWidth" aligned on BitOffs. +** The type string is allocated on the heap and may be freed after use. */ { Type* P; diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 0890c4d12..4f4b6f25e 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -435,8 +435,8 @@ Type* NewPointerTo (const Type* T); */ Type* NewBitFieldOf (const Type* T, unsigned BitOffs, unsigned BitWidth); -/* Return a type string that is "T : BitWidth" aligned on BitOffs. The type -** string is allocated on the heap and may be freed after use. +/* Return a type string that is "unqualified T : BitWidth" aligned on BitOffs. +** The type string is allocated on the heap and may be freed after use. */ const Type* AddressOf (const Type* T); diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index d30e591c9..a4ca9e23d 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -1023,6 +1023,7 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, } else { Entry->Type = NewBitFieldOf (T, BitOffs, BitWidth); } + Entry->Type[0].C |= GetQualifier (T) & T_MASK_QUAL; /* Add the entry to the symbol table */ AddSymEntry (FieldTab, Entry); diff --git a/test/err/bug2018-bitfield.c b/test/err/bug2018-bitfield.c new file mode 100644 index 000000000..ea2928659 --- /dev/null +++ b/test/err/bug2018-bitfield.c @@ -0,0 +1,14 @@ +/* Bug #2018 - Compiler has problems with const struct fields */ + +typedef union U { + int a : 16; + const int b : 16; +} U; + +int main(void) +{ + U x = { 42 }; + x.b = 0; + + return 0; +} From c0a2021d9ae8a68989a873452085eda76b6b7a39 Mon Sep 17 00:00:00 2001 From: acqn Date: Thu, 30 Nov 2023 00:35:30 +0800 Subject: [PATCH 023/707] Fixed endlessly repeated disgnostics when there are some certain patterns of syntax errors in a struct/union declaration. --- src/cc65/compile.c | 44 ++++++++------------- src/cc65/declare.c | 95 ++++++++++++++++++++++++++++++++++------------ src/cc65/declare.h | 21 +++++++--- 3 files changed, 102 insertions(+), 58 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 02d37c53e..bef55e375 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -257,6 +257,7 @@ static void Parse (void) /* Parse the initialization */ ParseInit (Sym->Type); + } else { /* This is a declaration */ @@ -326,21 +327,19 @@ NextDecl: } } - /* Function declaration? */ - if (Sym && IsTypeFunc (Sym->Type)) { - - /* Function */ - if (CurTok.Tok == TOK_SEMI) { - /* Prototype only */ - NeedClean = 0; - NextToken (); - } else if (CurTok.Tok == TOK_LCURLY) { - /* ISO C: The type category in a function definition cannot be - ** inherited from a typedef. - */ + /* Finish the declaration */ + if (Sym) { + /* Function definition? */ + if (IsTypeFunc (Sym->Type) && CurTok.Tok == TOK_LCURLY) { if (IsTypeFunc (Spec.Type) && TypeCmp (Sym->Type, Spec.Type).C >= TC_EQUAL) { + /* ISO C: The type category in a function definition cannot be + ** inherited from a typedef. + */ Error ("Function cannot be defined with a typedef"); } else if (comma) { + /* ISO C: A function definition cannot shall its return type + ** specifier with other declarators. + */ Error ("';' expected after top level declarator"); } @@ -350,30 +349,19 @@ NextDecl: /* Make sure we aren't omitting any work */ CheckDeferredOpAllDone (); - } - - } else { - - if (Sym) { + } else { /* Must be followed by a semicolon */ - if (CurTok.Tok != TOK_SEMI) { + if (ConsumeSemi ()) { + NeedClean = 0; + } else { NeedClean = -1; } - ConsumeSemi (); } - } /* Try some smart error recovery */ if (PrevErrorCount != ErrorCount && NeedClean < 0) { - /* Some fix point tokens that are used for error recovery */ - static const token_t TokenList[] = { TOK_SEMI, TOK_RCURLY }; - - SmartErrorSkip (); - SkipTokens (TokenList, sizeof (TokenList) / sizeof (TokenList[0])); - if (CurTok.Tok == TOK_SEMI || CurTok.Tok == TOK_RCURLY) { - NextToken (); - } + SmartErrorSkip (1); } } diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 45d031ff2..b6620785f 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -117,11 +117,22 @@ static int CloseBrace (Collection* C, token_t Tok) -int SmartErrorSkip (void) -/* Try some smart error recovery. Skip tokens until either a comma or semicolon -** that is not enclosed in an open parenthesis/bracket/curly brace, or until an -** unpaired right parenthesis/bracket/curly brace is reached. Return 0 if it is -** the former case, or -1 if it is the latter case. */ +int SmartErrorSkip (int WholeDecl) +/* Try some smart error recovery. +** +** - If WholeDecl is 0: +** Skip tokens until a comma or closing curly brace that is not enclosed in +** an open parenthesis/bracket/curly brace, or until a semicolon, EOF or +** unpaired right parenthesis/bracket/curly brace is reached. +** +** - If WholeDecl is non-0: +** Skip tokens until a closing curly brace that is not enclosed in an open +** parenthesis/bracket/curly brace, or until a semicolon or EOF is reached. +** +** Return 0 if this exits as soon as it reaches an EOF. Return 0 as well if +** this exits with no open parentheses/brackets/curly braces. Otherwise, return +** -1. +*/ { Collection C = AUTO_COLLECTION_INITIALIZER; int Res = 0; @@ -142,31 +153,41 @@ int SmartErrorSkip (void) case TOK_RPAREN: case TOK_RBRACK: - if (CloseBrace (&C, CurTok.Tok)) { - Res = -1; - goto ExitPoint; + if (CloseBrace (&C, CurTok.Tok) < 0) { + if (!WholeDecl) { + Res = -1; + goto ExitPoint; + } + NextToken (); } break; case TOK_RCURLY: - if (CloseBrace (&C, CurTok.Tok)) { - Res = -1; - goto ExitPoint; + if (CloseBrace (&C, CurTok.Tok) < 0) { + if (!WholeDecl) { + Res = -1; + goto ExitPoint; + } + NextToken (); } else if (CollCount (&C) == 0) { goto ExitPoint; } break; case TOK_COMMA: - if (CollCount (&C) == 0) { + if (CollCount (&C) == 0 && !WholeDecl) { goto ExitPoint; } NextToken (); break; case TOK_SEMI: + if (CollCount (&C) != 0) { + Res = -1; + } + goto ExitPoint; + case TOK_CEOF: - Res = -1; goto ExitPoint; default: @@ -1058,8 +1079,9 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) while (CurTok.Tok != TOK_RCURLY) { /* Get the type of the entry */ - DeclSpec Spec; - int SignednessSpecified = 0; + DeclSpec Spec; + int SignednessSpecified = 0; + int NeedClean = 0; /* Check for a _Static_assert */ if (CurTok.Tok == TOK_STATIC_ASSERT) { @@ -1076,7 +1098,7 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) Declarator Decl; /* Get type and name of the struct field */ - ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT); + NeedClean = ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT); /* Check for a bit-field declaration */ FieldWidth = ParseFieldWidth (&Decl); @@ -1172,7 +1194,18 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { } NextToken (); } - ConsumeSemi (); + + /* Must be followed by a semicolon */ + if (NeedClean >= 0 && ConsumeSemi ()) { + NeedClean = 0; + } else { + NeedClean = -1; + } + + /* Try some smart error recovery */ + if (NeedClean < 0) { + SmartErrorSkip (1); + } } /* Skip the closing brace */ @@ -1236,8 +1269,9 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) while (CurTok.Tok != TOK_RCURLY) { /* Get the type of the entry */ - DeclSpec Spec; - int SignednessSpecified = 0; + DeclSpec Spec; + int SignednessSpecified = 0; + int NeedClean = 0; /* Check for a _Static_assert */ if (CurTok.Tok == TOK_STATIC_ASSERT) { @@ -1262,7 +1296,7 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) } /* Get type and name of the struct field */ - ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT); + NeedClean = ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT); /* Check for a bit-field declaration */ FieldWidth = ParseFieldWidth (&Decl); @@ -1403,7 +1437,18 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { } NextToken (); } - ConsumeSemi (); + + /* Must be followed by a semicolon */ + if (NeedClean >= 0 && ConsumeSemi ()) { + NeedClean = 0; + } else { + NeedClean = -1; + } + + /* Try some smart error recovery */ + if (NeedClean < 0) { + SmartErrorSkip (1); + } } if (BitOffs > 0) { @@ -1778,7 +1823,7 @@ static void ParseOldStyleParamList (FuncDesc* F) Error ("Identifier expected for parameter name"); /* Try some smart error recovery */ - if (SmartErrorSkip () < 0) { + if (SmartErrorSkip (0) < 0) { break; } } @@ -1868,7 +1913,7 @@ static void ParseOldStyleParamList (FuncDesc* F) if (PrevErrorCount != ErrorCount && CurTok.Tok != TOK_LCURLY) { /* Try some smart error recovery */ - SmartErrorSkip (); + SmartErrorSkip (0); } } @@ -1953,7 +1998,7 @@ static void ParseAnsiParamList (FuncDesc* F) if (PrevErrorCount != ErrorCount) { /* Try some smart error recovery */ - if (SmartErrorSkip () < 0) { + if (SmartErrorSkip (0) < 0) { break; } } @@ -2335,7 +2380,7 @@ int ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode) /* Try some smart error recovery */ if (CurTok.Tok != TOK_LCURLY || !IsTypeFunc (D->Type)) { - return SmartErrorSkip (); + return SmartErrorSkip (0); } } diff --git a/src/cc65/declare.h b/src/cc65/declare.h index add86594d..1ce764f7a 100644 --- a/src/cc65/declare.h +++ b/src/cc65/declare.h @@ -128,11 +128,22 @@ typedef enum { -int SmartErrorSkip (void); -/* Try some smart error recovery. Skip tokens until either a comma or semicolon -** that is not enclosed in an open parenthesis/bracket/curly brace, or until an -** unpaired right parenthesis/bracket/curly brace is reached. Return 0 if it is -** the former case, or -1 if it is the latter case. */ +int SmartErrorSkip (int WholeDecl); +/* Try some smart error recovery. +** +** - If WholeDecl is 0: +** Skip tokens until a comma or closing curly brace that is not enclosed in +** an open parenthesis/bracket/curly brace, or until a semicolon, EOF or +** unpaired right parenthesis/bracket/curly brace is reached. +** +** - If WholeDecl is non-0: +** Skip tokens until a closing curly brace that is not enclosed in an open +** parenthesis/bracket/curly brace, or until a semicolon or EOF is reached. +** +** Return 0 if this exits as soon as it reaches an EOF. Return 0 as well if +** this exits with no open parentheses/brackets/curly braces. Otherwise, return +** -1. +*/ Type* ParseType (Type* Type); /* Parse a complete type specification */ From 47e7ed2f560c991959e4d3c09254e820ecd1fe25 Mon Sep 17 00:00:00 2001 From: acqn Date: Thu, 30 Nov 2023 00:36:13 +0800 Subject: [PATCH 024/707] Fixed wrong "Mixed declarations and code are not supported in cc65" error message when it should be "Expression expected". --- src/cc65/expr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 6d4b04892..54984230c 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1412,9 +1412,9 @@ static void Primary (ExprDesc* E) } else { /* Let's see if this is a C99-style declaration */ DeclSpec Spec; - ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT, SC_AUTO); + ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE, SC_AUTO); - if (Spec.Type->C != T_END) { + if ((Spec.Flags & DS_DEF_TYPE) == 0) { /* Recognized but not supported */ Error ("Mixed declarations and code are not supported in cc65"); From d8a3938f2b8d6c53c2f75b5a07964e8beef746a5 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Mon, 13 Nov 2023 20:24:14 +0100 Subject: [PATCH 025/707] Optimize a bit static long assignation --- src/Makefile | 2 +- src/cc65.vcxproj | 4 +- src/cc65/codegen.c | 42 ++------- src/cc65/codeopt.c | 7 ++ src/cc65/coptlong.c | 210 +++++++++++++++++++++++++++++++++++++++++ src/cc65/coptlong.h | 63 +++++++++++++ test/val/long.c | 41 ++++++++ test/val/static-long.c | 41 ++++++++ 8 files changed, 374 insertions(+), 36 deletions(-) create mode 100644 src/cc65/coptlong.c create mode 100644 src/cc65/coptlong.h create mode 100644 test/val/long.c create mode 100644 test/val/static-long.c diff --git a/src/Makefile b/src/Makefile index 034a2230f..4b993c881 100644 --- a/src/Makefile +++ b/src/Makefile @@ -66,7 +66,7 @@ ifndef BUILD_ID endif $(info BUILD_ID: $(BUILD_ID)) -CFLAGS += -MMD -MP -O3 -I common \ +CFLAGS += -MMD -MP -O0 -g -I common \ -Wall -Wextra -Wno-char-subscripts $(USER_CFLAGS) \ -DCA65_INC="\"$(CA65_INC)\"" -DCC65_INC="\"$(CC65_INC)\"" -DCL65_TGT="\"$(CL65_TGT)\"" \ -DLD65_LIB="\"$(LD65_LIB)\"" -DLD65_OBJ="\"$(LD65_OBJ)\"" -DLD65_CFG="\"$(LD65_CFG)\"" \ diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 6f3f8e4e4..9c1719538 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -69,6 +69,7 @@ + @@ -150,6 +151,7 @@ + @@ -214,4 +216,4 @@ - \ No newline at end of file + diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 2721f8e96..db487ca40 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -705,7 +705,6 @@ void g_getimmed (unsigned Flags, uintptr_t Val, long Offs) /* Load a constant into the primary register */ { unsigned char B1, B2, B3, B4; - unsigned Done; if ((Flags & CF_CONST) != 0) { @@ -731,40 +730,15 @@ void g_getimmed (unsigned Flags, uintptr_t Val, long Offs) B3 = (unsigned char) (Val >> 16); B4 = (unsigned char) (Val >> 24); - /* Remember which bytes are done */ - Done = 0; - - /* Load the value */ - AddCodeLine ("ldx #$%02X", B2); - Done |= 0x02; - if (B2 == B3) { - AddCodeLine ("stx sreg"); - Done |= 0x04; - } - if (B2 == B4) { - AddCodeLine ("stx sreg+1"); - Done |= 0x08; - } - if ((Done & 0x04) == 0 && B1 != B3) { - AddCodeLine ("lda #$%02X", B3); - AddCodeLine ("sta sreg"); - Done |= 0x04; - } - if ((Done & 0x08) == 0 && B1 != B4) { - AddCodeLine ("lda #$%02X", B4); - AddCodeLine ("sta sreg+1"); - Done |= 0x08; - } + /* Load the value. Don't be too smart here and let + * the optimizer do its job. + */ + AddCodeLine ("lda #$%02X", B4); + AddCodeLine ("sta sreg+1"); + AddCodeLine ("lda #$%02X", B3); + AddCodeLine ("sta sreg"); AddCodeLine ("lda #$%02X", B1); - Done |= 0x01; - if ((Done & 0x04) == 0) { - CHECK (B1 == B3); - AddCodeLine ("sta sreg"); - } - if ((Done & 0x08) == 0) { - CHECK (B1 == B4); - AddCodeLine ("sta sreg+1"); - } + AddCodeLine ("ldx #$%02X", B2); break; default: diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 3a2c2a35d..c9c1592bc 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -57,6 +57,7 @@ #include "coptcmp.h" #include "coptind.h" #include "coptjmp.h" +#include "coptlong.h" #include "coptmisc.h" #include "coptptrload.h" #include "coptptrstore.h" @@ -150,6 +151,8 @@ static OptFunc DOptJumpTarget3 = { OptJumpTarget3, "OptJumpTarget3", 100, 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 DOptLoad3 = { OptLoad3, "OptLoad3", 0, 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 DOptNegAX1 = { OptNegAX1, "OptNegAX1", 165, 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 }; @@ -262,6 +265,8 @@ static OptFunc* OptFuncs[] = { &DOptLoad1, &DOptLoad2, &DOptLoad3, + &DOptLongAssign, + &DOptLongCopy, &DOptNegAX1, &DOptNegAX2, &DOptPrecalc, @@ -632,6 +637,7 @@ static unsigned RunOptGroup1 (CodeSeg* S) Changes += RunOptFunc (S, &DOptAdd6, 1); Changes += RunOptFunc (S, &DOptSub1, 1); Changes += RunOptFunc (S, &DOptSub3, 1); + Changes += RunOptFunc (S, &DOptLongAssign, 1); Changes += RunOptFunc (S, &DOptStore4, 1); Changes += RunOptFunc (S, &DOptStore5, 1); Changes += RunOptFunc (S, &DOptShift1, 1); @@ -641,6 +647,7 @@ static unsigned RunOptGroup1 (CodeSeg* S) Changes += RunOptFunc (S, &DOptStore1, 1); Changes += RunOptFunc (S, &DOptStore2, 5); Changes += RunOptFunc (S, &DOptStore3, 5); + Changes += RunOptFunc (S, &DOptLongCopy, 1); /* Return the number of changes */ return Changes; diff --git a/src/cc65/coptlong.c b/src/cc65/coptlong.c new file mode 100644 index 000000000..16f089e49 --- /dev/null +++ b/src/cc65/coptlong.c @@ -0,0 +1,210 @@ +/*****************************************************************************/ +/* */ +/* coptlong.c */ +/* */ +/* Long integers optimizations */ +/* */ +/* */ +/* */ +/* (C) 2001-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* (C) 2023, Colin Leroy-Mira OPC == OP65_LDA && + L[1]->OPC == OP65_STA && + !strcmp (L[1]->Arg, "sreg+1") && + L[2]->OPC == OP65_LDA && + L[3]->OPC == OP65_STA && + !strcmp (L[3]->Arg, "sreg") && + L[4]->OPC == OP65_LDA && + L[5]->OPC == OP65_LDX && + L[6]->OPC == OP65_STA && + L[7]->OPC == OP65_STX && + !strncmp(L[7]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && + !strcmp(L[7]->Arg + strlen(L[6]->Arg), "+1") && + L[8]->OPC == OP65_LDY && + !strcmp (L[8]->Arg, "sreg") && + L[9]->OPC == OP65_STY && + !strncmp(L[9]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && + !strcmp(L[9]->Arg + strlen(L[6]->Arg), "+2") && + L[10]->OPC == OP65_LDY && + !strcmp (L[10]->Arg, "sreg+1") && + L[11]->OPC == OP65_STY && + !strncmp(L[11]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && + !strcmp(L[11]->Arg + strlen(L[6]->Arg), "+3") && + !RegXUsed (S, I+11)) { + + L[1]->AM = L[11]->AM; + CE_SetArg(L[1], L[11]->Arg); + + L[3]->AM = L[9]->AM; + CE_SetArg(L[3], L[9]->Arg); + + CS_DelEntries (S, I+8, 4); + + /* Remember, we had changes */ + ++Changes; + } + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + +unsigned OptLongCopy (CodeSeg* S) +/* Simplify long copies. +** Recognize +** lda XXX+3 0 +** sta sreg+1 1 +** lda XXX+2 2 +** sta sreg 3 +** ldx XXX+1 4 +** lda XXX 5 +** sta YYY 6 +** stx YYY+1 7 +** ldy sreg 8 +** sty YYY+2 9 +** ldy sreg+1 10 +** sty YYY+3 11 +** and simplify if not used right after. +*/ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[12]; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + if (CS_GetEntries (S, L+1, I+1, 11)) { + if (L[0]->OPC == OP65_LDA && + !strncmp(L[0]->Arg, L[5]->Arg, strlen(L[5]->Arg)) && + !strcmp(L[0]->Arg + strlen(L[5]->Arg), "+3") && + L[1]->OPC == OP65_STA && + !strcmp (L[1]->Arg, "sreg+1") && + L[2]->OPC == OP65_LDA && + !strncmp(L[2]->Arg, L[5]->Arg, strlen(L[5]->Arg)) && + !strcmp(L[2]->Arg + strlen(L[5]->Arg), "+2") && + L[3]->OPC == OP65_STA && + !strcmp (L[3]->Arg, "sreg") && + L[4]->OPC == OP65_LDX && + !strncmp(L[4]->Arg, L[5]->Arg, strlen(L[5]->Arg)) && + !strcmp(L[4]->Arg + strlen(L[5]->Arg), "+1") && + L[5]->OPC == OP65_LDA && + L[6]->OPC == OP65_STA && + L[7]->OPC == OP65_STX && + !strncmp(L[7]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && + !strcmp(L[7]->Arg + strlen(L[6]->Arg), "+1") && + L[8]->OPC == OP65_LDY && + !strcmp (L[8]->Arg, "sreg") && + L[9]->OPC == OP65_STY && + !strncmp(L[9]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && + !strcmp(L[9]->Arg + strlen(L[6]->Arg), "+2") && + L[10]->OPC == OP65_LDY && + !strcmp (L[10]->Arg, "sreg+1") && + L[11]->OPC == OP65_STY && + !strncmp(L[11]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && + !strcmp(L[11]->Arg + strlen(L[6]->Arg), "+3") && + !RegXUsed (S, I+11)) { + + L[1]->AM = L[11]->AM; + CE_SetArg(L[1], L[11]->Arg); + + L[3]->AM = L[9]->AM; + CE_SetArg(L[3], L[9]->Arg); + + CS_DelEntries (S, I+8, 4); + + /* Remember, we had changes */ + ++Changes; + } + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} diff --git a/src/cc65/coptlong.h b/src/cc65/coptlong.h new file mode 100644 index 000000000..c0233c299 --- /dev/null +++ b/src/cc65/coptlong.h @@ -0,0 +1,63 @@ +/*****************************************************************************/ +/* */ +/* coptlong.h */ +/* */ +/* Long integers optimizations */ +/* */ +/* */ +/* */ +/* (C) 2001-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* (C) 2023, Colin Leroy-Mira +#include + +int res = 0; + +int main(void) +{ + long a, b; + + a = 0x12345678L; + + /* Test assignment */ + b = a; + if (b != a) { + res++; + } + + /* Test increment */ + b++; + if (b != 0x12345679L) { + res++; + } + + /* Test decrement */ + b--; + if (b != 0x12345678L) { + res++; + } + + /* Test pre-decrement with test */ + if (--b != 0x12345677L) { + res++; + } + + a = --b; + if (a != 0x12345676L) { + res++; + } + + return res; +} diff --git a/test/val/static-long.c b/test/val/static-long.c new file mode 100644 index 000000000..a2e4e53a3 --- /dev/null +++ b/test/val/static-long.c @@ -0,0 +1,41 @@ +#include +#include + +int res = 0; + +int main(void) +{ + static long a, b; + + a = 0x12345678L; + + /* Test assignment */ + b = a; + if (b != a) { + res++; + } + + /* Test increment */ + b++; + if (b != 0x12345679L) { + res++; + } + + /* Test decrement */ + b--; + if (b != 0x12345678L) { + res++; + } + + /* Test pre-decrement with test */ + if (--b != 0x12345677L) { + res++; + } + + a = --b; + if (a != 0x12345676L) { + res++; + } + + return res; +} From 63861766e1fc9907536ab4f211652c62b908faba Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Fri, 1 Dec 2023 14:22:30 +0100 Subject: [PATCH 026/707] Fix Makefile change --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 4b993c881..034a2230f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -66,7 +66,7 @@ ifndef BUILD_ID endif $(info BUILD_ID: $(BUILD_ID)) -CFLAGS += -MMD -MP -O0 -g -I common \ +CFLAGS += -MMD -MP -O3 -I common \ -Wall -Wextra -Wno-char-subscripts $(USER_CFLAGS) \ -DCA65_INC="\"$(CA65_INC)\"" -DCC65_INC="\"$(CC65_INC)\"" -DCL65_TGT="\"$(CL65_TGT)\"" \ -DLD65_LIB="\"$(LD65_LIB)\"" -DLD65_OBJ="\"$(LD65_OBJ)\"" -DLD65_CFG="\"$(LD65_CFG)\"" \ From b7e7bb7489bb1509b4c67a8d0242a690f3a3a2c3 Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 9 Dec 2023 14:34:37 +0800 Subject: [PATCH 027/707] Fixed the issue that qualifiers of pointees of function parameters were ignored for type compatibility check. --- src/cc65/typecmp.c | 8 +++++--- src/cc65/typecmp.h | 12 +++++++----- test/err/bug2286-param-qualifier.c | 4 ++++ 3 files changed, 16 insertions(+), 8 deletions(-) create mode 100644 test/err/bug2286-param-qualifier.c diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index bb8bca880..e8b790a69 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -69,6 +69,7 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) /* Get the symbol types */ const Type* Type1 = Sym1->Type; const Type* Type2 = Sym2->Type; + typecmp_t CmpResult; /* If either of both functions is old style, apply the default ** promotions to the parameter type. @@ -84,9 +85,10 @@ static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2) } } - /* Compare this field */ - if (TypeCmp (Type1, Type2).C < TC_EQUAL) { - /* Field types not equal */ + /* Compare types of this parameter */ + CmpResult = TypeCmp (Type1, Type2); + if (CmpResult.C < TC_EQUAL || (CmpResult.F & TCF_MASK_PARAM_DIFF) != 0) { + /* The types are not compatible */ return 0; } diff --git a/src/cc65/typecmp.h b/src/cc65/typecmp.h index fa97ca176..43acc7ea5 100644 --- a/src/cc65/typecmp.h +++ b/src/cc65/typecmp.h @@ -68,15 +68,17 @@ typedef enum { TCF_VOID_PTR_ON_LEFT = 0x01, /* lhs is a void pointer */ TCF_VOID_PTR_ON_RIGHT = 0x02, /* rhs is a void pointer */ TCF_MASK_VOID_PTR = TCF_VOID_PTR_ON_LEFT | TCF_VOID_PTR_ON_RIGHT, - TCF_QUAL_DIFF = 0x04, /* CVR qualifiers differ in a way that doesn't matter */ + TCF_QUAL_DIFF = 0x04, /* lhs doesn't have all of CVR qualifiers of rhs */ TCF_QUAL_IMPLICIT = 0x08, /* CVR qualifiers of lhs are stricter than those of rhs */ - TCF_PTR_QUAL_DIFF = 0x10, /* CVR qualifiers of pointers differ */ - TCF_PTR_QUAL_IMPLICIT = 0x20, /* CVR qualifiers of pointers are stricter on lhs than those on rhs */ - TCF_MASK_C_QUAL_DIFF = 0x3C, /* All C Standard qualifiers */ + TCF_MASK_CVR_DIFF = 0x0C, /* All CVR qualifiers */ + TCF_PTR_QUAL_DIFF = 0x10, /* lhs pointee doesn't have all of CVR qualifiers of rhs pointee */ + TCF_PTR_QUAL_IMPLICIT = 0x20, /* CVR qualifiers of pointees are stricter on lhs than those on rhs */ + TCF_MASK_PTR_QUAL_DIFF = 0x30, /* All CVR qualifiers of pointees */ TCF_ADDRSIZE_QUAL_DIFF = 0x40, /* Address size qualifiers differ */ TCF_CCONV_QUAL_DIFF = 0x80, /* Function calling conventions differ. Unused now */ TCF_INCOMPATIBLE_QUAL = TCF_ADDRSIZE_QUAL_DIFF | TCF_CCONV_QUAL_DIFF, - TCF_MASK_QUAL = TCF_MASK_C_QUAL_DIFF | TCF_INCOMPATIBLE_QUAL, + TCF_MASK_PARAM_DIFF = TCF_MASK_PTR_QUAL_DIFF | TCF_INCOMPATIBLE_QUAL, + TCF_MASK_QUAL = TCF_MASK_CVR_DIFF | TCF_MASK_PTR_QUAL_DIFF | TCF_INCOMPATIBLE_QUAL, } typecmpflag_t; typedef struct { diff --git a/test/err/bug2286-param-qualifier.c b/test/err/bug2286-param-qualifier.c new file mode 100644 index 000000000..a014d0a0c --- /dev/null +++ b/test/err/bug2286-param-qualifier.c @@ -0,0 +1,4 @@ +/* Bug #2286 - Qualifiers of pointees of function parameters ignored for type compatibility check */ + +void woo(int* p); +void woo(const int* p); /* WRONG: Should be an error */ From 98ffc031d16efe00b4338e79f903382aa54af957 Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 9 Dec 2023 14:35:00 +0800 Subject: [PATCH 028/707] Fixed an iteration bug in type composition. --- src/cc65/expr.c | 3 ++- src/cc65/typeconv.c | 7 ------- test/err/bug2285-composite-type.c | 5 +++++ 3 files changed, 7 insertions(+), 8 deletions(-) create mode 100644 test/err/bug2285-composite-type.c diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 54984230c..a87335f42 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -4102,9 +4102,10 @@ static void hieQuest (ExprDesc* Expr) /* Avoid further errors */ ResultType = NewPointerTo (type_void); } else { - /* Result has the composite type */ + /* Result has the properly qualified composite type */ ResultType = TypeDup (Expr2.Type); TypeComposition (ResultType, Expr3.Type); + ResultType[1].C |= GetQualifier (Indirect (Expr3.Type)); } } } else if (IsClassPtr (Expr2.Type) && Expr3IsNULL) { diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index e5b054148..e5b6749d6 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -485,13 +485,6 @@ void TypeComposition (Type* lhs, const Type* rhs) } else if (RightCount != UNSPECIFIED) { SetElementCount (lhs, RightCount); } - } else { - /* Combine the qualifiers */ - if (IsClassPtr (lhs)) { - ++lhs; - ++rhs; - lhs->C |= GetQualifier (rhs); - } } /* Next type string element */ diff --git a/test/err/bug2285-composite-type.c b/test/err/bug2285-composite-type.c new file mode 100644 index 000000000..18a7b80a5 --- /dev/null +++ b/test/err/bug2285-composite-type.c @@ -0,0 +1,5 @@ +/* Bug #2285 - Regression in type composition */ + +void foo(); /* OK */ +void foo(int (*)(int)); /* OK */ +void foo(int (*)(long)); /* WRONG: Should be an error */ From 87f8893886570364ce18776490f470232860772e Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 9 Dec 2023 17:33:46 +0800 Subject: [PATCH 029/707] Avoided "Variable 'XXX' is defined but never used" error message resulted from an earlier error. --- src/cc65/symtab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index a4ca9e23d..86a92a019 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -178,7 +178,7 @@ static void CheckSymTable (SymTable* Tab) if (IS_Get (&WarnUnusedFunc)) { Warning ("Function '%s' is defined but never used", Entry->Name); } - } else { + } else if (!IsAnonName (Entry->Name)) { if (IS_Get (&WarnUnusedVar)) { Warning ("Variable '%s' is defined but never used", Entry->Name); } From d8a722b63826ea4a1df2bb7a7f4e1197f7707117 Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 9 Dec 2023 17:34:01 +0800 Subject: [PATCH 030/707] Improved diagnostics on multiple definition of struct/union types. --- src/cc65/declare.c | 10 ---------- src/cc65/symtab.c | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index b6620785f..96e1f1074 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1220,11 +1220,6 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { Flags |= SC_FICTITIOUS; } - /* Empty union is not supported now */ - if (UnionSize == 0) { - Error ("Empty union type '%s' is not supported", Name); - } - /* Make a real entry from the forward decl and return it */ return AddStructSym (Name, SC_UNION | SC_DEF | Flags, UnionSize, FieldTab, DSFlags); } @@ -1471,11 +1466,6 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { Flags |= SC_FICTITIOUS; } - /* Empty struct is not supported now */ - if (StructSize == 0) { - Error ("Empty struct type '%s' is not supported", Name); - } - /* Make a real entry from the forward decl and return it */ return AddStructSym (Name, SC_STRUCT | SC_DEF | Flags, StructSize, FieldTab, DSFlags); } diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 86a92a019..1b5c1e0b5 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -919,14 +919,8 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl /* SCType must be struct or union */ PRECONDITION (SCType == SC_STRUCT || SCType == SC_UNION); - if ((Flags & SC_FICTITIOUS) == 0) { - /* Do we have an entry with this name already? */ - TagEntry = FindSymInTable (CurTagTab, Name, HashStr (Name)); - } else { - /* Add a fictitious symbol in the fail-safe table */ - TagEntry = 0; - CurTagTab = FailSafeTab; - } + /* Do we have an entry with this name already? */ + TagEntry = FindSymInTable (CurTagTab, Name, HashStr (Name)); if (TagEntry) { @@ -954,6 +948,15 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl if (DSFlags != 0) { *DSFlags |= DS_NEW_TYPE_DEF; } + + if ((Flags & SC_FICTITIOUS) == SC_FICTITIOUS) { + /* Add a fictitious symbol in the fail-safe table */ + TagEntry = 0; + } else if (Size == 0) { + /* Empty struct is not supported now */ + Error ("Empty %s type '%s' is not supported", SCType == SC_STRUCT ? "struct" : "union", Name); + TagEntry = 0; + } } } From d8e61552be196bee3bb7fca6d23d92b1a3ffedc4 Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 9 Dec 2023 18:04:29 +0800 Subject: [PATCH 031/707] Removed outdated testcases no longer in the directory from test/misc/Makefile. --- test/misc/Makefile | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/test/misc/Makefile b/test/misc/Makefile index c708b160b..811f7f462 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -58,24 +58,6 @@ $(ISEQUAL): ../isequal.c | $(WORKDIR) define PRG_template -# should compile, but gives an error -$(WORKDIR)/int-static-1888.$1.$2.prg: int-static-1888.c | $(WORKDIR) - @echo "FIXME: " $$@ "currently does not compile." - $(if $(QUIET),echo misc/int-static-1888.$1.$2.prg) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - -# should compile, but gives an error -$(WORKDIR)/bug760.$1.$2.prg: bug760.c | $(WORKDIR) - @echo "FIXME: " $$@ "currently does not compile." - $(if $(QUIET),echo misc/bug760.$1.$2.prg) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - -# should compile, but gives an error -$(WORKDIR)/bug1437.$1.$2.prg: bug1437.c | $(WORKDIR) - @echo "FIXME: " $$@ "currently does not compile." - $(if $(QUIET),echo misc/bug1437.$1.$2.prg) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - # should compile, but gives an error $(WORKDIR)/bug1209-ind-goto-rev.$1.$2.prg: bug1209-ind-goto-rev.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." @@ -106,18 +88,6 @@ $(WORKDIR)/pptest2.$1.$2.prg: pptest2.c | $(WORKDIR) $(if $(QUIET),echo misc/pptest2.$1.$2.prg) $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) -# should compile, but gives an error -$(WORKDIR)/bug1263.$1.$2.prg: bug1263.c | $(WORKDIR) - @echo "FIXME: " $$@ "currently does not compile." - $(if $(QUIET),echo misc/bug1263.$1.$2.prg) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - -# should compile, but gives an error -$(WORKDIR)/bug1357.$1.$2.prg: bug1357.c | $(WORKDIR) - @echo "FIXME: " $$@ "currently does not compile." - $(if $(QUIET),echo misc/bug1357.$1.$2.prg) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) - # should compile, but compiler exits with internal error $(WORKDIR)/bug1211-ice-move-refs-2.$1.$2.prg: bug1211-ice-move-refs-2.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." From 2a2cc6cad69dd83ebd02b314f253119461ec7cfb Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sat, 9 Dec 2023 16:43:23 +0100 Subject: [PATCH 032/707] Fix bug introduced in #2260 bne should have applied to A, not X, but adding a cmp #$00 before makes the change less optimized than the existing. --- src/cc65/codegen.c | 8 +------- test/val/sub3.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index db487ca40..c2bdfcd63 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -3697,13 +3697,7 @@ void g_dec (unsigned flags, unsigned long val) } else { /* Inline the code */ if (val < 0x300) { - if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0 && val == 1) { - unsigned L = GetLocalLabel(); - AddCodeLine ("bne %s", LocalLabelName (L)); - AddCodeLine ("dex"); - g_defcodelabel (L); - AddCodeLine ("dea"); - } else if ((val & 0xFF) != 0) { + if ((val & 0xFF) != 0) { unsigned L = GetLocalLabel(); AddCodeLine ("sec"); AddCodeLine ("sbc #$%02X", (unsigned char) val); diff --git a/test/val/sub3.c b/test/val/sub3.c index 2a3646f9a..dd050224e 100644 --- a/test/val/sub3.c +++ b/test/val/sub3.c @@ -168,6 +168,31 @@ void post_dec_assign_test(void) failures++; } +void dex_tests(void) { + static unsigned int a, b; + + a = 257; + b = a - 1; + if (b != 256) { + printf("fail 257 => 256\n"); + failures++; + } + + a = 256; + b = a - 1; + if (b != 255) { + printf("fail 256 => 255\n"); + failures++; + } + + a = 255; + b = a - 1; + if (b != 254) { + printf("fail 255 => 254\n"); + failures++; + } +} + int main(void) { int0 = 5; @@ -186,6 +211,8 @@ int main(void) int1 = 5; post_dec_assign_test(); + dex_tests(); + printf("failures: %d\n",failures); return failures; From b66682a05b01ed0c1bae4e51758e26b4257ab6db Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 10 Dec 2023 00:47:10 +0800 Subject: [PATCH 033/707] Fixed wrapped call when the function to wrap has already got defined before it is wrapped with the pragma. --- doc/cc65.sgml | 9 +++++++-- src/cc65/declare.c | 22 ---------------------- src/cc65/expr.c | 14 +++++--------- src/cc65/funcdesc.c | 2 -- src/cc65/funcdesc.h | 2 -- src/cc65/symentry.h | 2 ++ src/cc65/symtab.c | 19 +++++++++++++------ test/val/trampoline.c | 14 +++++++------- 8 files changed, 34 insertions(+), 50 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 37e3e493d..efe48b61b 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1613,13 +1613,13 @@ parameter with the function will be used to determine the number from the bank attribute defined in the linker config, see . Note that @@ -1629,6 +1629,11 @@ parameter with the WrappedCall = WrappedCall; - F->WrappedCallData = WrappedCallData; - } - /* Return the function descriptor */ return F; } @@ -2099,7 +2088,6 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) /* Function declarator */ FuncDesc* F; - SymEntry* PrevEntry; /* Parse the function declarator */ F = ParseFuncDecl (); @@ -2110,16 +2098,6 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) Qualifiers &= ~T_QUAL_FASTCALL; } - /* Was there a previous entry? If so, copy WrappedCall info from it */ - PrevEntry = FindGlobalSym (D->Ident); - if (PrevEntry && PrevEntry->Flags & SC_FUNC) { - FuncDesc* D = GetFuncDesc (PrevEntry->Type); - if (D->WrappedCall && !F->WrappedCall) { - F->WrappedCall = D->WrappedCall; - F->WrappedCallData = D->WrappedCallData; - } - } - /* Add the function type. Be sure to bounds check the type buffer */ NeedTypeSpace (D, 1); D->Type[D->Index].C = T_FUNC | Qualifiers; diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 963ea8bd6..af39a79f9 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1057,11 +1057,6 @@ static void FunctionCall (ExprDesc* Expr) /* Special handling for function pointers */ if (IsFuncPtr) { - - if (Func->WrappedCall) { - Warning ("Calling a wrapped function via a pointer, wrapped-call will not be used"); - } - /* If the function is not a fastcall function, load the pointer to ** the function into the primary. */ @@ -1110,18 +1105,18 @@ static void FunctionCall (ExprDesc* Expr) } else { /* Normal function */ - if (Func->WrappedCall) { + if (Expr->Sym && Expr->Sym->V.F.WrappedCall) { char tmp[64]; StrBuf S = AUTO_STRBUF_INITIALIZER; - if (Func->WrappedCallData == WRAPPED_CALL_USE_BANK) { + if (Expr->Sym->V.F.WrappedCallData == WRAPPED_CALL_USE_BANK) { /* Store the bank attribute in tmp4 */ SB_AppendStr (&S, "ldy #<.bank(_"); SB_AppendStr (&S, (const char*) Expr->Name); SB_AppendChar (&S, ')'); } else { /* Store the WrappedCall data in tmp4 */ - sprintf(tmp, "ldy #%u", Func->WrappedCallData); + sprintf(tmp, "ldy #%u", Expr->Sym->V.F.WrappedCallData); SB_AppendStr (&S, tmp); } g_asmcode (&S); @@ -1154,7 +1149,7 @@ static void FunctionCall (ExprDesc* Expr) SB_Done (&S); - g_call (CG_CallFlags (Expr->Type), Func->WrappedCall->Name, ArgSize); + g_call (CG_CallFlags (Expr->Type), Expr->Sym->V.F.WrappedCall->Name, ArgSize); } else { g_call (CG_CallFlags (Expr->Type), (const char*) Expr->Name, ArgSize); } @@ -1328,6 +1323,7 @@ static void Primary (ExprDesc* E) E->Type = type_int; } + E->Sym = Sym; } break; diff --git a/src/cc65/funcdesc.c b/src/cc65/funcdesc.c index 2291b35ee..de881167d 100644 --- a/src/cc65/funcdesc.c +++ b/src/cc65/funcdesc.c @@ -61,8 +61,6 @@ FuncDesc* NewFuncDesc (void) F->ParamSize = 0; F->LastParam = 0; F->FuncDef = 0; - F->WrappedCall = 0; - F->WrappedCallData = 0; /* Return the new struct */ return F; diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index e065c7602..8d21d3080 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -70,8 +70,6 @@ struct FuncDesc { unsigned ParamSize; /* Size of the parameters */ struct SymEntry* LastParam; /* Pointer to last parameter */ struct FuncDesc* FuncDef; /* Descriptor used in definition */ - struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ - unsigned int WrappedCallData; /* The WrappedCall's user data */ }; diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 715c036d6..639221625 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -159,6 +159,8 @@ struct SymEntry { struct { struct SegContext* Seg; /* SegContext for this function */ struct LiteralPool* LitPool; /* Literal pool for this function */ + struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */ + unsigned int WrappedCallData; /* The WrappedCall's user data */ } F; /* Label name for static symbols */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 1b5c1e0b5..3018c910d 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -61,6 +61,7 @@ #include "symentry.h" #include "typecmp.h" #include "typeconv.h" +#include "wrappedcall.h" #include "symtab.h" @@ -1407,24 +1408,30 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) } if (Entry == 0) { - /* Create a new entry */ Entry = NewSymEntry (Name, Flags); /* Set the symbol attributes */ Entry->Type = TypeDup (T); - /* If this is a function, clear additional fields */ - if (IsTypeFunc (T)) { - Entry->V.F.Seg = 0; - } - /* Add the assembler name of the symbol */ SymSetAsmName (Entry); /* Add the entry to the symbol table */ AddSymEntry (Tab, Entry); + } + /* If this is a function, do we wrap calls to it? */ + if (IsTypeFunc (Entry->Type)) { + SymEntry* WrappedCall; + unsigned int WrappedCallData; + + /* Always use the latest wrapper data for it */ + GetWrappedCall ((void**)&WrappedCall, &WrappedCallData); + if (WrappedCall) { + Entry->V.F.WrappedCall = WrappedCall; + Entry->V.F.WrappedCallData = WrappedCallData; + } } /* Add an alias of the global symbol to the local symbol table */ diff --git a/test/val/trampoline.c b/test/val/trampoline.c index 8f1e1547c..d3e73b47d 100644 --- a/test/val/trampoline.c +++ b/test/val/trampoline.c @@ -22,23 +22,23 @@ void func3() { } -#pragma wrapped-call(push, trampoline_inc, 0) - void func2() { func3(); } +#pragma wrapped-call(push, trampoline_inc, 0) + +void func2(void); + #pragma wrapped-call(push, trampoline_set, 4) -void func1(void); - -#pragma wrapped-call(pop) -#pragma wrapped-call(pop) - void func1(void) { func2(); } +#pragma wrapped-call(pop) +#pragma wrapped-call(pop) + int main(void) { flag = 0; From 79b4690077cb41ff53bf48a126f48a53c8af1600 Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 10 Dec 2023 15:43:24 +0800 Subject: [PATCH 034/707] Fixed missing diagnostics on empty enum/struct/union declareations without tag names. Improved error recovery with local declarations and _Static_assert. --- src/cc65/compile.c | 84 +++-- src/cc65/declare.c | 436 ++++++++++------------- src/cc65/declare.h | 44 +-- src/cc65/expr.c | 2 +- src/cc65/locals.c | 54 ++- src/cc65/scanner.c | 157 ++++++++ src/cc65/scanner.h | 29 ++ src/cc65/staticassert.c | 61 ++-- test/ref/bug1889-missing-identifier.cref | 4 +- 9 files changed, 514 insertions(+), 357 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index bef55e375..5101eccd4 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -79,7 +79,6 @@ static void Parse (void) /* Top level parser routine. */ { - int comma; SymEntry* Sym; FuncDesc* FuncDef = 0; @@ -94,8 +93,8 @@ static void Parse (void) while (CurTok.Tok != TOK_CEOF) { DeclSpec Spec; + int Comma; int NeedClean = 0; - unsigned PrevErrorCount = ErrorCount; /* Check for empty statements */ if (CurTok.Tok == TOK_SEMI) { @@ -119,7 +118,7 @@ static void Parse (void) continue; } - /* Read variable defs and functions */ + /* Read the declaration specifier */ ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT, SC_EXTERN | SC_STATIC); /* Don't accept illegal storage classes */ @@ -139,17 +138,19 @@ static void Parse (void) } /* Read declarations for this type */ - Sym = 0; - comma = 0; + Comma = 0; while (1) { Declarator Decl; + Sym = 0; + /* Read the next declaration */ - NeedClean = ParseDecl (&Spec, &Decl, DM_NEED_IDENT); - if (Decl.Ident[0] == '\0') { - Sym = 0; - goto NextDecl; + NeedClean = ParseDecl (&Spec, &Decl, DM_IDENT_OR_EMPTY); + + /* Bail out if there are errors */ + if (NeedClean <= 0) { + break; } /* Check if we must reserve storage for the variable. We do this, @@ -191,10 +192,6 @@ static void Parse (void) FuncDef->Flags = (FuncDef->Flags & ~FD_EMPTY) | FD_VOID_PARAM; } } else { - if (CurTok.Tok != TOK_COMMA && CurTok.Tok != TOK_SEMI) { - Error ("Expected ',' or ';' after top level declarator"); - } - /* Just a declaration */ Decl.StorageClass |= SC_DECL; } @@ -317,50 +314,49 @@ static void Parse (void) } -NextDecl: /* Check for end of declaration list */ - if (CurTok.Tok == TOK_COMMA) { - NextToken (); - comma = 1; - } else { + if (CurTok.Tok != TOK_COMMA) { break; } + Comma = 1; + Spec.Flags |= DS_NO_EMPTY_DECL; + NextToken (); } /* Finish the declaration */ - if (Sym) { - /* Function definition? */ - if (IsTypeFunc (Sym->Type) && CurTok.Tok == TOK_LCURLY) { - if (IsTypeFunc (Spec.Type) && TypeCmp (Sym->Type, Spec.Type).C >= TC_EQUAL) { - /* ISO C: The type category in a function definition cannot be - ** inherited from a typedef. - */ - Error ("Function cannot be defined with a typedef"); - } else if (comma) { - /* ISO C: A function definition cannot shall its return type - ** specifier with other declarators. - */ - Error ("';' expected after top level declarator"); - } + if (Sym && IsTypeFunc (Sym->Type) && CurTok.Tok == TOK_LCURLY) { + /* A function definition is not terminated with a semicolon */ + if (IsTypeFunc (Spec.Type) && TypeCmp (Sym->Type, Spec.Type).C >= TC_EQUAL) { + /* ISO C: The type category in a function definition cannot be + ** inherited from a typedef. + */ + Error ("Function cannot be defined with a typedef"); + } else if (Comma) { + /* ISO C: A function definition cannot shall its return type + ** specifier with other declarators. + */ + Error ("';' expected after top level declarator"); + } - /* Parse the function body anyways */ - NeedClean = 0; - NewFunc (Sym, FuncDef); + /* Parse the function body anyways */ + NeedClean = 0; + NewFunc (Sym, FuncDef); - /* Make sure we aren't omitting any work */ - CheckDeferredOpAllDone (); + /* Make sure we aren't omitting any work */ + CheckDeferredOpAllDone (); + } else if (NeedClean > 0) { + /* Must be followed by a semicolon */ + if (CurTok.Tok != TOK_SEMI) { + Error ("',' or ';' expected after top level declarator"); + NeedClean = -1; } else { - /* Must be followed by a semicolon */ - if (ConsumeSemi ()) { - NeedClean = 0; - } else { - NeedClean = -1; - } + NextToken (); + NeedClean = 0; } } /* Try some smart error recovery */ - if (PrevErrorCount != ErrorCount && NeedClean < 0) { + if (NeedClean < 0) { SmartErrorSkip (1); } } diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 96e1f1074..efca09d7f 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -72,7 +72,7 @@ -static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSpecified); +static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags); /* Parse a type specifier */ @@ -83,125 +83,6 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp -static void OpenBrace (Collection* C, token_t Tok) -/* Consume an opening parenthesis/bracket/curly brace and remember that */ -{ - switch (Tok) { - case TOK_LPAREN: Tok = TOK_RPAREN; break; - case TOK_LBRACK: Tok = TOK_RBRACK; break; - case TOK_LCURLY: Tok = TOK_RCURLY; break; - default: Internal ("Unexpected opening token: %02X", (unsigned)Tok); - } - CollAppend (C, (void*)Tok); - NextToken (); -} - - - -static int CloseBrace (Collection* C, token_t Tok) -/* Consume a closing parenthesis/bracket/curly brace if it is matched with an -** opening one and return 0, or bail out and return -1 if it is not matched. -*/ -{ - if (CollCount (C) > 0) { - token_t LastTok = (token_t)CollLast (C); - if (LastTok == Tok) { - CollPop (C); - NextToken (); - return 0; - } - } - - return -1; -} - - - -int SmartErrorSkip (int WholeDecl) -/* Try some smart error recovery. -** -** - If WholeDecl is 0: -** Skip tokens until a comma or closing curly brace that is not enclosed in -** an open parenthesis/bracket/curly brace, or until a semicolon, EOF or -** unpaired right parenthesis/bracket/curly brace is reached. -** -** - If WholeDecl is non-0: -** Skip tokens until a closing curly brace that is not enclosed in an open -** parenthesis/bracket/curly brace, or until a semicolon or EOF is reached. -** -** Return 0 if this exits as soon as it reaches an EOF. Return 0 as well if -** this exits with no open parentheses/brackets/curly braces. Otherwise, return -** -1. -*/ -{ - Collection C = AUTO_COLLECTION_INITIALIZER; - int Res = 0; - - /* Some fix point tokens that are used for error recovery */ - static const token_t TokenList[] = { TOK_COMMA, TOK_SEMI, - TOK_LPAREN, TOK_RPAREN, TOK_LBRACK, TOK_RBRACK, TOK_LCURLY, TOK_RCURLY }; - - while (CurTok.Tok != TOK_CEOF) { - SkipTokens (TokenList, sizeof (TokenList) / sizeof (TokenList[0])); - - switch (CurTok.Tok) { - case TOK_LPAREN: - case TOK_LBRACK: - case TOK_LCURLY: - OpenBrace (&C, CurTok.Tok); - break; - - case TOK_RPAREN: - case TOK_RBRACK: - if (CloseBrace (&C, CurTok.Tok) < 0) { - if (!WholeDecl) { - Res = -1; - goto ExitPoint; - } - NextToken (); - } - break; - - case TOK_RCURLY: - if (CloseBrace (&C, CurTok.Tok) < 0) { - if (!WholeDecl) { - Res = -1; - goto ExitPoint; - } - NextToken (); - } else if (CollCount (&C) == 0) { - goto ExitPoint; - } - break; - - case TOK_COMMA: - if (CollCount (&C) == 0 && !WholeDecl) { - goto ExitPoint; - } - NextToken (); - break; - - case TOK_SEMI: - if (CollCount (&C) != 0) { - Res = -1; - } - goto ExitPoint; - - case TOK_CEOF: - goto ExitPoint; - - default: - Internal ("Unexpected token: %02X", (unsigned)CurTok.Tok); - } - } - -ExitPoint: - DoneCollection (&C); - return Res; -} - - - static unsigned ParseOneStorageClass (void) /* Parse and return a storage class specifier */ { @@ -451,20 +332,36 @@ static void OptionalInt (void) -static void OptionalSigned (int* SignednessSpecified) +static void OptionalSigned (DeclSpec* Spec) /* Eat an optional "signed" token */ { if (CurTok.Tok == TOK_SIGNED) { /* Skip it */ NextToken (); - if (SignednessSpecified != NULL) { - *SignednessSpecified = 1; + if (Spec != NULL) { + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; } } } +static void UseDefaultType (DeclSpec* Spec, typespec_t TSFlags) +/* Use the default type for the type specifier */ +{ + if ((TSFlags & TS_MASK_DEFAULT_TYPE) == TS_DEFAULT_TYPE_NONE) { + Spec->Flags |= DS_NO_TYPE; + Spec->Type[0].C = T_INT; + Spec->Type[1].C = T_END; + } else { + Spec->Flags |= DS_DEF_TYPE; + Spec->Type[0].C = T_INT; + Spec->Type[1].C = T_END; + } +} + + + static void InitDeclSpec (DeclSpec* Spec) /* Initialize the DeclSpec struct for use */ { @@ -1080,7 +977,6 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) /* Get the type of the entry */ DeclSpec Spec; - int SignednessSpecified = 0; int NeedClean = 0; /* Check for a _Static_assert */ @@ -1090,7 +986,17 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) } InitDeclSpec (&Spec); - ParseTypeSpec (&Spec, TS_DEFAULT_TYPE_NONE, &SignednessSpecified); + ParseTypeSpec (&Spec, TS_DEFAULT_TYPE_NONE); + + /* Check if this is only a type declaration */ + if (CurTok.Tok == TOK_SEMI && (Spec.Flags & DS_EXTRA_TYPE) == 0) { + CheckEmptyDecl (&Spec); + NextToken (); + continue; + } + + /* Allow anonymous bit-fields */ + Spec.Flags |= DS_ALLOW_BITFIELD; /* Read fields with this type */ while (1) { @@ -1098,7 +1004,12 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) Declarator Decl; /* Get type and name of the struct field */ - NeedClean = ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT); + NeedClean = ParseDecl (&Spec, &Decl, DM_IDENT_OR_EMPTY); + + /* Bail out if there are errors */ + if (NeedClean <= 0) { + break; + } /* Check for a bit-field declaration */ FieldWidth = ParseFieldWidth (&Decl); @@ -1123,9 +1034,7 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) Decl.Type[0].C &= ~T_QUAL_CVR; } } else { - /* A non bit-field without a name is legal but useless */ - Warning ("Declaration does not declare anything"); - + /* Invalid member */ goto NextMember; } } else if (FieldWidth > 0) { @@ -1160,7 +1069,7 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) ** bit-field. */ AddBitField (Decl.Ident, Decl.Type, 0, 0, FieldWidth, - SignednessSpecified); + (Spec.Flags & DS_EXPLICIT_SIGNEDNESS) != 0); } else if (Decl.Ident[0] != '\0') { /* Add the new field to the table */ Field = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); @@ -1189,17 +1098,22 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) } } -NextMember: if (CurTok.Tok != TOK_COMMA) { +NextMember: + /* Check for end of declaration list */ + if (CurTok.Tok != TOK_COMMA) { break; } + Spec.Flags |= DS_NO_EMPTY_DECL; NextToken (); } - /* Must be followed by a semicolon */ - if (NeedClean >= 0 && ConsumeSemi ()) { - NeedClean = 0; - } else { - NeedClean = -1; + if (NeedClean > 0) { + /* Must be followed by a semicolon */ + if (ConsumeSemi ()) { + NeedClean = 0; + } else { + NeedClean = -1; + } } /* Try some smart error recovery */ @@ -1265,7 +1179,6 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) /* Get the type of the entry */ DeclSpec Spec; - int SignednessSpecified = 0; int NeedClean = 0; /* Check for a _Static_assert */ @@ -1275,7 +1188,17 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) } InitDeclSpec (&Spec); - ParseTypeSpec (&Spec, TS_DEFAULT_TYPE_NONE, &SignednessSpecified); + ParseTypeSpec (&Spec, TS_DEFAULT_TYPE_NONE); + + /* Check if this is only a type declaration */ + if (CurTok.Tok == TOK_SEMI && (Spec.Flags & DS_EXTRA_TYPE) == 0) { + CheckEmptyDecl (&Spec); + NextToken (); + continue; + } + + /* Allow anonymous bit-fields */ + Spec.Flags |= DS_ALLOW_BITFIELD; /* Read fields with this type */ while (1) { @@ -1291,7 +1214,12 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) } /* Get type and name of the struct field */ - NeedClean = ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT); + NeedClean = ParseDecl (&Spec, &Decl, DM_IDENT_OR_EMPTY); + + /* Bail out if there are errors */ + if (NeedClean <= 0) { + break; + } /* Check for a bit-field declaration */ FieldWidth = ParseFieldWidth (&Decl); @@ -1335,9 +1263,7 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) Decl.Type[0].C &= ~T_QUAL_CVR; } } else { - /* A non bit-field without a name is legal but useless */ - Warning ("Declaration does not declare anything"); - + /* Invalid member */ goto NextMember; } } else if (FieldWidth > 0) { @@ -1387,8 +1313,8 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) ** bit-field as a char type in expressions. */ CHECK (BitOffs < CHAR_BITS); - AddBitField (Decl.Ident, Decl.Type, StructSize, BitOffs, - FieldWidth, SignednessSpecified); + AddBitField (Decl.Ident, Decl.Type, StructSize, BitOffs, FieldWidth, + (Spec.Flags & DS_EXPLICIT_SIGNEDNESS) != 0); BitOffs += FieldWidth; CHECK (BitOffs <= CHAR_BITS * SizeOf (Decl.Type)); /* Add any full bytes to the struct size */ @@ -1427,17 +1353,22 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) } } -NextMember: if (CurTok.Tok != TOK_COMMA) { +NextMember: + /* Check for end of declaration list */ + if (CurTok.Tok != TOK_COMMA) { break; } + Spec.Flags |= DS_NO_EMPTY_DECL; NextToken (); } - /* Must be followed by a semicolon */ - if (NeedClean >= 0 && ConsumeSemi ()) { - NeedClean = 0; - } else { - NeedClean = -1; + if (NeedClean > 0) { + /* Must be followed by a semicolon */ + if (ConsumeSemi ()) { + NeedClean = 0; + } else { + NeedClean = -1; + } } /* Try some smart error recovery */ @@ -1472,7 +1403,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { -static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSpecified) +static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags) /* Parse a type specifier. Store whether one of "signed" or "unsigned" was ** specified, so bit-fields of unspecified signedness can be treated as ** unsigned; without special handling, it would be treated as signed. @@ -1482,10 +1413,6 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp SymEntry* TagEntry; TypeCode Qualifiers = T_QUAL_NONE; - if (SignednessSpecified != NULL) { - *SignednessSpecified = 0; - } - /* Assume we have an explicit type */ Spec->Flags &= ~DS_DEF_TYPE; @@ -1511,15 +1438,13 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp case TOK_LONG: NextToken (); if (CurTok.Tok == TOK_UNSIGNED) { - if (SignednessSpecified != NULL) { - *SignednessSpecified = 1; - } + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; NextToken (); OptionalInt (); Spec->Type[0].C = T_ULONG; Spec->Type[1].C = T_END; } else { - OptionalSigned (SignednessSpecified); + OptionalSigned (Spec); OptionalInt (); Spec->Type[0].C = T_LONG; Spec->Type[1].C = T_END; @@ -1529,15 +1454,13 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp case TOK_SHORT: NextToken (); if (CurTok.Tok == TOK_UNSIGNED) { - if (SignednessSpecified != NULL) { - *SignednessSpecified = 1; - } + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; NextToken (); OptionalInt (); Spec->Type[0].C = T_USHORT; Spec->Type[1].C = T_END; } else { - OptionalSigned (SignednessSpecified); + OptionalSigned (Spec); OptionalInt (); Spec->Type[0].C = T_SHORT; Spec->Type[1].C = T_END; @@ -1550,10 +1473,8 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp Spec->Type[1].C = T_END; break; - case TOK_SIGNED: - if (SignednessSpecified != NULL) { - *SignednessSpecified = 1; - } + case TOK_SIGNED: + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; NextToken (); switch (CurTok.Tok) { @@ -1589,9 +1510,7 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp break; case TOK_UNSIGNED: - if (SignednessSpecified != NULL) { - *SignednessSpecified = 1; - } + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; NextToken (); switch (CurTok.Tok) { @@ -1640,12 +1559,16 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp case TOK_UNION: NextToken (); - /* */ + /* Check for tag name */ if (CurTok.Tok == TOK_IDENT) { strcpy (Ident, CurTok.Ident); NextToken (); - } else { + } else if (CurTok.Tok == TOK_LCURLY) { AnonName (Ident, "union"); + } else { + Error ("Tag name identifier or '{' expected"); + UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); + break; } /* Remember we have an extra type decl */ Spec->Flags |= DS_EXTRA_TYPE; @@ -1659,12 +1582,16 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp case TOK_STRUCT: NextToken (); - /* */ + /* Check for tag name */ if (CurTok.Tok == TOK_IDENT) { strcpy (Ident, CurTok.Ident); NextToken (); - } else { + } else if (CurTok.Tok == TOK_LCURLY) { AnonName (Ident, "struct"); + } else { + Error ("Tag name identifier or '{' expected"); + UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); + break; } /* Remember we have an extra type decl */ Spec->Flags |= DS_EXTRA_TYPE; @@ -1678,15 +1605,16 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp case TOK_ENUM: NextToken (); - /* Named enum */ + /* Check for tag name */ if (CurTok.Tok == TOK_IDENT) { strcpy (Ident, CurTok.Ident); NextToken (); - } else { - if (CurTok.Tok != TOK_LCURLY) { - Error ("Identifier expected for enum tag name"); - } + } else if (CurTok.Tok == TOK_LCURLY) { AnonName (Ident, "enum"); + } else { + Error ("Tag name identifier or '{' expected"); + UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); + break; } /* Remember we have an extra type decl */ Spec->Flags |= DS_EXTRA_TYPE; @@ -1699,9 +1627,7 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp /* The signedness of enums is determined by the type, so say this is specified to avoid ** the int -> unsigned int handling for plain int bit-fields in AddBitField. */ - if (SignednessSpecified) { - *SignednessSpecified = 1; - } + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; break; case TOK_IDENT: @@ -1718,9 +1644,7 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp ** Unforunately, this will cause plain int bit-fields defined via typedefs ** to be treated as signed rather than unsigned. */ - if (SignednessSpecified) { - *SignednessSpecified = 1; - } + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; break; } else if ((TSFlags & TS_MASK_DEFAULT_TYPE) == TS_DEFAULT_TYPE_NONE) { /* Treat this identifier as an unknown type */ @@ -1742,15 +1666,7 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags, int* SignednessSp /* FALL THROUGH */ default: - if ((TSFlags & TS_MASK_DEFAULT_TYPE) == TS_DEFAULT_TYPE_NONE) { - Spec->Flags |= DS_NO_TYPE; - Spec->Type[0].C = T_INT; - Spec->Type[1].C = T_END; - } else { - Spec->Flags |= DS_DEF_TYPE; - Spec->Type[0].C = T_INT; - Spec->Type[1].C = T_END; - } + UseDefaultType (Spec, TSFlags); break; } @@ -1839,6 +1755,9 @@ static void ParseOldStyleParamList (FuncDesc* F) /* Read the declaration specifier */ ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE, SC_AUTO); + /* Paremeters must have identifiers as names */ + Spec.Flags |= DS_NO_EMPTY_DECL; + /* We accept only auto and register as storage class specifiers, but ** we ignore all this, since we use auto anyway. */ @@ -1859,7 +1778,7 @@ static void ParseOldStyleParamList (FuncDesc* F) Declarator Decl; /* Read the parameter */ - ParseDecl (&Spec, &Decl, DM_NEED_IDENT); + ParseDecl (&Spec, &Decl, DM_IDENT_OR_EMPTY); /* Warn about new local type declaration */ if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0) { @@ -2083,7 +2002,7 @@ static FuncDesc* ParseFuncDecl (void) -static declmode_t DirectDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode) +static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) /* Recursively process direct declarators. Build a type array in reverse order. */ { /* Read optional function or pointer qualifiers that modify the identifier @@ -2101,19 +2020,19 @@ static declmode_t DirectDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mo NextToken (); /* A pointer type cannot be used as an empty declaration */ - if (Mode == DM_ACCEPT_IDENT) { - Mode = DM_NEED_IDENT; + if (Mode == DM_IDENT_OR_EMPTY) { + Spec->Flags |= DS_NO_EMPTY_DECL; } /* Allow const, restrict, and volatile qualifiers */ Qualifiers |= OptionalQualifiers (Qualifiers, T_QUAL_CVR); /* Parse the type that the pointer points to */ - Mode = DirectDecl (Spec, D, Mode); + DirectDecl (Spec, D, Mode); /* Add the type */ AddTypeCodeToDeclarator (D, T_PTR | Qualifiers); - return Mode; + return; } if (CurTok.Tok == TOK_LPAREN) { @@ -2121,28 +2040,24 @@ static declmode_t DirectDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mo /* An empty declaration cannot contain parentheses where an identifier ** would show up if it were a non-empty declaration. */ - if (Mode == DM_ACCEPT_IDENT) { - Mode = DM_NEED_IDENT; + if (Mode == DM_IDENT_OR_EMPTY) { + Spec->Flags |= DS_NO_EMPTY_DECL; } - Mode = DirectDecl (Spec, D, Mode); + DirectDecl (Spec, D, Mode); ConsumeRParen (); } else if (CurTok.Tok == TOK_IDENT) { strcpy (D->Ident, CurTok.Ident); NextToken (); } else { D->Ident[0] = '\0'; - if (Mode == DM_NEED_IDENT) { + if ((Spec->Flags & DS_NO_EMPTY_DECL) != 0 && + CurTok.Tok != TOK_LBRACK && + ((Spec->Flags & DS_ALLOW_BITFIELD) == 0 || CurTok.Tok != TOK_COLON)) { Error ("Identifier expected"); } } while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN) { - /* An array or function type cannot be used as an empty declaration */ - if (Mode == DM_ACCEPT_IDENT && D->Ident[0] == '\0') { - Mode = DM_NEED_IDENT; - Error ("Identifier expected"); - } - if (CurTok.Tok == TOK_LPAREN) { /* Function declarator */ @@ -2181,6 +2096,18 @@ static declmode_t DirectDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mo /* Array declarator */ long Size = UNSPECIFIED; + /* An array type cannot be used as an empty declaration */ + if (Mode == DM_IDENT_OR_EMPTY) { + Spec->Flags |= DS_NO_EMPTY_DECL; + if (D->Ident[0] == '\0') { + if ((Spec->Flags & DS_DEF_TYPE) == 0) { + Error ("Identifier or ';' expected after declaration specifiers"); + } else { + Error ("Identifier expected"); + } + } + } + /* We cannot have any qualifiers for an array */ if (Qualifiers != T_QUAL_NONE) { Error ("Invalid qualifiers for array"); @@ -2228,8 +2155,6 @@ static declmode_t DirectDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mo if (Qualifiers & T_QUAL_CDECL) { Error ("Invalid '__cdecl__' qualifier"); } - - return Mode; } @@ -2248,7 +2173,7 @@ Type* ParseType (Type* T) /* Get a type without a default */ InitDeclSpec (&Spec); - ParseTypeSpec (&Spec, TS_DEFAULT_TYPE_NONE, NULL); + ParseTypeSpec (&Spec, TS_DEFAULT_TYPE_NONE); /* Parse additional declarators */ ParseDecl (&Spec, &Decl, DM_NO_IDENT); @@ -2262,14 +2187,23 @@ Type* ParseType (Type* T) -int ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode) +int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) /* Parse a variable, type or function declarator. Return -1 if this stops at -** an unpaired right parenthesis/bracket/curly brace. +** an unpaired right parenthesis/bracket/curly brace. Return 0 if this stops +** after consuming a semicolon or closing curly brace, or reaching an EOF. +** Return 1 otherwise. */ { /* Used to check if we have any errors during parsing this */ unsigned PrevErrorCount = ErrorCount; + /* If there is no explicit type specifier, an optional identifier becomes + ** required. + */ + if (Mode == DM_IDENT_OR_EMPTY && (Spec->Flags & DS_DEF_TYPE) != 0) { + Spec->Flags |= DS_NO_EMPTY_DECL; + } + /* Initialize the Declarator struct */ InitDeclarator (D); @@ -2283,6 +2217,11 @@ int ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode) /* Use the storage class from the declspec */ D->StorageClass = Spec->StorageClass; + /* If we have a function, add a special symbol type */ + if (IsTypeFunc (D->Type)) { + D->StorageClass |= SC_FUNC; + } + /* Do several fixes on qualifiers */ FixQualifiers (D->Type); @@ -2297,24 +2236,6 @@ int ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode) /* Parse attributes for this declarator */ ParseAttribute (D); - /* If we have a function, add a special storage class */ - if (IsTypeFunc (D->Type)) { - - D->StorageClass |= SC_FUNC; - - } else if (!IsTypeVoid (D->Type)) { - /* Check the size of the generated type */ - unsigned Size = SizeOf (D->Type); - - if (Size >= 0x10000) { - if (D->Ident[0] != '\0') { - Error ("Size of '%s' is invalid (0x%06X)", D->Ident, Size); - } else { - Error ("Invalid size in declaration (0x%06X)", Size); - } - } - } - /* Check a few pre-C99 things */ if (D->Ident[0] != '\0' && (Spec->Flags & DS_DEF_TYPE) != 0) { /* Check and warn about an implicit int return in the function */ @@ -2331,7 +2252,7 @@ int ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode) /* For anything that is not a function or typedef, check for an implicit ** int declaration. */ - if ((D->StorageClass & SC_FUNC) != SC_FUNC && + if (!IsTypeFunc (D->Type) && (D->StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { /* If the standard was not set explicitly to C89, print a warning ** for variables with implicit int type. @@ -2342,11 +2263,32 @@ int ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode) } } - if (PrevErrorCount != ErrorCount) { - if ((Spec->Flags & DS_DEF_TYPE) == 0 && Mode == DM_NEED_IDENT && D->Ident[0] == '\0') { - /* Make the declaration fictitious if is is not parsed correctly */ - D->StorageClass |= SC_FICTITIOUS; + /* Check the size of the declared type */ + if (IsObjectType (D->Type)) { + unsigned Size = SizeOf (D->Type); + if (Size >= 0x10000) { + if (D->Ident[0] != '\0') { + Error ("Size of '%s' is too large (0x%06X)", D->Ident, Size); + } else { + Error ("Size in declaration is too large (0x%06X)", Size); + } + } + } + + /* An empty declaration must be terminated with a semicolon */ + if (PrevErrorCount == ErrorCount && + Mode == DM_IDENT_OR_EMPTY && + D->Ident[0] == '\0' && + CurTok.Tok != TOK_SEMI && + ((Spec->Flags & DS_ALLOW_BITFIELD) == 0 || CurTok.Tok != TOK_COLON)) { + Error ("Identifier or ';' expected after declaration specifiers"); + } + + if (PrevErrorCount != ErrorCount) { + if ((Spec->Flags & DS_DEF_TYPE) == 0 && + (Spec->Flags & DS_NO_EMPTY_DECL) != 0 && + D->Ident[0] == '\0') { /* Use a fictitious name for the identifier if it is missing */ const char* Level = ""; @@ -2366,15 +2308,21 @@ int ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode) break; } AnonName (D->Ident, Level); + + /* Make the declarator fictitious */ + D->StorageClass |= SC_FICTITIOUS; } /* Try some smart error recovery */ if (CurTok.Tok != TOK_LCURLY || !IsTypeFunc (D->Type)) { - return SmartErrorSkip (0); + /* Skip to the end of the whole declaration if it is not part of a + ** parameter list or a type cast. + */ + return SmartErrorSkip (Mode == DM_IDENT_OR_EMPTY); } } - return 0; + return 1; } @@ -2389,7 +2337,7 @@ void ParseDeclSpec (DeclSpec* Spec, typespec_t TSFlags, unsigned DefStorage) Spec->Flags &= ~DS_DEF_STORAGE; /* Parse the type specifiers */ - ParseTypeSpec (Spec, TSFlags | TS_STORAGE_CLASS_SPEC | TS_FUNCTION_SPEC, NULL); + ParseTypeSpec (Spec, TSFlags | TS_STORAGE_CLASS_SPEC | TS_FUNCTION_SPEC); /* If no explicit storage class is given, use the default */ if (Spec->StorageClass == 0) { @@ -2407,6 +2355,10 @@ void CheckEmptyDecl (const DeclSpec* Spec) */ { if ((Spec->Flags & DS_EXTRA_TYPE) == 0) { - Warning ("Useless declaration"); + Warning ("Declaration does not declare anything"); + } else if (IsClassStruct (Spec->Type) && + !IsIncompleteESUType (Spec->Type) && + SymHasAnonName (GetESUTagSym (Spec->Type))) { + Warning ("Unnamed %s that defines no instances", GetBasicTypeName (Spec->Type)); } } diff --git a/src/cc65/declare.h b/src/cc65/declare.h index 1ce764f7a..36de40311 100644 --- a/src/cc65/declare.h +++ b/src/cc65/declare.h @@ -77,6 +77,11 @@ enum typespec_t { #define DS_NEW_TYPE_DECL 0x0010U /* New type declared */ #define DS_NEW_TYPE_DEF 0x0020U /* New type defined */ #define DS_NEW_TYPE (DS_NEW_TYPE_DECL | DS_NEW_TYPE_DEF) +#define DS_EXPLICIT_SIGNEDNESS 0x0040U /* Signedness specified */ +#define DS_NO_EMPTY_DECL 0x0100U /* Disallow empty declaration */ +#define DS_ALLOW_BITFIELD 0x0200U /* Allow anonymous bit-fields */ + + /* Result of ParseDeclSpec */ typedef struct DeclSpec DeclSpec; @@ -99,24 +104,22 @@ struct Declarator { }; /* Modes for ParseDecl: -** - DM_NEED_IDENT means: -** we *must* have a type and a variable identifer. +** - DM_IDENT_OR_EMPTY means: +** we *may* have an identifier, or none. If it is the latter case, +** the type specifier must be used for an empty declaration, +** or it is an error. ** - DM_NO_IDENT means: ** we must have a type but no variable identifer ** (if there is one, it's not read). -** - DM_ACCEPT_IDENT means: -** we *may* have an identifier, or none. If it is the latter case, -** the type must be used as an empty declaration, or it is an error. -** Note: this is used for struct/union members. -** - DM_IGNORE_IDENT means: +** Note: this is used for type names. +** - DM_ACCEPT_PARAM_IDENT means: ** we *may* have an identifier. If there is an identifier, ** it is read, but it is no error, if there is none. ** Note: this is used for function parameter type lists. */ typedef enum { - DM_NEED_IDENT, + DM_IDENT_OR_EMPTY, DM_NO_IDENT, - DM_ACCEPT_IDENT, DM_ACCEPT_PARAM_IDENT, } declmode_t; @@ -128,29 +131,14 @@ typedef enum { -int SmartErrorSkip (int WholeDecl); -/* Try some smart error recovery. -** -** - If WholeDecl is 0: -** Skip tokens until a comma or closing curly brace that is not enclosed in -** an open parenthesis/bracket/curly brace, or until a semicolon, EOF or -** unpaired right parenthesis/bracket/curly brace is reached. -** -** - If WholeDecl is non-0: -** Skip tokens until a closing curly brace that is not enclosed in an open -** parenthesis/bracket/curly brace, or until a semicolon or EOF is reached. -** -** Return 0 if this exits as soon as it reaches an EOF. Return 0 as well if -** this exits with no open parentheses/brackets/curly braces. Otherwise, return -** -1. -*/ - Type* ParseType (Type* Type); /* Parse a complete type specification */ -int ParseDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode); +int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode); /* Parse a variable, type or function declarator. Return -1 if this stops at -** an unpaired right parenthesis/bracket/curly brace. +** an unpaired right parenthesis/bracket/curly brace. Return 0 if this stops +** after consuming a semicolon or closing curly brace, or reaching an EOF. +** Return 1 otherwise. */ void ParseDeclSpec (DeclSpec* Spec, typespec_t TSFlags, unsigned DefStorage); diff --git a/src/cc65/expr.c b/src/cc65/expr.c index a87335f42..d672b032e 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1422,7 +1422,7 @@ static void Primary (ExprDesc* E) Declarator Decl; /* Parse one declaration */ - ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT); + ParseDecl (&Spec, &Decl, DM_IDENT_OR_EMPTY); if (CurTok.Tok == TOK_ASSIGN) { NextToken (); ParseInit (Decl.Type); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 381477faa..701dcb806 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -441,14 +441,15 @@ static void ParseStaticDecl (Declarator* Decl) -static void ParseOneDecl (const DeclSpec* Spec) +static int ParseOneDecl (DeclSpec* Spec) /* Parse one variable declarator. */ { - Declarator Decl; /* Declarator data structure */ + Declarator Decl; /* Declarator data structure */ + int NeedClean; /* Read the declarator */ - ParseDecl (Spec, &Decl, DM_NEED_IDENT); + NeedClean = ParseDecl (Spec, &Decl, DM_IDENT_OR_EMPTY); /* Check if there are any non-extern storage classes set for function ** declarations. Function can only be declared inside functions with the @@ -538,6 +539,8 @@ static void ParseOneDecl (const DeclSpec* Spec) /* Make sure we aren't missing some work */ CheckDeferredOpAllDone (); + + return NeedClean; } @@ -553,15 +556,8 @@ void DeclareLocals (void) /* Loop until we don't find any more variables */ while (1) { - - /* Check variable declarations. We need to distinguish between a - ** default int type and the end of variable declarations. So we - ** will do the following: If there is no explicit storage class - ** specifier *and* no explicit type given, *and* no type qualifiers - ** have been read, it is assumed that we have reached the end of - ** declarations. - */ DeclSpec Spec; + int NeedClean; /* Check for a _Static_assert */ if (CurTok.Tok == TOK_STATIC_ASSERT) { @@ -569,10 +565,18 @@ void DeclareLocals (void) continue; } + /* Read the declaration specifier */ ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT, SC_AUTO); - if ((Spec.Flags & DS_DEF_STORAGE) != 0 && /* No storage spec */ - (Spec.Flags & DS_DEF_TYPE) != 0 && /* No type given */ - GetQualifier (Spec.Type) == T_QUAL_NONE) { /* No type qualifier */ + + /* Check variable declarations. We need distinguish between a default + ** int type and the end of variable declarations. So we will do the + ** following: If there is no explicit storage class specifier *and* no + ** explicit type given, *and* no type qualifiers have been read, it is + ** assumed that we have reached the end of declarations. + */ + if ((Spec.Flags & DS_DEF_STORAGE) != 0 && /* No storage spec */ + (Spec.Flags & DS_DEF_TYPE) == DS_DEF_TYPE && /* No type given */ + GetQualifier (Spec.Type) == T_QUAL_NONE) { /* No type qualifier */ break; } @@ -587,8 +591,11 @@ void DeclareLocals (void) /* Parse a comma separated variable list */ while (1) { - /* Parse one declaration */ - ParseOneDecl (&Spec); + /* Parse one declarator */ + NeedClean = ParseOneDecl (&Spec); + if (NeedClean <= 0) { + break; + } /* Check if there is more */ if (CurTok.Tok == TOK_COMMA) { @@ -600,8 +607,19 @@ void DeclareLocals (void) } } - /* A semicolon must follow */ - ConsumeSemi (); + if (NeedClean > 0) { + /* Must be followed by a semicolon */ + if (ConsumeSemi ()) { + NeedClean = 0; + } else { + NeedClean = -1; + } + } + + /* Try some smart error recovery */ + if (NeedClean < 0) { + SmartErrorSkip (1); + } } /* Be sure to allocate any reserved space for locals */ diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 00dde9e83..6af9bc4be 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -1235,6 +1235,163 @@ void SkipTokens (const token_t* TokenList, unsigned TokenCount) +static void OpenBrace (Collection* C, token_t Tok) +/* Consume an opening parenthesis/bracket/curly brace and remember that */ +{ + switch (Tok) { + case TOK_LPAREN: Tok = TOK_RPAREN; break; + case TOK_LBRACK: Tok = TOK_RBRACK; break; + case TOK_LCURLY: Tok = TOK_RCURLY; break; + default: Internal ("Unexpected opening token: %02X", (unsigned)Tok); + } + CollAppend (C, (void*)Tok); + NextToken (); +} + + + +static void PopBrace (Collection* C) +/* Close the latest open parenthesis/bracket/curly brace */ +{ + if (CollCount (C) > 0) { + CollPop (C); + } +} + + + +static int CloseBrace (Collection* C, token_t Tok) +/* Consume a closing parenthesis/bracket/curly brace if it is matched with an +** opening one to close and return 0, or bail out and return -1 if it is not +** matched. +*/ +{ + if (CollCount (C) > 0) { + token_t LastTok = (token_t)CollLast (C); + if (LastTok == Tok) { + CollPop (C); + NextToken (); + return 0; + } + } + + return -1; +} + + + +int SmartErrorSkip (int TillEnd) +/* Try some smart error recovery. +** +** - If TillEnd == 0: +** Skip tokens until a comma or closing curly brace that is not enclosed in +** an open parenthesis/bracket/curly brace, or until a semicolon, EOF or +** unpaired right parenthesis/bracket/curly brace is reached. The closing +** curly brace is consumed in the former case. +** +** - If TillEnd != 0: +** Skip tokens until a right curly brace or semicolon is reached and consumed +** while there are no open parentheses/brackets/curly braces, or until an EOF +** is reached anytime. Any open parenthesis/bracket/curly brace is considered +** to be closed by consuming a right parenthesis/bracket/curly brace even if +** they didn't match. +** +** - Return -1: +** If this exits at a semicolon or unpaired right parenthesis/bracket/curly +** brace while there are still open parentheses/brackets/curly braces. +** +** - Return 0: +** If this exits as soon as it reaches an EOF; +** Or if this exits right after consuming a semicolon or right curly brace +** while there are no open parentheses/brackets/curly braces. +** +** - Return 1: +** If this exits at a non-EOF without consuming it. +*/ +{ + Collection C = AUTO_COLLECTION_INITIALIZER; + int Res = 0; + + /* Some fix point tokens that are used for error recovery */ + static const token_t TokenList[] = { TOK_COMMA, TOK_SEMI, + TOK_LPAREN, TOK_RPAREN, TOK_LBRACK, TOK_RBRACK, TOK_LCURLY, TOK_RCURLY }; + + while (CurTok.Tok != TOK_CEOF) { + SkipTokens (TokenList, sizeof (TokenList) / sizeof (TokenList[0])); + + switch (CurTok.Tok) { + case TOK_LPAREN: + case TOK_LBRACK: + case TOK_LCURLY: + OpenBrace (&C, CurTok.Tok); + break; + + case TOK_RPAREN: + case TOK_RBRACK: + if (CloseBrace (&C, CurTok.Tok) < 0) { + if (!TillEnd) { + Res = -1; + goto ExitPoint; + } + PopBrace (&C); + NextToken (); + } + break; + + case TOK_RCURLY: + if (CloseBrace (&C, CurTok.Tok) < 0) { + if (!TillEnd) { + Res = -1; + goto ExitPoint; + } + PopBrace (&C); + NextToken (); + } + if (CollCount (&C) == 0) { + /* We consider this as a terminator as well */ + Res = 0; + goto ExitPoint; + } + break; + + case TOK_COMMA: + if (CollCount (&C) == 0 && !TillEnd) { + Res = 1; + goto ExitPoint; + } + NextToken (); + break; + + case TOK_SEMI: + if (CollCount (&C) == 0) { + if (TillEnd) { + NextToken (); + Res = 0; + } else { + Res = 1; + } + goto ExitPoint; + } + NextToken (); + break; + + case TOK_CEOF: + /* We cannot consume this */ + Res = 0; + goto ExitPoint; + + default: + Internal ("Unexpected token: %02X", (unsigned)CurTok.Tok); + } + } + +ExitPoint: + DoneCollection (&C); + return Res; +} + + + int Consume (token_t Token, const char* ErrorMsg) /* Eat token if it is the next in the input stream, otherwise print an error ** message. Returns true if the token was found and false otherwise. diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index e6b788660..808b96c5e 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -310,6 +310,35 @@ void SkipTokens (const token_t* TokenList, unsigned TokenCount); ** This routine is used for error recovery. */ +int SmartErrorSkip (int TillEnd); +/* Try some smart error recovery. +** +** - If TillEnd == 0: +** Skip tokens until a comma or closing curly brace that is not enclosed in +** an open parenthesis/bracket/curly brace, or until a semicolon, EOF or +** unpaired right parenthesis/bracket/curly brace is reached. The closing +** curly brace is consumed in the former case. +** +** - If TillEnd != 0: +** Skip tokens until a right curly brace or semicolon is reached and consumed +** while there are no open parentheses/brackets/curly braces, or until an EOF +** is reached anytime. Any open parenthesis/bracket/curly brace is considered +** to be closed by consuming a right parenthesis/bracket/curly brace even if +** they didn't match. +** +** - Return -1: +** If this exits at a semicolon or unpaired right parenthesis/bracket/curly +** brace while there are still open parentheses/brackets/curly braces. +** +** - Return 0: +** If this exits as soon as it reaches an EOF; +** Or if this exits right after consuming a semicolon or right curly brace +** while there are no open parentheses/brackets/curly braces. +** +** - Return 1: +** If this exits at a non-EOF without consuming it. +*/ + int Consume (token_t Token, const char* ErrorMsg); /* Eat token if it is the next in the input stream, otherwise print an error ** message. Returns true if the token was found and false otherwise. diff --git a/src/cc65/staticassert.c b/src/cc65/staticassert.c index abb2c57ca..9df9af7da 100644 --- a/src/cc65/staticassert.c +++ b/src/cc65/staticassert.c @@ -45,7 +45,7 @@ -void ParseStaticAssert () +void ParseStaticAssert (void) { /* ** static_assert-declaration ::= @@ -53,20 +53,23 @@ void ParseStaticAssert () ** _Static_assert ( constant-expression , string-literal ) ; */ ExprDesc Expr; - int failed; + unsigned PrevErrorCount = ErrorCount; + int failed = 0; /* Skip the _Static_assert token itself */ CHECK (CurTok.Tok == TOK_STATIC_ASSERT); NextToken (); /* We expect an opening paren */ - if (!ConsumeLParen ()) { - return; + if (ConsumeLParen ()) { + /* Parse assertion condition */ + Expr = NoCodeConstAbsIntExpr (hie1); + failed = !Expr.IVal; } - /* Parse assertion condition */ - Expr = NoCodeConstAbsIntExpr (hie1); - failed = !Expr.IVal; + if (PrevErrorCount != ErrorCount) { + goto ExitPoint; + } /* If there is a comma, we also have an error message. The message is optional because we ** support the C2X syntax with only an expression. @@ -84,19 +87,16 @@ void ParseStaticAssert () /* String literal */ if (CurTok.Tok != TOK_SCONST) { Error ("String literal expected for static_assert message"); - return; - } + } else { + /* Issue an error including the message if the static_assert failed. */ + if (failed) { + Error ("static_assert failed '%s'", GetLiteralStr (CurTok.SVal)); + } - /* Issue an error including the message if the static_assert failed. */ - if (failed) { - Error ("static_assert failed '%s'", GetLiteralStr (CurTok.SVal)); - } - - /* Consume the string constant, now that we don't need it anymore. - ** This should never fail since we checked the token type above. - */ - if (!Consume (TOK_SCONST, "String literal expected")) { - return; + /* Consume the string constant, now that we don't need it anymore. + ** This should never fail since we checked the token type above. + */ + Consume (TOK_SCONST, "String literal expected"); } } else { /* No message. */ @@ -105,7 +105,24 @@ void ParseStaticAssert () } } - /* Closing paren and semi-colon needed */ - ConsumeRParen (); - ConsumeSemi (); + /* The assertion failure error is not a syntax error */ + if (failed) { + ++PrevErrorCount; + } + + if (PrevErrorCount == ErrorCount) { + /* Closing paren needed */ + ConsumeRParen (); + } + + if (PrevErrorCount == ErrorCount) { + /* Must be followed by a semicolon */ + ConsumeSemi (); + } + +ExitPoint: + /* Try some smart error recovery */ + if (PrevErrorCount != ErrorCount) { + SmartErrorSkip (1); + } } diff --git a/test/ref/bug1889-missing-identifier.cref b/test/ref/bug1889-missing-identifier.cref index 534c6aaba..2d92ff263 100644 --- a/test/ref/bug1889-missing-identifier.cref +++ b/test/ref/bug1889-missing-identifier.cref @@ -1,3 +1,3 @@ -bug1889-missing-identifier.c:3: Error: Identifier expected -bug1889-missing-identifier.c:3: Error: ';' expected +bug1889-missing-identifier.c:3: Error: Identifier or ';' expected after declaration specifiers +bug1889-missing-identifier.c:3: Warning: Implicit 'int' is an obsolete feature bug1889-missing-identifier.c:4: Error: Identifier expected From a1a060c29151c1571a93922575fabe2f582ff16c Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 10 Dec 2023 15:43:24 +0800 Subject: [PATCH 035/707] Declaration specifier flags cleanup. --- src/cc65/declare.c | 23 ++++++++++++----------- src/cc65/declare.h | 13 ++++++++----- src/cc65/expr.c | 2 +- src/cc65/locals.c | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index efca09d7f..62c2bdfa3 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -350,11 +350,11 @@ static void UseDefaultType (DeclSpec* Spec, typespec_t TSFlags) /* Use the default type for the type specifier */ { if ((TSFlags & TS_MASK_DEFAULT_TYPE) == TS_DEFAULT_TYPE_NONE) { - Spec->Flags |= DS_NO_TYPE; + Spec->Flags = (Spec->Flags & ~DS_TYPE_MASK) | DS_NONE; Spec->Type[0].C = T_INT; Spec->Type[1].C = T_END; } else { - Spec->Flags |= DS_DEF_TYPE; + Spec->Flags = (Spec->Flags & ~DS_TYPE_MASK) | DS_DEF_TYPE; Spec->Type[0].C = T_INT; Spec->Type[1].C = T_END; } @@ -1413,8 +1413,8 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags) SymEntry* TagEntry; TypeCode Qualifiers = T_QUAL_NONE; - /* Assume we have an explicit type */ - Spec->Flags &= ~DS_DEF_TYPE; + /* Assume we have an explicitly specified type */ + Spec->Flags = (Spec->Flags & ~DS_TYPE_MASK) | DS_EXPLICIT_TYPE; /* Read storage specifiers and/or type qualifiers if we have any */ OptionalSpecifiers (Spec, &Qualifiers, TSFlags); @@ -1767,7 +1767,7 @@ static void ParseOldStyleParamList (FuncDesc* F) } /* Type must be specified */ - if ((Spec.Flags & DS_NO_TYPE) != 0) { + if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) { Error ("Expected declaration specifiers"); break; } @@ -1860,7 +1860,7 @@ static void ParseAnsiParamList (FuncDesc* F) } /* Type must be specified */ - if ((Spec.Flags & DS_NO_TYPE) != 0) { + if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) { Error ("Type specifier missing"); } @@ -2100,7 +2100,7 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) if (Mode == DM_IDENT_OR_EMPTY) { Spec->Flags |= DS_NO_EMPTY_DECL; if (D->Ident[0] == '\0') { - if ((Spec->Flags & DS_DEF_TYPE) == 0) { + if ((Spec->Flags & DS_TYPE_MASK) != DS_NONE) { Error ("Identifier or ';' expected after declaration specifiers"); } else { Error ("Identifier expected"); @@ -2200,7 +2200,8 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) /* If there is no explicit type specifier, an optional identifier becomes ** required. */ - if (Mode == DM_IDENT_OR_EMPTY && (Spec->Flags & DS_DEF_TYPE) != 0) { + if (Mode == DM_IDENT_OR_EMPTY && + (Spec->Flags & DS_TYPE_MASK) == DS_DEF_TYPE) { Spec->Flags |= DS_NO_EMPTY_DECL; } @@ -2237,7 +2238,7 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) ParseAttribute (D); /* Check a few pre-C99 things */ - if (D->Ident[0] != '\0' && (Spec->Flags & DS_DEF_TYPE) != 0) { + if (D->Ident[0] != '\0' && (Spec->Flags & DS_TYPE_MASK) == DS_DEF_TYPE) { /* Check and warn about an implicit int return in the function */ if (IsTypeFunc (D->Type) && IsRankInt (GetFuncReturnType (D->Type))) { /* Function has an implicit int return. Output a warning if we don't @@ -2286,8 +2287,8 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) } if (PrevErrorCount != ErrorCount) { - if ((Spec->Flags & DS_DEF_TYPE) == 0 && - (Spec->Flags & DS_NO_EMPTY_DECL) != 0 && + if ((Spec->Flags & DS_TYPE_MASK) != DS_DEF_TYPE && + (Spec->Flags & DS_NO_EMPTY_DECL) != 0 && D->Ident[0] == '\0') { /* Use a fictitious name for the identifier if it is missing */ const char* Level = ""; diff --git a/src/cc65/declare.h b/src/cc65/declare.h index 36de40311..6185a111e 100644 --- a/src/cc65/declare.h +++ b/src/cc65/declare.h @@ -65,15 +65,18 @@ enum typespec_t { TS_DEFAULT_TYPE_AUTO = 0x02, /* C23 type inference with auto */ /* Whether to allow certain kinds of specifiers */ - TS_STORAGE_CLASS_SPEC = 0x04, /* Allow storage storage class specifiers */ - TS_FUNCTION_SPEC = 0x08, /* Allow function specifiers */ + TS_STORAGE_CLASS_SPEC = 0x04, /* Allow storage class specifiers */ + TS_FUNCTION_SPEC = 0x08, /* Allow function specifiers */ }; /* Masks for the Flags field in DeclSpec */ +#define DS_NONE 0x0000U /* Nothing specified or used */ #define DS_DEF_STORAGE 0x0001U /* Default storage class used */ -#define DS_NO_TYPE 0x0002U /* No type explicitly specified */ -#define DS_DEF_TYPE 0x0006U /* Default type used */ -#define DS_EXTRA_TYPE 0x0008U /* Extra type declared */ +#define DS_EXPLICIT_TYPE 0x0002U /* Type specified */ +#define DS_DEF_TYPE 0x0004U /* Implicit type used */ +#define DS_AUTO_TYPE 0x0006U /* C23 auto type used */ +#define DS_TYPE_MASK 0x0006U /* Mask for type of spec decl */ +#define DS_EXTRA_TYPE 0x0008U /* ESU type in declaration */ #define DS_NEW_TYPE_DECL 0x0010U /* New type declared */ #define DS_NEW_TYPE_DEF 0x0020U /* New type defined */ #define DS_NEW_TYPE (DS_NEW_TYPE_DECL | DS_NEW_TYPE_DEF) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index d672b032e..a0902ed82 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1414,7 +1414,7 @@ static void Primary (ExprDesc* E) DeclSpec Spec; ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE, SC_AUTO); - if ((Spec.Flags & DS_DEF_TYPE) == 0) { + if ((Spec.Flags & DS_TYPE_MASK) != DS_NONE) { /* Recognized but not supported */ Error ("Mixed declarations and code are not supported in cc65"); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 701dcb806..79bbd4573 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -575,7 +575,7 @@ void DeclareLocals (void) ** assumed that we have reached the end of declarations. */ if ((Spec.Flags & DS_DEF_STORAGE) != 0 && /* No storage spec */ - (Spec.Flags & DS_DEF_TYPE) == DS_DEF_TYPE && /* No type given */ + (Spec.Flags & DS_TYPE_MASK) == DS_DEF_TYPE && /* No type given */ GetQualifier (Spec.Type) == T_QUAL_NONE) { /* No type qualifier */ break; } From cadf8012f6b861d67b5e68a54f7b65b9fe71c633 Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 10 Dec 2023 15:43:24 +0800 Subject: [PATCH 036/707] Improved error recovery with type cast and sizeof. --- src/cc65/declare.c | 31 +++++++++++++++++++++++----- src/cc65/declare.h | 2 +- src/cc65/expr.c | 20 +----------------- src/cc65/scanner.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ src/cc65/scanner.h | 5 +++++ src/cc65/typeconv.c | 8 +------- 6 files changed, 83 insertions(+), 32 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 62c2bdfa3..fdc481ce1 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2166,20 +2166,41 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) Type* ParseType (Type* T) -/* Parse a complete type specification */ +/* Parse a complete type specification in parentheses */ { DeclSpec Spec; Declarator Decl; + int NeedClean = -1; + + /* Skip the left paren */ + NextToken (); /* Get a type without a default */ InitDeclSpec (&Spec); ParseTypeSpec (&Spec, TS_DEFAULT_TYPE_NONE); - /* Parse additional declarators */ - ParseDecl (&Spec, &Decl, DM_NO_IDENT); + /* Only parse further if there is a type specifier */ + if ((Spec.Flags & DS_TYPE_MASK) != DS_NONE) { + /* Parse additional declarators */ + NeedClean = ParseDecl (&Spec, &Decl, DM_NO_IDENT); - /* Copy the type to the target buffer */ - TypeCopy (T, Decl.Type); + /* Copy the type to the target buffer */ + TypeCopy (T, Decl.Type); + } else { + /* Fail-safe */ + TypeCopy (T, type_int); + } + + /* Try some smart error recovery */ + if (NeedClean < 0) { + SimpleErrorSkip (); + } + + /* Closing paren */ + if (!ConsumeRParen ()) { + SimpleErrorSkip (); + NextToken (); + } /* Return a pointer to the target buffer */ return T; diff --git a/src/cc65/declare.h b/src/cc65/declare.h index 6185a111e..4cfc48c68 100644 --- a/src/cc65/declare.h +++ b/src/cc65/declare.h @@ -135,7 +135,7 @@ typedef enum { Type* ParseType (Type* Type); -/* Parse a complete type specification */ +/* Parse a complete type specification in parentheses */ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode); /* Parse a variable, type or function declarator. Return -1 if this stops at diff --git a/src/cc65/expr.c b/src/cc65/expr.c index a0902ed82..963ea8bd6 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1415,24 +1415,8 @@ static void Primary (ExprDesc* E) ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE, SC_AUTO); if ((Spec.Flags & DS_TYPE_MASK) != DS_NONE) { - /* Recognized but not supported */ Error ("Mixed declarations and code are not supported in cc65"); - - while (CurTok.Tok != TOK_SEMI) { - Declarator Decl; - - /* Parse one declaration */ - ParseDecl (&Spec, &Decl, DM_IDENT_OR_EMPTY); - if (CurTok.Tok == TOK_ASSIGN) { - NextToken (); - ParseInit (Decl.Type); - } - if (CurTok.Tok == TOK_COMMA) { - NextToken (); - } else { - break; - } - } + SmartErrorSkip (0); } else { Error ("Expression expected"); E->Flags |= E_EVAL_MAYBE_UNUSED; @@ -2089,9 +2073,7 @@ void hie10 (ExprDesc* Expr) NextToken (); if (TypeSpecAhead ()) { Type T[MAXTYPELEN]; - NextToken (); Size = ExprCheckedSizeOf (ParseType (T)); - ConsumeRParen (); } else { /* Remember the output queue pointer */ CodeMark Mark; diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 6af9bc4be..6b5235679 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -1392,6 +1392,55 @@ ExitPoint: +int SimpleErrorSkip (void) +/* Skip tokens until an EOF or unpaired right parenthesis/bracket/curly brace +** is reached. Return 0 If this exits at an EOF. Otherwise return -1. +*/ +{ + Collection C = AUTO_COLLECTION_INITIALIZER; + int Res = 0; + + /* Some fix point tokens that are used for error recovery */ + static const token_t TokenList[] = { + TOK_LPAREN, TOK_RPAREN, TOK_LBRACK, TOK_RBRACK, TOK_LCURLY, TOK_RCURLY }; + + while (CurTok.Tok != TOK_CEOF) { + SkipTokens (TokenList, sizeof (TokenList) / sizeof (TokenList[0])); + + switch (CurTok.Tok) { + case TOK_LPAREN: + case TOK_LBRACK: + case TOK_LCURLY: + OpenBrace (&C, CurTok.Tok); + break; + + case TOK_RPAREN: + case TOK_RBRACK: + case TOK_RCURLY: + if (CloseBrace (&C, CurTok.Tok) < 0) { + /* Found a terminator */ + Res = -1; + goto ExitPoint; + } + break; + + case TOK_CEOF: + /* We cannot go any farther */ + Res = 0; + goto ExitPoint; + + default: + Internal ("Unexpected token: %02X", (unsigned)CurTok.Tok); + } + } + +ExitPoint: + DoneCollection (&C); + return Res; +} + + + int Consume (token_t Token, const char* ErrorMsg) /* Eat token if it is the next in the input stream, otherwise print an error ** message. Returns true if the token was found and false otherwise. diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 808b96c5e..ccf3a8805 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -339,6 +339,11 @@ int SmartErrorSkip (int TillEnd); ** If this exits at a non-EOF without consuming it. */ +int SimpleErrorSkip (void); +/* Skip tokens until an EOF or unpaired right parenthesis/bracket/curly brace +** is reached. Return 0 If this exits at an EOF. Otherwise return -1. +*/ + int Consume (token_t Token, const char* ErrorMsg); /* Eat token if it is the next in the input stream, otherwise print an error ** message. Returns true if the token was found and false otherwise. diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index e5b6749d6..76658502d 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -321,15 +321,9 @@ void TypeCast (ExprDesc* Expr) { Type NewType[MAXTYPELEN]; - /* Skip the left paren */ - NextToken (); - - /* Read the type */ + /* Read the type enclosed in parentheses */ ParseType (NewType); - /* Closing paren */ - ConsumeRParen (); - /* Read the expression we have to cast */ hie10 (Expr); From 3215d377ea27cf404126ef4c33a4a48008bbf015 Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 10 Dec 2023 15:46:48 +0800 Subject: [PATCH 037/707] More accurate diagnostic messages on wrong missing declaration specifiers. --- src/cc65/compile.c | 13 +++++++++++ src/cc65/declare.c | 56 +++++++++++++++++++++++++++++++++++++--------- src/cc65/locals.c | 11 +++++++++ 3 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 5101eccd4..0dc75273d 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -88,6 +88,7 @@ static void Parse (void) /* Fill up the next token with a bogus semicolon and start the tokenizer */ NextTok.Tok = TOK_SEMI; NextToken (); + NextToken (); /* Parse until end of input */ while (CurTok.Tok != TOK_CEOF) { @@ -98,6 +99,7 @@ static void Parse (void) /* Check for empty statements */ if (CurTok.Tok == TOK_SEMI) { + /* TODO: warn on this if we have a pedantic mode */ NextToken (); continue; } @@ -137,6 +139,16 @@ static void Parse (void) continue; } + /* If we haven't got a type specifier yet, something must be wrong */ + if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) { + /* Avoid extra errors if it was a failed type specifier */ + if ((Spec.Flags & DS_EXTRA_TYPE) == 0) { + Error ("Declaration specifier expected"); + } + NeedClean = -1; + goto EndOfDecl; + } + /* Read declarations for this type */ Comma = 0; while (1) { @@ -355,6 +367,7 @@ static void Parse (void) } } +EndOfDecl: /* Try some smart error recovery */ if (NeedClean < 0) { SmartErrorSkip (1); diff --git a/src/cc65/declare.c b/src/cc65/declare.c index fdc481ce1..029e22069 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -979,6 +979,13 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) DeclSpec Spec; int NeedClean = 0; + /* Check for extra semicolons */ + if (CurTok.Tok == TOK_SEMI) { + /* TODO: warn on this if we have a pedantic mode */ + NextToken (); + continue; + } + /* Check for a _Static_assert */ if (CurTok.Tok == TOK_STATIC_ASSERT) { ParseStaticAssert (); @@ -995,6 +1002,16 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) continue; } + /* If we haven't got a type specifier yet, something must be wrong */ + if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) { + /* Avoid extra errors if it was a failed type specifier */ + if ((Spec.Flags & DS_EXTRA_TYPE) == 0) { + Error ("Declaration specifier expected"); + } + NeedClean = -1; + goto EndOfDecl; + } + /* Allow anonymous bit-fields */ Spec.Flags |= DS_ALLOW_BITFIELD; @@ -1107,6 +1124,7 @@ NextMember: NextToken (); } +EndOfDecl: if (NeedClean > 0) { /* Must be followed by a semicolon */ if (ConsumeSemi ()) { @@ -1181,6 +1199,13 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) DeclSpec Spec; int NeedClean = 0; + /* Check for extra semicolons */ + if (CurTok.Tok == TOK_SEMI) { + /* TODO: warn on this if we have a pedantic mode */ + NextToken (); + continue; + } + /* Check for a _Static_assert */ if (CurTok.Tok == TOK_STATIC_ASSERT) { ParseStaticAssert (); @@ -1197,6 +1222,16 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) continue; } + /* If we haven't got a type specifier yet, something must be wrong */ + if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) { + /* Avoid extra errors if it was a failed type specifier */ + if ((Spec.Flags & DS_EXTRA_TYPE) == 0) { + Error ("Declaration specifier expected"); + } + NeedClean = -1; + goto EndOfDecl; + } + /* Allow anonymous bit-fields */ Spec.Flags |= DS_ALLOW_BITFIELD; @@ -1362,6 +1397,7 @@ NextMember: NextToken (); } +EndOfDecl: if (NeedClean > 0) { /* Must be followed by a semicolon */ if (ConsumeSemi ()) { @@ -1559,6 +1595,8 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags) case TOK_UNION: NextToken (); + /* Remember we have an extra type decl */ + Spec->Flags |= DS_EXTRA_TYPE; /* Check for tag name */ if (CurTok.Tok == TOK_IDENT) { strcpy (Ident, CurTok.Ident); @@ -1570,8 +1608,6 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags) UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); break; } - /* Remember we have an extra type decl */ - Spec->Flags |= DS_EXTRA_TYPE; /* Declare the union in the current scope */ TagEntry = ParseUnionSpec (Ident, &Spec->Flags); /* Encode the union entry into the type */ @@ -1582,6 +1618,8 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags) case TOK_STRUCT: NextToken (); + /* Remember we have an extra type decl */ + Spec->Flags |= DS_EXTRA_TYPE; /* Check for tag name */ if (CurTok.Tok == TOK_IDENT) { strcpy (Ident, CurTok.Ident); @@ -1593,8 +1631,6 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags) UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); break; } - /* Remember we have an extra type decl */ - Spec->Flags |= DS_EXTRA_TYPE; /* Declare the struct in the current scope */ TagEntry = ParseStructSpec (Ident, &Spec->Flags); /* Encode the struct entry into the type */ @@ -1605,6 +1641,8 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags) case TOK_ENUM: NextToken (); + /* Remember we have an extra type decl */ + Spec->Flags |= DS_EXTRA_TYPE; /* Check for tag name */ if (CurTok.Tok == TOK_IDENT) { strcpy (Ident, CurTok.Ident); @@ -1616,8 +1654,6 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags) UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); break; } - /* Remember we have an extra type decl */ - Spec->Flags |= DS_EXTRA_TYPE; /* Parse the enum decl */ TagEntry = ParseEnumSpec (Ident, &Spec->Flags); /* Encode the enum entry into the type */ @@ -1658,9 +1694,7 @@ static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags) ** in DeclareLocals. The type code used here doesn't matter as ** long as it has no qualifiers. */ - Spec->Flags |= DS_DEF_TYPE; - Spec->Type[0].C = T_INT; - Spec->Type[1].C = T_END; + UseDefaultType (Spec, TS_DEFAULT_TYPE_INT); break; } /* FALL THROUGH */ @@ -2376,7 +2410,9 @@ void CheckEmptyDecl (const DeclSpec* Spec) ** warning if not. */ { - if ((Spec->Flags & DS_EXTRA_TYPE) == 0) { + if ((Spec->Flags & DS_TYPE_MASK) == DS_NONE) { + /* No declaration at all */ + } else if ((Spec->Flags & DS_EXTRA_TYPE) == 0) { Warning ("Declaration does not declare anything"); } else if (IsClassStruct (Spec->Type) && !IsIncompleteESUType (Spec->Type) && diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 79bbd4573..b8738992f 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -588,6 +588,16 @@ void DeclareLocals (void) continue; } + /* If we haven't got a type specifier yet, something must be wrong */ + if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) { + /* Avoid extra errors if it was a failed type specifier */ + if ((Spec.Flags & DS_EXTRA_TYPE) == 0) { + Error ("Declaration specifier expected"); + } + NeedClean = -1; + goto EndOfDecl; + } + /* Parse a comma separated variable list */ while (1) { @@ -616,6 +626,7 @@ void DeclareLocals (void) } } +EndOfDecl: /* Try some smart error recovery */ if (NeedClean < 0) { SmartErrorSkip (1); From 07c71541f43f70e59cf440dc1d9c9e085f9f577c Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sun, 10 Dec 2023 09:30:41 +0100 Subject: [PATCH 038/707] Fix #2262: Make sure there's no branching after the sequence Also better check that arguments match --- src/cc65/coptlong.c | 79 +++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/src/cc65/coptlong.c b/src/cc65/coptlong.c index 16f089e49..29cf4d353 100644 --- a/src/cc65/coptlong.c +++ b/src/cc65/coptlong.c @@ -49,24 +49,30 @@ /* Remove unused loads and stores */ /*****************************************************************************/ - - unsigned OptLongAssign (CodeSeg* S) /* Simplify long assignments. ** Recognize -** lda ... 0 +** lda #IMM 0 ** sta sreg+1 1 -** lda ... 2 +** lda #IMM 2 ** sta sreg 3 -** lda ... 4 -** ldx ... 5 -** sta M0002 6 -** stx M0002+1 7 +** lda #IMM 4 +** ldx #IMM 5 +** sta YYY 6 +** stx YYY+1 7 ** ldy sreg 8 -** sty M0002+2 9 +** sty YYY+2 9 ** ldy sreg+1 10 -** sty M0002+3 11 -** and simplify if not used right after. +** sty YYY+3 11 +** and simplify, if not used right after and no branching occurs, to +** lda XXX+3 +** sta YYY+3 +** lda XXX+2 +** sta YYY+2 +** ldx XXX +** lda XXX+1 +** sta YYY +** stx YYY+1 */ { unsigned Changes = 0; @@ -75,35 +81,43 @@ unsigned OptLongAssign (CodeSeg* S) unsigned I = 0; while (I < CS_GetEntryCount (S)) { - CodeEntry* L[12]; + CodeEntry* L[13]; /* Get next entry */ L[0] = CS_GetEntry (S, I); - if (CS_GetEntries (S, L+1, I+1, 11)) { - if (L[0]->OPC == OP65_LDA && + if (CS_GetEntries (S, L+1, I+1, 12)) { + if (/* Check the opcode sequence */ + L[0]->OPC == OP65_LDA && L[1]->OPC == OP65_STA && - !strcmp (L[1]->Arg, "sreg+1") && L[2]->OPC == OP65_LDA && L[3]->OPC == OP65_STA && - !strcmp (L[3]->Arg, "sreg") && L[4]->OPC == OP65_LDA && L[5]->OPC == OP65_LDX && L[6]->OPC == OP65_STA && L[7]->OPC == OP65_STX && - !strncmp(L[7]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && - !strcmp(L[7]->Arg + strlen(L[6]->Arg), "+1") && L[8]->OPC == OP65_LDY && - !strcmp (L[8]->Arg, "sreg") && L[9]->OPC == OP65_STY && - !strncmp(L[9]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && - !strcmp(L[9]->Arg + strlen(L[6]->Arg), "+2") && L[10]->OPC == OP65_LDY && - !strcmp (L[10]->Arg, "sreg+1") && L[11]->OPC == OP65_STY && - !strncmp(L[11]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && + /* Check the arguments match */ + L[0]->AM == AM65_IMM && + !strcmp (L[1]->Arg, "sreg+1") && + L[2]->AM == AM65_IMM && + !strcmp (L[3]->Arg, "sreg") && + L[4]->AM == AM65_IMM && + L[5]->AM == AM65_IMM && + !strncmp(L[7]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && + !strcmp(L[7]->Arg + strlen(L[6]->Arg), "+1") && + !strcmp (L[8]->Arg, "sreg") && + !strncmp(L[9]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && + !strcmp(L[9]->Arg + strlen(L[6]->Arg), "+2") && + !strcmp (L[10]->Arg, "sreg+1") && + !strncmp(L[11]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && !strcmp(L[11]->Arg + strlen(L[6]->Arg), "+3") && - !RegXUsed (S, I+11)) { + /* Check there's nothing more */ + !RegXUsed (S, I+12) && + !CS_RangeHasLabel(S, I, 12)) { L[1]->AM = L[11]->AM; CE_SetArg(L[1], L[11]->Arg); @@ -142,7 +156,15 @@ unsigned OptLongCopy (CodeSeg* S) ** sty YYY+2 9 ** ldy sreg+1 10 ** sty YYY+3 11 -** and simplify if not used right after. +** and simplify, if not used right after and no branching occurs, to +** lda XXX+3 +** sta YYY+3 +** lda XXX+2 +** sta YYY+2 +** ldx XXX +** lda XXX+1 +** sta YYY +** stx YYY+1 */ { unsigned Changes = 0; @@ -151,12 +173,12 @@ unsigned OptLongCopy (CodeSeg* S) unsigned I = 0; while (I < CS_GetEntryCount (S)) { - CodeEntry* L[12]; + CodeEntry* L[13]; /* Get next entry */ L[0] = CS_GetEntry (S, I); - if (CS_GetEntries (S, L+1, I+1, 11)) { + if (CS_GetEntries (S, L+1, I+1, 12)) { if (L[0]->OPC == OP65_LDA && !strncmp(L[0]->Arg, L[5]->Arg, strlen(L[5]->Arg)) && !strcmp(L[0]->Arg + strlen(L[5]->Arg), "+3") && @@ -185,7 +207,8 @@ unsigned OptLongCopy (CodeSeg* S) L[11]->OPC == OP65_STY && !strncmp(L[11]->Arg, L[6]->Arg, strlen(L[6]->Arg)) && !strcmp(L[11]->Arg + strlen(L[6]->Arg), "+3") && - !RegXUsed (S, I+11)) { + !RegXUsed (S, I+11) && + !CS_RangeHasLabel(S, I, 12)) { L[1]->AM = L[11]->AM; CE_SetArg(L[1], L[11]->Arg); From bbd542fac7fd78d6cb2b7c53cf198c3c79b3047d Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 10 Dec 2023 17:01:54 +0800 Subject: [PATCH 039/707] Fixed missing diagnosis on extra identifiers in type names. --- src/cc65/declare.c | 3 +++ test/err/type-name-extra-identifier.c | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 test/err/type-name-extra-identifier.c diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 029e22069..076e94aa8 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2080,6 +2080,9 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) DirectDecl (Spec, D, Mode); ConsumeRParen (); } else if (CurTok.Tok == TOK_IDENT) { + if (Mode == DM_NO_IDENT) { + Error ("Unexpected identifier in type name"); + } strcpy (D->Ident, CurTok.Ident); NextToken (); } else { diff --git a/test/err/type-name-extra-identifier.c b/test/err/type-name-extra-identifier.c new file mode 100644 index 000000000..72de4778d --- /dev/null +++ b/test/err/type-name-extra-identifier.c @@ -0,0 +1,25 @@ +/* + Copyright 2023 The cc65 Authors + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + Test of type name with extra identifier +*/ + +int a = sizeof (int b); From befc9533c6195e9cc18aa4873b823d486dba0abd Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 10 Dec 2023 20:21:50 +0800 Subject: [PATCH 040/707] More accurate diagnostic messages on empty declarations without any type specifiers. --- src/cc65/declare.c | 9 ++++++--- src/cc65/expr.c | 2 +- test/ref/bug1889-missing-identifier.cref | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 076e94aa8..ec5116ead 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2087,10 +2087,13 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) NextToken (); } else { D->Ident[0] = '\0'; - if ((Spec->Flags & DS_NO_EMPTY_DECL) != 0 && - CurTok.Tok != TOK_LBRACK && + if (CurTok.Tok != TOK_LBRACK && ((Spec->Flags & DS_ALLOW_BITFIELD) == 0 || CurTok.Tok != TOK_COLON)) { - Error ("Identifier expected"); + if ((Spec->Flags & DS_TYPE_MASK) == DS_DEF_TYPE) { + Error ("Declaration specifier or identifier expected"); + } else if ((Spec->Flags & DS_NO_EMPTY_DECL) != 0) { + Error ("Identifier expected"); + } } } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 963ea8bd6..ed918b4ee 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1412,7 +1412,7 @@ static void Primary (ExprDesc* E) } else { /* Let's see if this is a C99-style declaration */ DeclSpec Spec; - ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE, SC_AUTO); + ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT, SC_AUTO); if ((Spec.Flags & DS_TYPE_MASK) != DS_NONE) { Error ("Mixed declarations and code are not supported in cc65"); diff --git a/test/ref/bug1889-missing-identifier.cref b/test/ref/bug1889-missing-identifier.cref index 2d92ff263..7381d2032 100644 --- a/test/ref/bug1889-missing-identifier.cref +++ b/test/ref/bug1889-missing-identifier.cref @@ -1,3 +1,3 @@ bug1889-missing-identifier.c:3: Error: Identifier or ';' expected after declaration specifiers bug1889-missing-identifier.c:3: Warning: Implicit 'int' is an obsolete feature -bug1889-missing-identifier.c:4: Error: Identifier expected +bug1889-missing-identifier.c:4: Error: Declaration specifier or identifier expected From b31a1c7c0c25de087e272c045eb2370a03856c93 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 10 Dec 2023 22:16:30 +0100 Subject: [PATCH 041/707] test for regression that occured after #2262 --- test/val/optimizer-bug-pr2262.c | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 test/val/optimizer-bug-pr2262.c diff --git a/test/val/optimizer-bug-pr2262.c b/test/val/optimizer-bug-pr2262.c new file mode 100644 index 000000000..f2c08a98c --- /dev/null +++ b/test/val/optimizer-bug-pr2262.c @@ -0,0 +1,53 @@ + +// optimizer bug that occured after PR #2262, fixed by PR #2295 + +#include + +unsigned char n; +unsigned long fp1; + +int failures = 0; + +void test1(void) +{ + asm("lda _n"); + asm("jeq %g", L0004); + + asm("lda #$3F"); + asm("sta sreg+1"); + asm("lda #$C0"); + asm("sta sreg"); + asm("lda #$00"); + asm("ldx #$00"); + asm("jmp %g", L0005); + +L0004: + asm("lda #$3F"); + asm("sta sreg+1"); + asm("lda #$00"); + asm("sta sreg"); + asm("lda #$00"); + asm("ldx #$00"); + +L0005: + asm("sta _fp1"); + asm("stx _fp1+1"); + asm("ldy sreg"); + asm("sty _fp1+2"); + asm("ldy sreg+1"); + asm("sty _fp1+3"); +} + +int main(void) +{ + n = 0; + test1(); + printf("fp1:%08lx\n", fp1); + if (fp1 != 0x3f000000) failures++; + n = 0xff; + test1(); + printf("fp1:%08lx\n", fp1); + if (fp1 != 0x3fc00000) failures++; + printf("failures:%d\n", failures); + return failures; +} From 0b077f561f890c74045dc72598243d01c5384fc0 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 10 Dec 2023 22:43:47 +0100 Subject: [PATCH 042/707] exclude test directory from some style checks - it makes no sense to enforce these things in the test bench, we need to be able to test all kinds of spaces and tabs :) --- .github/checks/spaces.sh | 2 +- .github/checks/tabs.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/checks/spaces.sh b/.github/checks/spaces.sh index 945e9acc3..e231f6c2d 100755 --- a/.github/checks/spaces.sh +++ b/.github/checks/spaces.sh @@ -5,7 +5,7 @@ CHECK_PATH=. cd $SCRIPT_PATH/../../ -FILES=`find $CHECK_PATH -type f \( -name \*.inc -o -name Makefile -o -name \*.cfg -o -name \*.\[chs\] -o -name \*.mac -o -name \*.asm -o -name \*.sgml \) -print | grep -v "libwrk/" | grep -v "testwrk/" | xargs grep -l ' $'` +FILES=`find $CHECK_PATH -type f \( -name \*.inc -o -name Makefile -o -name \*.cfg -o -name \*.\[chs\] -o -name \*.mac -o -name \*.asm -o -name \*.sgml \) -print | grep -v "test/" | grep -v "libwrk/" | grep -v "testwrk/" | xargs grep -l ' $'` cd $OLDCWD diff --git a/.github/checks/tabs.sh b/.github/checks/tabs.sh index 1c32def17..80dac3f2d 100755 --- a/.github/checks/tabs.sh +++ b/.github/checks/tabs.sh @@ -5,7 +5,7 @@ CHECK_PATH=. cd $SCRIPT_PATH/../../ -FILES=`find $CHECK_PATH -type f \( \( -name \*.inc -a \! -name Makefile.inc \) -o -name \*.cfg -o -name \*.\[chs\] -o -name \*.mac -o -name \*.asm -o -name \*.sgml \) -print | grep -v "libwrk/" | grep -v "testwrk/" | xargs grep -l $'\t'` +FILES=`find $CHECK_PATH -type f \( \( -name \*.inc -a \! -name Makefile.inc \) -o -name \*.cfg -o -name \*.\[chs\] -o -name \*.mac -o -name \*.asm -o -name \*.sgml \) -print | grep -v "test/" | grep -v "libwrk/" | grep -v "testwrk/" | xargs grep -l $'\t'` cd $OLDCWD From 6b855d562aa16b1e36ef7270b0dcfdb27398bd24 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 10 Dec 2023 23:18:55 +0100 Subject: [PATCH 043/707] use -std=gnu17 for the references, so the test bench will not break with GCC 14. see #2277 --- test/ref/Makefile | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/ref/Makefile b/test/ref/Makefile index abd3e9bc0..9538fdee7 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -39,8 +39,18 @@ OPTIONS = g O Os Osi Osir Osr Oi Oir Or ISEQUAL = ..$S..$Stestwrk$Sisequal$(EXE) +# NOTE: the current test bench may include K&R style C, C89 style C, C99 - and +# even things from later standards. Technically C99 removed certain C89 +# constructs - However, so far GCC would still compile them and issue a +# warning (instead of an error). Now, GCC 14 will be more strict about this, +# and by default make those things an error instead. We use -std=gnu17 here +# so we can still build the references with a modern compiler, and don't +# have to deal with special-casing individual tests that use constructs +# from those old standards. Should this become a problem in the future, we +# will have to change that, and create said special cases here. +# see discussion in https://github.com/cc65/cc65/issues/2277 CC = gcc -CFLAGS = -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow +CFLAGS = -std=gnu17 -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow .PHONY: all clean From 9985ee7f61f9c0e1b1256d16e3fb901c87531019 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Mon, 11 Dec 2023 00:18:40 +0100 Subject: [PATCH 044/707] fix %hhn and %hn in the internal xvsnprintf function --- src/common/xsprintf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/xsprintf.c b/src/common/xsprintf.c index 556e4f359..2e811a5b1 100644 --- a/src/common/xsprintf.c +++ b/src/common/xsprintf.c @@ -352,8 +352,8 @@ static void StoreOffset (PrintfCtrl* P) /* Store the current output offset (%n format spec) */ { switch (P->LengthMod) { - case lmChar: *va_arg (P->ap, int*) = P->BufFill; break; - case lmShort: *va_arg (P->ap, int*) = P->BufFill; break; + case lmChar: *va_arg (P->ap, char*) = P->BufFill; break; + case lmShort: *va_arg (P->ap, short*) = P->BufFill; break; case lmInt: *va_arg (P->ap, int*) = P->BufFill; break; case lmLong: *va_arg (P->ap, long*) = P->BufFill; break; case lmIntMax: *va_arg (P->ap, intmax_t*) = P->BufFill; break; From b1c150249495d35b299c46579efc47a7b3cbc717 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Mon, 11 Dec 2023 00:35:07 +0100 Subject: [PATCH 045/707] MS compiler insists on those typecasts apparently --- src/common/xsprintf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/xsprintf.c b/src/common/xsprintf.c index 2e811a5b1..aa3183752 100644 --- a/src/common/xsprintf.c +++ b/src/common/xsprintf.c @@ -352,8 +352,8 @@ static void StoreOffset (PrintfCtrl* P) /* Store the current output offset (%n format spec) */ { switch (P->LengthMod) { - case lmChar: *va_arg (P->ap, char*) = P->BufFill; break; - case lmShort: *va_arg (P->ap, short*) = P->BufFill; break; + case lmChar: *va_arg (P->ap, char*) = (char)P->BufFill; break; + case lmShort: *va_arg (P->ap, short*) = (short)P->BufFill; break; case lmInt: *va_arg (P->ap, int*) = P->BufFill; break; case lmLong: *va_arg (P->ap, long*) = P->BufFill; break; case lmIntMax: *va_arg (P->ap, intmax_t*) = P->BufFill; break; From f8fe1d1560aa79d497393771fa10ef09663da7bb Mon Sep 17 00:00:00 2001 From: acqn Date: Wed, 13 Dec 2023 22:57:32 +0800 Subject: [PATCH 046/707] Fixed missing diagnosis on function parameter lists with trailing commas. --- src/cc65/declare.c | 107 +++++++++++++++++++---------- test/err/bug2301-trailing-coma-1.c | 3 + test/err/bug2301-trailing-coma-2.c | 6 ++ 3 files changed, 78 insertions(+), 38 deletions(-) create mode 100644 test/err/bug2301-trailing-coma-1.c create mode 100644 test/err/bug2301-trailing-coma-2.c diff --git a/src/cc65/declare.c b/src/cc65/declare.c index eee6dff9f..2746d1326 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1740,10 +1740,12 @@ static const Type* ParamTypeCvt (Type* T) static void ParseOldStyleParamList (FuncDesc* F) /* Parse an old-style (K&R) parameter list */ { - unsigned PrevErrorCount = ErrorCount; + if (CurTok.Tok == TOK_RPAREN) { + return; + } /* Parse params */ - while (CurTok.Tok != TOK_RPAREN) { + while (1) { /* List of identifiers expected */ if (CurTok.Tok == TOK_IDENT) { @@ -1768,29 +1770,33 @@ static void ParseOldStyleParamList (FuncDesc* F) } /* Check for more parameters */ - if (CurTok.Tok == TOK_COMMA) { - NextToken (); - } else { + if (CurTok.Tok != TOK_COMMA) { break; } - } + NextToken (); - /* Skip right paren. We must explicitly check for one here, since some of - ** the breaks above bail out without checking. - */ - ConsumeRParen (); + } +} + + + +static void ParseOldStyleParamDeclList (FuncDesc* F attribute ((unused))) +/* Parse an old-style (K&R) function declarator declaration list */ +{ + if (CurTok.Tok == TOK_SEMI) { + /* No parameter declaration list */ + return; + } /* An optional list of type specifications follows */ while (CurTok.Tok != TOK_LCURLY) { DeclSpec Spec; + int NeedClean; /* Read the declaration specifier */ ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE, SC_AUTO); - /* Paremeters must have identifiers as names */ - Spec.Flags |= DS_NO_EMPTY_DECL; - /* We accept only auto and register as storage class specifiers, but ** we ignore all this, since we use auto anyway. */ @@ -1799,10 +1805,14 @@ static void ParseOldStyleParamList (FuncDesc* F) Error ("Illegal storage class"); } - /* Type must be specified */ + /* If we haven't got a type specifier yet, something must be wrong */ if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) { - Error ("Expected declaration specifiers"); - break; + /* Avoid extra errors if it was a failed type specifier */ + if ((Spec.Flags & DS_EXTRA_TYPE) == 0) { + Error ("Declaration specifier expected"); + } + NeedClean = -1; + goto EndOfDecl; } /* Parse a comma separated variable list */ @@ -1811,7 +1821,12 @@ static void ParseOldStyleParamList (FuncDesc* F) Declarator Decl; /* Read the parameter */ - ParseDecl (&Spec, &Decl, DM_IDENT_OR_EMPTY); + NeedClean = ParseDecl (&Spec, &Decl, DM_IDENT_OR_EMPTY); + + /* Bail out if there are errors */ + if (NeedClean <= 0) { + break; + } /* Warn about new local type declaration */ if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0) { @@ -1820,9 +1835,9 @@ static void ParseOldStyleParamList (FuncDesc* F) } if (Decl.Ident[0] != '\0') { - /* We have a name given. Search for the symbol */ SymEntry* Param = FindLocalSym (Decl.Ident); + if (Param) { /* Check if we already changed the type for this ** parameter. @@ -1837,25 +1852,40 @@ static void ParseOldStyleParamList (FuncDesc* F) Error ("Redefinition for parameter '%s'", Param->Name); } } else { - Error ("Unknown identifier: '%s'", Decl.Ident); + Error ("Unknown parameter '%s'", Decl.Ident); + } + + /* Initialization is not allowed */ + if (CurTok.Tok == TOK_ASSIGN) { + Error ("Parameter '%s' cannot be initialized", Decl.Ident); + + /* Try some smart error recovery */ + SmartErrorSkip (0); } } - if (CurTok.Tok == TOK_COMMA) { - NextToken (); - } else { + /* Check for more declarators */ + if (CurTok.Tok != TOK_COMMA) { break; } + NextToken (); } - /* Variable list must be semicolon terminated */ - ConsumeSemi (); - } +EndOfDecl: + if (NeedClean > 0) { + /* Must be followed by a semicolon */ + if (ConsumeSemi ()) { + NeedClean = 0; + } else { + NeedClean = -1; + } + } - if (PrevErrorCount != ErrorCount && CurTok.Tok != TOK_LCURLY) { /* Try some smart error recovery */ - SmartErrorSkip (0); + if (NeedClean < 0) { + SmartErrorSkip (1); + } } } @@ -1864,8 +1894,12 @@ static void ParseOldStyleParamList (FuncDesc* F) static void ParseAnsiParamList (FuncDesc* F) /* Parse a new-style (ANSI) parameter list */ { + if (CurTok.Tok == TOK_RPAREN) { + return; + } + /* Parse params */ - while (CurTok.Tok != TOK_RPAREN) { + while (1) { DeclSpec Spec; Declarator Decl; @@ -1894,7 +1928,7 @@ static void ParseAnsiParamList (FuncDesc* F) /* Type must be specified */ if ((Spec.Flags & DS_TYPE_MASK) == DS_NONE) { - Error ("Type specifier missing"); + Error ("Declaration specifier or '...' expected"); } /* Warn about new local type declaration */ @@ -1945,18 +1979,12 @@ static void ParseAnsiParamList (FuncDesc* F) } } - /* Check for more parameters */ - if (CurTok.Tok == TOK_COMMA) { - NextToken (); - } else { + /* Check for end of parameter type list */ + if (CurTok.Tok != TOK_COMMA) { break; } + NextToken (); } - - /* Skip right paren. We must explicitly check for one here, since some of - ** the breaks above bail out without checking. - */ - ConsumeRParen (); } @@ -1998,9 +2026,12 @@ static FuncDesc* ParseFuncDecl (void) if ((F->Flags & FD_OLDSTYLE) == 0) { /* New-style function */ ParseAnsiParamList (F); + ConsumeRParen (); } else { /* Old-style function */ ParseOldStyleParamList (F); + ConsumeRParen (); + ParseOldStyleParamDeclList (F); } PopLexicalLevel (); diff --git a/test/err/bug2301-trailing-coma-1.c b/test/err/bug2301-trailing-coma-1.c new file mode 100644 index 000000000..66cd4fae3 --- /dev/null +++ b/test/err/bug2301-trailing-coma-1.c @@ -0,0 +1,3 @@ +/* Bug #2301 - Function parameter list with an extra trailing comma should not compile */ + +int foo(int a,); /* Should fail */ diff --git a/test/err/bug2301-trailing-coma-2.c b/test/err/bug2301-trailing-coma-2.c new file mode 100644 index 000000000..40ca3d0ca --- /dev/null +++ b/test/err/bug2301-trailing-coma-2.c @@ -0,0 +1,6 @@ +/* Bug #2301 - Function parameter list with an extra trailing comma should not compile */ + +int bar(a,) int a; /* Should fail */ +{ + return a; +} From 1e4d1b4311149ca84cbd35267e447d58ae47f9e6 Mon Sep 17 00:00:00 2001 From: acqn Date: Thu, 14 Dec 2023 02:34:03 +0800 Subject: [PATCH 047/707] Fixed function declarator parser when a parameter has a function type. Ensured check on parameter lists without types in non-definition declarations. --- src/cc65/compile.c | 8 ++++ src/cc65/declare.c | 92 +++++++++++++++++++++++++++++----------------- test/err/bug2303.c | 1 + test/val/bug2302.c | 32 ++++++++++++++++ 4 files changed, 100 insertions(+), 33 deletions(-) create mode 100644 test/err/bug2303.c create mode 100644 test/val/bug2302.c diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 0dc75273d..b996c78df 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -206,6 +206,14 @@ static void Parse (void) } else { /* Just a declaration */ Decl.StorageClass |= SC_DECL; + + FuncDef = GetFuncDesc (Decl.Type); + if ((FuncDef->Flags & (FD_EMPTY | FD_OLDSTYLE)) == FD_OLDSTYLE) { + /* A parameter list without types is only allowed in a + ** function definition. + */ + Error ("Parameter names without types in function declaration"); + } } } diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 2746d1326..8b7512730 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1989,7 +1989,7 @@ static void ParseAnsiParamList (FuncDesc* F) -static FuncDesc* ParseFuncDecl (void) +static void ParseFuncDecl (Declarator* D, declmode_t Mode, TypeCode Qualifiers) /* Parse the argument list of a function with the enclosing parentheses */ { /* Create a new function descriptor */ @@ -2009,14 +2009,17 @@ static FuncDesc* ParseFuncDecl (void) /* Parameter list declared as void */ NextToken (); F->Flags |= FD_VOID_PARAM; - } else if (CurTok.Tok == TOK_IDENT && + } else if (Mode != DM_NO_IDENT && + CurTok.Tok == TOK_IDENT && (NextTok.Tok == TOK_COMMA || NextTok.Tok == TOK_RPAREN)) { /* If the identifier is a typedef, we have a new-style parameter list; ** if it's some other identifier, it's an old-style parameter list. + ** Note: Non-empty Old-style (K&R) parameter list is not allowed in + ** type names. */ SymEntry* Sym = FindSym (CurTok.Ident); if (Sym == 0 || !SymIsTypeDef (Sym)) { - /* Old-style (K&R) function. */ + /* Old-style (K&R) function */ F->Flags |= FD_OLDSTYLE; } } @@ -2026,13 +2029,20 @@ static FuncDesc* ParseFuncDecl (void) if ((F->Flags & FD_OLDSTYLE) == 0) { /* New-style function */ ParseAnsiParamList (F); - ConsumeRParen (); } else { /* Old-style function */ ParseOldStyleParamList (F); - ConsumeRParen (); + } + + if (!ConsumeRParen ()) { + /* Try some smart error recovery */ + SimpleErrorSkip (); + NextToken (); + } else if (Mode == DM_IDENT_OR_EMPTY && (F->Flags & FD_OLDSTYLE) != 0) { + /* Parameter declaration list is only allowed in function definitions */ ParseOldStyleParamDeclList (F); } + PopLexicalLevel (); /* Remember the last function parameter. We need it later for several @@ -2040,18 +2050,27 @@ static FuncDesc* ParseFuncDecl (void) ** more symbols are added to the table, it is easier if we remember it ** now, since it is currently the last entry in the symbol table. */ - F->LastParam = GetSymTab()->SymTail; + F->LastParam = GetSymTab ()->SymTail; + + /* Leave the lexical level remembering the symbol tables */ + RememberFunctionLevel (F); /* It is allowed to use incomplete types in function prototypes, so we ** won't always get to know the parameter sizes here and may do that later. */ F->Flags |= FD_INCOMPLETE_PARAM; - /* Leave the lexical level remembering the symbol tables */ - RememberFunctionLevel (F); + /* We cannot specify fastcall for variadic functions */ + if ((F->Flags & FD_VARIADIC) && (Qualifiers & T_QUAL_FASTCALL)) { + Error ("Variadic functions cannot be __fastcall__"); + Qualifiers &= ~T_QUAL_FASTCALL; + } - /* Return the function descriptor */ - return F; + /* Add the function type. Be sure to bounds check the type buffer */ + NeedTypeSpace (D, 1); + D->Type[D->Index].C = T_FUNC | Qualifiers; + D->Type[D->Index].A.F = F; + ++D->Index; } @@ -2090,15 +2109,37 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) } if (CurTok.Tok == TOK_LPAREN) { - NextToken (); + SymEntry* Entry; + /* An empty declaration cannot contain parentheses where an identifier ** would show up if it were a non-empty declaration. */ if (Mode == DM_IDENT_OR_EMPTY) { Spec->Flags |= DS_NO_EMPTY_DECL; } - DirectDecl (Spec, D, Mode); - ConsumeRParen (); + + /* We have to disambiguate the meanings of 'type (identifier' when + ** the identifier can be a typedef'ed parameter type specifier or + ** a declarator enclosed in parentheses in some cases. + */ + if (Mode == DM_IDENT_OR_EMPTY || /* If we are in a declaration... */ + NextTok.Tok == TOK_LPAREN || /* or the next token is one more paren... */ + NextTok.Tok == TOK_STAR || /* or a '*' ... */ + (NextTok.Tok == TOK_IDENT && /* or an identifier that... */ + ((Entry = FindSym (NextTok.Ident)) == 0 || /* is not a typedef. */ + !SymIsTypeDef (Entry)))) { + /* Parse the direct declarator in parentheses */ + NextToken (); + DirectDecl (Spec, D, Mode); + ConsumeRParen (); + } else { + /* This is a parameter type list in parentheses */ + ParseFuncDecl (D, Mode, Qualifiers); + + /* Qualifiers now used */ + Qualifiers = T_QUAL_NONE; + } + } else if (CurTok.Tok == TOK_IDENT) { if (Mode == DM_NO_IDENT) { Error ("Unexpected identifier in type name"); @@ -2119,28 +2160,11 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN) { if (CurTok.Tok == TOK_LPAREN) { - /* Function declarator */ - FuncDesc* F; - - /* Parse the function declarator */ - F = ParseFuncDecl (); - - /* We cannot specify fastcall for variadic functions */ - if ((F->Flags & FD_VARIADIC) && (Qualifiers & T_QUAL_FASTCALL)) { - Error ("Variadic functions cannot be __fastcall__"); - Qualifiers &= ~T_QUAL_FASTCALL; - } - - /* Add the function type. Be sure to bounds check the type buffer */ - NeedTypeSpace (D, 1); - D->Type[D->Index].C = T_FUNC | Qualifiers; - D->Type[D->Index].A.F = F; - ++D->Index; + ParseFuncDecl (D, Mode, Qualifiers); /* Qualifiers now used */ Qualifiers = T_QUAL_NONE; - } else { /* Array declarator */ long Size = UNSPECIFIED; @@ -2385,9 +2409,11 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) } /* Try some smart error recovery */ - if (CurTok.Tok != TOK_LCURLY || !IsTypeFunc (D->Type)) { + if (Mode == DM_NO_IDENT) { + return SimpleErrorSkip (); + } else if (CurTok.Tok != TOK_LCURLY || !IsTypeFunc (D->Type)) { /* Skip to the end of the whole declaration if it is not part of a - ** parameter list or a type cast. + ** parameter list. */ return SmartErrorSkip (Mode == DM_IDENT_OR_EMPTY); } diff --git a/test/err/bug2303.c b/test/err/bug2303.c new file mode 100644 index 000000000..609725ad8 --- /dev/null +++ b/test/err/bug2303.c @@ -0,0 +1 @@ +int f(a); /* Should be an error */ diff --git a/test/val/bug2302.c b/test/val/bug2302.c new file mode 100644 index 000000000..3ca8a5572 --- /dev/null +++ b/test/val/bug2302.c @@ -0,0 +1,32 @@ +/* Bug #2302 - Parameters of function types not parsed correctly */ + +#include + +typedef int A; +int zoo(A ()); /* OK: int zoo(int (*)()) */ +int zoo(A (())); /* OK: int zoo(int ((*)())) aka. int zoo(int (*)()) */ +int zoo(A (A)); /* OK: int zoo(int (*)(int)) */ +int zoo(A ((A))); /* OK: int zoo(int ((*)(int))) aka. int zoo(int (*)(int)) */ +int zoo(A A(A)); /* OK: int zoo(int (*A)(int)) */ +int zoo(A (*)(A)); /* OK: int zoo(int (*)(int)) */ +int zoo(A (*A)(A)); /* OK: int zoo(int (*A)(int)) */ +int zoo(A ((*A))(A)); /* OK: int zoo(int (*A)(int)) */ +int zoo(A ((((*((fp))))(A A)))) /* OK: int zoo(int (*fp)(int A)) */ +{ + return fp(42); +} + +int bar(int a) +{ + return a ^ 42; +} + +int main(void) +{ + int a = zoo((int (*)())bar); + if (a != 0) + { + printf("failed: a = %d\n", a); + } + return a; +} From a5746227dc15b2961b91350ae52a29df13227770 Mon Sep 17 00:00:00 2001 From: acqn Date: Thu, 14 Dec 2023 21:27:48 +0800 Subject: [PATCH 048/707] Added warning on static functions that are used but not defined. --- src/cc65/compile.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 0dc75273d..94e389292 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -273,11 +273,12 @@ static void Parse (void) if (IsTypeVoid (Decl.Type)) { /* We cannot declare variables of type void */ Error ("Illegal type for variable '%s'", Decl.Ident); - Sym->Flags &= ~(SC_STORAGE | SC_DEF); + Sym->Flags |= SC_DEF; } else if (Size == 0 && SymIsDef (Sym) && !IsEmptiableObjectType (Decl.Type)) { /* Size is unknown. Is it an array? */ if (!IsTypeArray (Decl.Type)) { Error ("Variable '%s' has unknown size", Decl.Ident); + Sym->Flags |= SC_DEF; } } else { /* Check for enum forward declaration. @@ -539,10 +540,16 @@ void Compile (const char* FileName) Entry->Flags |= SC_DEF; } else if (!IsTypeArray (Entry->Type)) { /* Tentative declared variable is still of incomplete type */ - Error ("Definition of '%s' has type '%s' that is never completed", + Error ("Definition of '%s' never has its type '%s' completed", Entry->Name, GetFullTypeName (Entry->Type)); } + } else if (!SymIsDef (Entry) && (Entry->Flags & SC_FUNC) == SC_FUNC) { + /* Check for undefined functions */ + if ((Entry->Flags & (SC_EXTERN | SC_STATIC)) == SC_STATIC && SymIsRef (Entry)) { + Warning ("Static function '%s' used but never defined", + Entry->Name); + } } } From 1093d169ad3f03de4b86a69dba200bad62a1f261 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Tue, 12 Dec 2023 18:03:00 +0100 Subject: [PATCH 049/707] Fix BSS obliteration by mliparam during exec(). Using mliparam at this time could lead to corruption at the start of the new executed program if BSS is real full and mliparam is over $BB00. The fix is to open the file from the loader stub instead of doing it before the C library shutdown. --- libsrc/apple2/exec.s | 65 +++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/libsrc/apple2/exec.s b/libsrc/apple2/exec.s index 27a6487bd..b8875e9ca 100644 --- a/libsrc/apple2/exec.s +++ b/libsrc/apple2/exec.s @@ -121,35 +121,9 @@ setbuf: lda #$00 ; Low byte dex dex - ; Set I/O buffer - sta mliparam + MLI::OPEN::IO_BUFFER - stx mliparam + MLI::OPEN::IO_BUFFER+1 - - ; PATHNAME already set - .assert MLI::OPEN::PATHNAME = MLI::INFO::PATHNAME, error - - ; Lower file level to avoid program file - ; being closed by C library shutdown code - ldx LEVEL - stx level - beq :+ - dec LEVEL - - ; Open file -: lda #OPEN_CALL - ldx #OPEN_COUNT - jsr callmli - - ; Restore file level - ldx level - stx LEVEL - bcc :+ - jmp oserr - - ; Get and save fd -: lda mliparam + MLI::OPEN::REF_NUM - sta read_ref - sta close_ref + ; Set OPEN MLI call I/O buffer parameter + sta io_buffer + stx io_buffer+1 .ifdef __APPLE2ENH__ ; Calling the 80 column firmware needs the ROM switched @@ -194,14 +168,25 @@ setbuf: lda #$00 ; Low byte ; Initiate C library shutdown jmp _exit - .bss - -level : .res 1 - .rodata +source: + ; Open program file + ; PATHNAME parameter is already set (we reuse + ; the copy at $0280); IO_BUFFER has been setup + ; before shutting down the C library + jsr $BF00 + .byte OPEN_CALL + .word open_param + bcs error + + ; Copy REF_NUM to MLI READ and CLOSE parameters + lda open_ref + sta read_ref + sta close_ref + ; Read whole program file -source: jsr $BF00 + jsr $BF00 .byte READ_CALL .word read_param bcs error @@ -254,6 +239,14 @@ jump: jmp (data_buffer) file_type = * - source + target .byte $00 +open_param = * - source + target + .byte $03 ; PARAM_COUNT + .addr $0280 ; PATHNAME +io_buffer = * - source + target + .addr $0000 ; IO_BUFFER +open_ref = * - source + target + .byte $00 ; REF_NUM + read_param = * - source + target .byte $04 ; PARAM_COUNT read_ref = * - source + target @@ -285,4 +278,8 @@ size = * - source target = DOSWARM - size + ; Make sure that the loader isn't too big, and + ; fits in $300-$3D0 + .assert target >= $300, error + dosvec: jmp quit From 08341aae3026453cf1b7777e7fc31ef2395772af Mon Sep 17 00:00:00 2001 From: paul moore Date: Thu, 14 Dec 2023 14:25:35 -0800 Subject: [PATCH 050/707] second try at fixing win64 build --- .github/workflows/build-on-pull-request.yml | 16 ++++-- src/ar65.vcxproj | 33 ++++++++++++ src/ca65.vcxproj | 33 ++++++++++++ src/cc65.sln | 60 ++++++++++++++++++++- src/cc65.vcxproj | 35 +++++++++++- src/chrcvt65.vcxproj | 33 ++++++++++++ src/cl65.vcxproj | 33 ++++++++++++ src/cl65/main.c | 2 +- src/co65.vcxproj | 31 +++++++++++ src/common.vcxproj | 29 ++++++++++ src/common/filetype.c | 3 +- src/common/filetype.h | 2 +- src/da65.vcxproj | 33 ++++++++++++ src/grc65.vcxproj | 33 ++++++++++++ src/ld65.vcxproj | 39 +++++++++++++- src/ld65/main.c | 2 +- src/od65.vcxproj | 33 ++++++++++++ src/sim65.vcxproj | 33 ++++++++++++ src/sp65.vcxproj | 35 +++++++++++- 19 files changed, 504 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 55be5db1e..55ee3df2d 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -67,8 +67,16 @@ jobs: - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.1 - - name: Build app (debug) - run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug + - name: Build app (x86 debug) + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug Platform=Win32 + + - name: Build app (x86 release) + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release Platform=Win32 + + - name: Build app (x64 release) + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug Platform=x64 + + - name: Build app (x64 release) + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release Platform=x64 + - - name: Build app (release) - run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release diff --git a/src/ar65.vcxproj b/src/ar65.vcxproj index 27d12dadc..0fd788e06 100644 --- a/src/ar65.vcxproj +++ b/src/ar65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {5E8C19C6-B167-440C-8BEF-3CBF109CDB49} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -40,6 +55,15 @@ Console + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + 4267;%(DisableSpecificWarnings) + + + Console + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) @@ -48,6 +72,15 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 4267;%(DisableSpecificWarnings) + + + Console + + diff --git a/src/ca65.vcxproj b/src/ca65.vcxproj index 3cc6019f2..d8fd39303 100644 --- a/src/ca65.vcxproj +++ b/src/ca65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -40,6 +55,15 @@ Console + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) @@ -48,6 +72,15 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + diff --git a/src/cc65.sln b/src/cc65.sln index 4ae2816ad..8e31ef909 100644 --- a/src/cc65.sln +++ b/src/cc65.sln @@ -1,6 +1,8 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.6.33829.357 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "common.vcxproj", "{71DC1F68-BFC4-478C-8655-C8E9C9654D2B}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cc65", "cc65.vcxproj", "{B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}" @@ -66,61 +68,115 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {71DC1F68-BFC4-478C-8655-C8E9C9654D2B}.Debug|Win32.ActiveCfg = Debug|Win32 {71DC1F68-BFC4-478C-8655-C8E9C9654D2B}.Debug|Win32.Build.0 = Debug|Win32 + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B}.Debug|x64.ActiveCfg = Debug|x64 + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B}.Debug|x64.Build.0 = Debug|x64 {71DC1F68-BFC4-478C-8655-C8E9C9654D2B}.Release|Win32.ActiveCfg = Release|Win32 {71DC1F68-BFC4-478C-8655-C8E9C9654D2B}.Release|Win32.Build.0 = Release|Win32 + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B}.Release|x64.ActiveCfg = Release|x64 + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B}.Release|x64.Build.0 = Release|x64 {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}.Debug|Win32.ActiveCfg = Debug|Win32 {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}.Debug|Win32.Build.0 = Debug|Win32 + {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}.Debug|x64.ActiveCfg = Debug|x64 + {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}.Debug|x64.Build.0 = Debug|x64 {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}.Release|Win32.ActiveCfg = Release|Win32 {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}.Release|Win32.Build.0 = Release|Win32 + {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}.Release|x64.ActiveCfg = Release|x64 + {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA}.Release|x64.Build.0 = Release|x64 {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC}.Debug|Win32.ActiveCfg = Debug|Win32 {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC}.Debug|Win32.Build.0 = Debug|Win32 + {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC}.Debug|x64.ActiveCfg = Debug|x64 + {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC}.Debug|x64.Build.0 = Debug|x64 {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC}.Release|Win32.ActiveCfg = Release|Win32 {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC}.Release|Win32.Build.0 = Release|Win32 + {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC}.Release|x64.ActiveCfg = Release|x64 + {D28CB737-E6CA-49C4-8CE9-FF05F86DD4EC}.Release|x64.Build.0 = Release|x64 {5E8C19C6-B167-440C-8BEF-3CBF109CDB49}.Debug|Win32.ActiveCfg = Debug|Win32 {5E8C19C6-B167-440C-8BEF-3CBF109CDB49}.Debug|Win32.Build.0 = Debug|Win32 + {5E8C19C6-B167-440C-8BEF-3CBF109CDB49}.Debug|x64.ActiveCfg = Debug|x64 + {5E8C19C6-B167-440C-8BEF-3CBF109CDB49}.Debug|x64.Build.0 = Debug|x64 {5E8C19C6-B167-440C-8BEF-3CBF109CDB49}.Release|Win32.ActiveCfg = Release|Win32 {5E8C19C6-B167-440C-8BEF-3CBF109CDB49}.Release|Win32.Build.0 = Release|Win32 + {5E8C19C6-B167-440C-8BEF-3CBF109CDB49}.Release|x64.ActiveCfg = Release|x64 + {5E8C19C6-B167-440C-8BEF-3CBF109CDB49}.Release|x64.Build.0 = Release|x64 {26C749A0-814C-47A2-9D36-AE92AE932FE4}.Debug|Win32.ActiveCfg = Debug|Win32 {26C749A0-814C-47A2-9D36-AE92AE932FE4}.Debug|Win32.Build.0 = Debug|Win32 + {26C749A0-814C-47A2-9D36-AE92AE932FE4}.Debug|x64.ActiveCfg = Debug|x64 + {26C749A0-814C-47A2-9D36-AE92AE932FE4}.Debug|x64.Build.0 = Debug|x64 {26C749A0-814C-47A2-9D36-AE92AE932FE4}.Release|Win32.ActiveCfg = Release|Win32 {26C749A0-814C-47A2-9D36-AE92AE932FE4}.Release|Win32.Build.0 = Release|Win32 + {26C749A0-814C-47A2-9D36-AE92AE932FE4}.Release|x64.ActiveCfg = Release|x64 + {26C749A0-814C-47A2-9D36-AE92AE932FE4}.Release|x64.Build.0 = Release|x64 {F657912F-050A-488B-B203-50ED5715CDD7}.Debug|Win32.ActiveCfg = Debug|Win32 {F657912F-050A-488B-B203-50ED5715CDD7}.Debug|Win32.Build.0 = Debug|Win32 + {F657912F-050A-488B-B203-50ED5715CDD7}.Debug|x64.ActiveCfg = Debug|x64 + {F657912F-050A-488B-B203-50ED5715CDD7}.Debug|x64.Build.0 = Debug|x64 {F657912F-050A-488B-B203-50ED5715CDD7}.Release|Win32.ActiveCfg = Release|Win32 {F657912F-050A-488B-B203-50ED5715CDD7}.Release|Win32.Build.0 = Release|Win32 + {F657912F-050A-488B-B203-50ED5715CDD7}.Release|x64.ActiveCfg = Release|x64 + {F657912F-050A-488B-B203-50ED5715CDD7}.Release|x64.Build.0 = Release|x64 {0BCFB793-2B25-40E2-B265-75848824AC4C}.Debug|Win32.ActiveCfg = Debug|Win32 {0BCFB793-2B25-40E2-B265-75848824AC4C}.Debug|Win32.Build.0 = Debug|Win32 + {0BCFB793-2B25-40E2-B265-75848824AC4C}.Debug|x64.ActiveCfg = Debug|x64 + {0BCFB793-2B25-40E2-B265-75848824AC4C}.Debug|x64.Build.0 = Debug|x64 {0BCFB793-2B25-40E2-B265-75848824AC4C}.Release|Win32.ActiveCfg = Release|Win32 {0BCFB793-2B25-40E2-B265-75848824AC4C}.Release|Win32.Build.0 = Release|Win32 + {0BCFB793-2B25-40E2-B265-75848824AC4C}.Release|x64.ActiveCfg = Release|x64 + {0BCFB793-2B25-40E2-B265-75848824AC4C}.Release|x64.Build.0 = Release|x64 {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2}.Debug|Win32.ActiveCfg = Debug|Win32 {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2}.Debug|Win32.Build.0 = Debug|Win32 + {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2}.Debug|x64.ActiveCfg = Debug|x64 + {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2}.Debug|x64.Build.0 = Debug|x64 {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2}.Release|Win32.ActiveCfg = Release|Win32 {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2}.Release|Win32.Build.0 = Release|Win32 + {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2}.Release|x64.ActiveCfg = Release|x64 + {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2}.Release|x64.Build.0 = Release|x64 {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39}.Debug|Win32.ActiveCfg = Debug|Win32 {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39}.Debug|Win32.Build.0 = Debug|Win32 + {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39}.Debug|x64.ActiveCfg = Debug|x64 + {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39}.Debug|x64.Build.0 = Debug|x64 {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39}.Release|Win32.ActiveCfg = Release|Win32 {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39}.Release|Win32.Build.0 = Release|Win32 + {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39}.Release|x64.ActiveCfg = Release|x64 + {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39}.Release|x64.Build.0 = Release|x64 {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD}.Debug|Win32.ActiveCfg = Debug|Win32 {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD}.Debug|Win32.Build.0 = Debug|Win32 + {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD}.Debug|x64.ActiveCfg = Debug|x64 + {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD}.Debug|x64.Build.0 = Debug|x64 {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD}.Release|Win32.ActiveCfg = Release|Win32 {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD}.Release|Win32.Build.0 = Release|Win32 + {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD}.Release|x64.ActiveCfg = Release|x64 + {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD}.Release|x64.Build.0 = Release|x64 {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Debug|Win32.ActiveCfg = Debug|Win32 {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Debug|Win32.Build.0 = Debug|Win32 + {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Debug|x64.ActiveCfg = Debug|x64 + {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Debug|x64.Build.0 = Debug|x64 {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Release|Win32.ActiveCfg = Release|Win32 {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Release|Win32.Build.0 = Release|Win32 + {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Release|x64.ActiveCfg = Release|x64 + {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Release|x64.Build.0 = Release|x64 {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Debug|Win32.ActiveCfg = Debug|Win32 {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Debug|Win32.Build.0 = Debug|Win32 + {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Debug|x64.ActiveCfg = Debug|x64 + {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Debug|x64.Build.0 = Debug|x64 {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Release|Win32.ActiveCfg = Release|Win32 {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Release|Win32.Build.0 = Release|Win32 + {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Release|x64.ActiveCfg = Release|x64 + {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Release|x64.Build.0 = Release|x64 {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}.Debug|Win32.ActiveCfg = Debug|Win32 {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}.Debug|Win32.Build.0 = Debug|Win32 + {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}.Debug|x64.ActiveCfg = Debug|x64 + {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}.Debug|x64.Build.0 = Debug|x64 {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}.Release|Win32.ActiveCfg = Release|Win32 {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}.Release|Win32.Build.0 = Release|Win32 + {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}.Release|x64.ActiveCfg = Release|x64 + {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj index 9c1719538..75ee92276 100644 --- a/src/cc65.vcxproj +++ b/src/cc65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {B17EDBD5-DC04-4970-9CBD-56A98B6A3FCA} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -40,6 +55,15 @@ Console + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) @@ -48,6 +72,15 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + @@ -216,4 +249,4 @@ - + \ No newline at end of file diff --git a/src/chrcvt65.vcxproj b/src/chrcvt65.vcxproj index 1e5c753b5..d44380c4e 100644 --- a/src/chrcvt65.vcxproj +++ b/src/chrcvt65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {1C7A3FEF-DD0B-4B10-BC33-C3BE29BF67CC} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -40,6 +55,15 @@ Console + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + + + Console + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) @@ -48,6 +72,15 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + + + Console + + diff --git a/src/cl65.vcxproj b/src/cl65.vcxproj index 67b7eb087..688926557 100644 --- a/src/cl65.vcxproj +++ b/src/cl65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {F657912F-050A-488B-B203-50ED5715CDD7} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -40,6 +55,15 @@ Console + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) @@ -48,6 +72,15 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + diff --git a/src/cl65/main.c b/src/cl65/main.c index 553fb9ca6..0148ad1e3 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -1610,7 +1610,7 @@ int main (int argc, char* argv []) } /* Determine the file type by the extension */ - switch (GetFileType (Arg)) { + switch (GetTypeOfFile (Arg)) { case FILETYPE_C: /* Compile the file */ diff --git a/src/co65.vcxproj b/src/co65.vcxproj index 9f5959d89..fa6a1e315 100644 --- a/src/co65.vcxproj +++ b/src/co65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {F5DB5D1A-05BC-48FE-B346-4E96DD522AA2} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -40,6 +55,14 @@ Console + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + + + Console + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) @@ -48,6 +71,14 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + + + Console + + diff --git a/src/common.vcxproj b/src/common.vcxproj index df99fc4a9..6098c98a0 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} @@ -22,16 +30,25 @@ StaticLibrary true + + StaticLibrary + true + StaticLibrary false + + StaticLibrary + false + + @@ -39,11 +56,23 @@ _LIB;_DEBUG;%(PreprocessorDefinitions) + + + _LIB;_DEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + _LIB;NDEBUG;%(PreprocessorDefinitions) + + + _LIB;NDEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + diff --git a/src/common/filetype.c b/src/common/filetype.c index a5bac640d..ae8b636dc 100644 --- a/src/common/filetype.c +++ b/src/common/filetype.c @@ -92,8 +92,7 @@ static const FileId TypeTable[] = { /*****************************************************************************/ - -FILETYPE GetFileType (const char* Name) +FILETYPE GetTypeOfFile (const char* Name) /* Determine the type of the given file by looking at the name. If the file ** type could not be determined, the function returns FILETYPE_UNKOWN. */ diff --git a/src/common/filetype.h b/src/common/filetype.h index f4beae73a..0738078ba 100644 --- a/src/common/filetype.h +++ b/src/common/filetype.h @@ -63,7 +63,7 @@ typedef enum { -FILETYPE GetFileType (const char* Name); +FILETYPE GetTypeOfFile (const char* Name); /* Determine the type of the given file by looking at the name. If the file ** type could not be determined, the function returns FILETYPE_UNKOWN. */ diff --git a/src/da65.vcxproj b/src/da65.vcxproj index a40daf1d6..9d2b0ded6 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {0BCFB793-2B25-40E2-B265-75848824AC4C} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -40,6 +55,15 @@ Console + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) @@ -48,6 +72,15 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + diff --git a/src/grc65.vcxproj b/src/grc65.vcxproj index fbd44fa3e..742003899 100644 --- a/src/grc65.vcxproj +++ b/src/grc65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {E0FD0AB3-3BEE-496F-8108-A8E0F8933F39} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -40,6 +55,15 @@ Console + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + 4267;%(DisableSpecificWarnings) + + + Console + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) @@ -48,6 +72,15 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 4267;%(DisableSpecificWarnings) + + + Console + + diff --git a/src/ld65.vcxproj b/src/ld65.vcxproj index 9e4b08621..e2f06b198 100644 --- a/src/ld65.vcxproj +++ b/src/ld65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {26C749A0-814C-47A2-9D36-AE92AE932FE4} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -38,6 +53,19 @@ Console + ld65.map + true + + + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + ld65.map + true @@ -48,6 +76,15 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + @@ -118,4 +155,4 @@ - + \ No newline at end of file diff --git a/src/ld65/main.c b/src/ld65/main.c index 70e9c84d1..5632f4961 100644 --- a/src/ld65/main.c +++ b/src/ld65/main.c @@ -189,7 +189,7 @@ static void LinkFile (const char* Name, FILETYPE Type) /* If we don't know the file type, determine it from the extension */ if (Type == FILETYPE_UNKNOWN) { - Type = GetFileType (Name); + Type = GetTypeOfFile (Name); } /* For known file types, search the file in the directory list */ diff --git a/src/od65.vcxproj b/src/od65.vcxproj index 1a1527067..409b5038e 100644 --- a/src/od65.vcxproj +++ b/src/od65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {FF8576C2-1253-44FE-A51B-D9AE35F3CEAD} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -40,6 +55,15 @@ Console + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) @@ -48,6 +72,15 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 97fc3855a..7bc489398 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {002A366E-2863-46A8-BDDE-DDF534AAEC73} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -40,6 +55,15 @@ Console + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + 4267;%(DisableSpecificWarnings) + + + Console + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) @@ -48,6 +72,15 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 4267;%(DisableSpecificWarnings) + + + Console + + diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index a9f0919a3..21816ee2b 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF} @@ -21,15 +29,22 @@ true + + true + false + + false + + @@ -40,6 +55,15 @@ Console + + + _CONSOLE;_DEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) @@ -48,6 +72,15 @@ Console + + + _CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 4244;4267;%(DisableSpecificWarnings) + + + Console + + @@ -99,4 +132,4 @@ - + \ No newline at end of file From 269786a5aeefc7171dfd22662a26513443b98817 Mon Sep 17 00:00:00 2001 From: paul moore Date: Thu, 14 Dec 2023 14:38:24 -0800 Subject: [PATCH 051/707] fix msbuild syntax --- .github/workflows/build-on-pull-request.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 55ee3df2d..f1dd58ee5 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -68,15 +68,15 @@ jobs: uses: microsoft/setup-msbuild@v1.1 - name: Build app (x86 debug) - run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug Platform=Win32 + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug -Platform=Win32 - name: Build app (x86 release) - run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release Platform=Win32 + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release -Platform=Win32 - name: Build app (x64 release) - run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug Platform=x64 + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug -Platform=x64 - name: Build app (x64 release) - run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release Platform=x64 + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release -Platform=x64 From 103d4b82c5889ae3acf34c6b281f3f9879d853d4 Mon Sep 17 00:00:00 2001 From: paul moore Date: Thu, 14 Dec 2023 14:43:58 -0800 Subject: [PATCH 052/707] more msbuild syntax fixes --- .github/workflows/build-on-pull-request.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index f1dd58ee5..045bc048d 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -68,15 +68,15 @@ jobs: uses: microsoft/setup-msbuild@v1.1 - name: Build app (x86 debug) - run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug -Platform=Win32 + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug -property:Platform=Win32 - name: Build app (x86 release) - run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release -Platform=Win32 + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release -property:Platform=Win32 - name: Build app (x64 release) - run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug -Platform=x64 + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug -property:Platform=x64 - name: Build app (x64 release) - run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release -Platform=x64 + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release -property:Platform=x64 From 0d74b84ce4c484f0ef4a23326c4327d05ac4358a Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Sat, 16 Dec 2023 19:18:25 -0500 Subject: [PATCH 053/707] Test of .struct and .union features. Update documentation with more examples, better clarity, and fixes to incorrect data. --- doc/ca65.sgml | 76 ++++++++++++--- test/asm/val/struct.s | 222 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 286 insertions(+), 12 deletions(-) create mode 100644 test/asm/val/struct.s diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 104c59bbd..e54b308d4 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4086,8 +4086,10 @@ See: ,.TAG

- Allocate space for a struct or union. - + Allocate space for a struct or union. This is equivalent to + with the + of a struct. + Example: @@ -4100,6 +4102,7 @@ See: , + See: .UNDEF, .UNDEFINE

@@ -4865,10 +4868,15 @@ compiler, depending on the target system selected: Structs and unions are special forms of . They are, to some degree, comparable to their C counterparts. Both have a list of -members. Each member allocates storage, and optionally may have a name whose -value, in the case of a struct, usually is the storage offset from the -beginning, and in the case of a union, doesn't change, and usually is zero. +members. Each member allocates storage, and optionally may have a name. +Each named member has a constant value equal to the storage offset from the +beginning of the structure. In the case of a union, all members are placed at +the same offset, typically 0. + +Each named member also has a storage size which can be accessed with the + operator. The struct or union itself also +has a Declaration

@@ -4895,8 +4903,9 @@ A struct or union may not necessarily have a name. If it is anonymous, no local scope is opened; the identifiers used to name the members are placed into the current scope instead. -A struct may contain unnamed members and definitions of local structs/unions. -The storage allocators may contain a multiplier, as in the example below: +Storage allocators may contain a multiplier. A struct may also contain members +and definitions of local structs/unions. Example: + .struct Circle .struct Point @@ -4905,7 +4914,8 @@ The storage allocators may contain a multiplier, as in the example below: Radius .word .endstruct -The size of the Circle struct is 6 (three words). + +In this example the size of the Circle struct is 6 (three words). The storage allocator keywords

@@ -4915,7 +4925,7 @@ The size of the Circle struct is 6 (three words). @@ -4968,13 +4987,46 @@ name=".TAG"> directive. C: .tag Circle -Currently, members are just offsets from the start of the struct or union. To +Members are just offsets from the start of the struct or union. To access a field of a struct, the member offset must be added to the address of the struct variable itself: - lda C+Circle::Radius ; Load circle radius into A + lda C + Circle::Radius ; Load circle radius + lda C + Circle::Origin + Point::ycoord ; Load circle origin.ycoord -That may change in a future version of the assembler. + +Nested structures or unions are treated differently depending on whether they +are anonymous. If named, a new structure definition is created within the +enclosing scope, with its offsets beginning at 0. If anonymous, the members of +the new structure are added to the enclosing scope instead. Example: + + + .struct Object + member .byte ; Object::member = 0 + named .struct Point ; Object::named = 1 + xcoord .word ; Object::Point::xcoord = 0 + ycoord .word ; Object::Point::ycoord = 2 + .endstruct + unnamed .struct ; Object::unnamed = 5 + un1 .word ; Object::un1 = 5 + un2 .word ; Object::un2 = 7 + .endstruct + .struct + un3 .word ; Object::un3 = 9 + .endstruct + .endstruct + + lda O + Object::named + Object::Point::ycoord + lda O + Object::un2 + + +In this example, the first nested structure is named "Point", and its member +offsets begin at 0. On the other hand, the two anonymous structures simply +continue to add members to the enclosing Object structure. + +Note that an anonymous structure does not need a member name, since all of its +members become part of the enclosing structure. The "unnamed" member in the +example is redundantly the same offset as its first member "un1. Limitations

diff --git a/test/asm/val/struct.s b/test/asm/val/struct.s new file mode 100644 index 000000000..b2bf08ea0 --- /dev/null +++ b/test/asm/val/struct.s @@ -0,0 +1,222 @@ +; test .struct feature + +.code + +; exit with 0 +.export _main +_main: + lda #0 + tax + rts + +; test storage allocator sizes and offsets + +.struct Storage + mb1 .byte + mb5 .byte 5 + mr1 .res 1 + mr5 .res 5 + mdb1 .dbyt + mdb5 .dbyt 5 + mw1 .word + mw5 .word 5 + ma1 .addr + ma5 .addr 5 + mf1 .faraddr + mf5 .faraddr 5 + mdw1 .dword + mdw5 .dword 5 +.endstruct + +.assert .sizeof(Storage::mb1) = 1, error, ".struct .byte member has unexpected .sizeof" +.assert .sizeof(Storage::mb5) = 5, error, ".struct .byte 5 member has unexpected .sizeof" +.assert .sizeof(Storage::mr1) = 1, error, ".struct .res 1 member has unexpected .sizeof" +.assert .sizeof(Storage::mr5) = 5, error, ".struct .res 5 member has unexpected .sizeof" +.assert .sizeof(Storage::mdb1) = 2, error, ".struct .dbyt member has unexpected .sizeof" +.assert .sizeof(Storage::mdb5) = 10, error, ".struct .dbyt 5 member has unexpected .sizeof" +.assert .sizeof(Storage::mw1) = 2, error, ".struct .word member has unexpected .sizeof" +.assert .sizeof(Storage::mw5) = 10, error, ".struct .word 5 member has unexpected .sizeof" +.assert .sizeof(Storage::ma1) = 2, error, ".struct .addr member has unexpected .sizeof" +.assert .sizeof(Storage::ma5) = 10, error, ".struct .addr 5 member has unexpected .sizeof" +.assert .sizeof(Storage::mf1) = 3, error, ".struct .faraddr member has unexpected .sizeof" +.assert .sizeof(Storage::mf5) = 15, error, ".struct .faraddr 5 member has unexpected .sizeof" +.assert .sizeof(Storage::mdw1) = 4, error, ".struct .dword member has unexpected .sizeof" +.assert .sizeof(Storage::mdw5) = 20, error, ".struct .dword 5 member has unexpected .sizeof" + +.assert Storage::mb1 = 0, error, ".struct storage offset is incorrect" +.assert Storage::mb5 = Storage::mb1 + .sizeof(Storage::mb1), error, ".struct storage offset is incorrect" +.assert Storage::mr1 = Storage::mb5 + .sizeof(Storage::mb5), error, ".struct storage offset is incorrect" +.assert Storage::mr5 = Storage::mr1 + .sizeof(Storage::mr1), error, ".struct storage offset is incorrect" +.assert Storage::mdb1 = Storage::mr5 + .sizeof(Storage::mr5), error, ".struct storage offset is incorrect" +.assert Storage::mdb5 = Storage::mdb1 + .sizeof(Storage::mdb1), error, ".struct storage offset is incorrect" +.assert Storage::mw1 = Storage::mdb5 + .sizeof(Storage::mdb5), error, ".struct storage offset is incorrect" +.assert Storage::mw5 = Storage::mw1 + .sizeof(Storage::mw1), error, ".struct storage offset is incorrect" +.assert Storage::ma1 = Storage::mw5 + .sizeof(Storage::mw5), error, ".struct storage offset is incorrect" +.assert Storage::ma5 = Storage::ma1 + .sizeof(Storage::ma1), error, ".struct storage offset is incorrect" +.assert Storage::mf1 = Storage::ma5 + .sizeof(Storage::ma5), error, ".struct storage offset is incorrect" +.assert Storage::mf5 = Storage::mf1 + .sizeof(Storage::mf1), error, ".struct storage offset is incorrect" +.assert Storage::mdw1 = Storage::mf5 + .sizeof(Storage::mf5), error, ".struct storage offset is incorrect" +.assert Storage::mdw5 = Storage::mdw1 + .sizeof(Storage::mdw1), error, ".struct storage offset is incorrect" +.assert .sizeof(Storage) = Storage::mdw5 + .sizeof(Storage::mdw5), error, ".struct has unexpected .sizeof" + +; test union offset and size + +.union UStorage + mb1 .byte + mb5 .byte 5 + mr1 .res 1 + mr5 .res 5 + mdb1 .dbyt + mdb5 .dbyt 5 + mw1 .word + mw5 .word 5 + ma1 .addr + ma5 .addr 5 + mf1 .faraddr + mf5 .faraddr 5 + mdw1 .dword + mdw5 .dword 5 +.endunion + +.assert .sizeof(UStorage::mb1) = 1, error, ".union .byte member has unexpected .sizeof" +.assert .sizeof(UStorage::mb5) = 5, error, ".union .byte 5 member has unexpected .sizeof" +.assert .sizeof(UStorage::mr1) = 1, error, ".union .res 1 member has unexpected .sizeof" +.assert .sizeof(UStorage::mr5) = 5, error, ".union .res 5 member has unexpected .sizeof" +.assert .sizeof(UStorage::mdb1) = 2, error, ".union .dbyt member has unexpected .sizeof" +.assert .sizeof(UStorage::mdb5) = 10, error, ".union .dbyt 5 member has unexpected .sizeof" +.assert .sizeof(UStorage::mw1) = 2, error, ".union .word member has unexpected .sizeof" +.assert .sizeof(UStorage::mw5) = 10, error, ".union .word 5 member has unexpected .sizeof" +.assert .sizeof(UStorage::ma1) = 2, error, ".union .addr member has unexpected .sizeof" +.assert .sizeof(UStorage::ma5) = 10, error, ".union .addr 5 member has unexpected .sizeof" +.assert .sizeof(UStorage::mf1) = 3, error, ".union .faraddr member has unexpected .sizeof" +.assert .sizeof(UStorage::mf5) = 15, error, ".union .faraddr 5 member has unexpected .sizeof" +.assert .sizeof(UStorage::mdw1) = 4, error, ".union .dword member has unexpected .sizeof" +.assert .sizeof(UStorage::mdw5) = 20, error, ".union .dword 5 member has unexpected .sizeof" +.assert .sizeof(UStorage) = 20, error, ".union has unexpected .sizeof" + +.assert UStorage::mb1 = 0, error, ".union storage offset is incorrect" +.assert UStorage::mb5 = 0, error, ".union storage offset is incorrect" +.assert UStorage::mr1 = 0, error, ".union storage offset is incorrect" +.assert UStorage::mr5 = 0, error, ".union storage offset is incorrect" +.assert UStorage::mdb1 = 0, error, ".union storage offset is incorrect" +.assert UStorage::mdb5 = 0, error, ".union storage offset is incorrect" +.assert UStorage::mw1 = 0, error, ".union storage offset is incorrect" +.assert UStorage::mw5 = 0, error, ".union storage offset is incorrect" +.assert UStorage::ma1 = 0, error, ".union storage offset is incorrect" +.assert UStorage::ma5 = 0, error, ".union storage offset is incorrect" +.assert UStorage::mf1 = 0, error, ".union storage offset is incorrect" +.assert UStorage::mf5 = 0, error, ".union storage offset is incorrect" +.assert UStorage::mdw1 = 0, error, ".union storage offset is incorrect" +.assert UStorage::mdw5 = 0, error, ".union storage offset is incorrect" + +; test tag + +storage: .tag Storage +.assert (*-storage)=.sizeof(Storage), error, ".tag reserved size incorrect" + +; test nested structures + +.struct Point + xc .word + yc .word +.endstruct + +.struct Nested + pad .res 13 + tag .tag Point + ch .struct Child + ca .word ; offset = 0 + gch .struct Grandchild + gca .word ; offset = 0 + gcb .byte + .endstruct + cb .byte + .endstruct + anon .struct + aa .dword ; offset = Nested::anon (anonymous .struct) + ab .dword + .endstruct + chu .union Chunion + ua .byte ; offset = 0 + ub .dword + .endunion + chanon .union + uc .byte ; offset = Nested::chanon + ud .dword + .endunion + last .byte +.endstruct + +.assert Nested::pad = 0, error, "Nested .struct has unexpected starting offset" +.assert Nested::Child::ca = 0, error, "Nested .struct has unexpected starting offset" +.assert Nested::Child::Grandchild::gca = 0, error, "Nested .struct has unexpected starting offset" + +.assert .sizeof(Nested::tag) = .sizeof(Point), error, ".tag in .struct has unexpected .sizeof" +.assert .sizeof(Nested::Child::Grandchild) = 2 + 1, error, "Nested .struct has unexpected .sizeof" +.assert .sizeof(Nested::Child) = 2 + 1 + .sizeof(Nested::Child::Grandchild), error, "Nested .struct has unpexpected .sizeof" +.assert .sizeof(Nested::ch) = .sizeof(Nested::Child), error, "Nested .struct has unexpected member .sizeof" +.assert .sizeof(Nested::Child::gch) = .sizeof(Nested::Child::Grandchild), error, "Nested .struct has unexpected member .sizeof" +.assert .sizeof(Nested::anon) = 8, error, "Nested anonymous member .struct has unexpected .sizeof" +.assert .sizeof(Nested::aa) = 4, error, "Nested anonymous .struct member has unexpected .sizeof" +.assert .sizeof(Nested::ab) = 4, error, "Nested anonymous .struct member has unexpected .sizeof" +.assert .sizeof(Nested::Chunion) = 4, error, "Nested .union has unexpected .sizeof" +.assert .sizeof(Nested::chu) = .sizeof(Nested::Chunion), error, "Nested member .union has unexpected .sizeof" +.assert .sizeof(Nested::chanon) = 4, error, "Nested anonymous member .union as unexpected .sizeof" + +.assert Nested::tag = Nested::pad + .sizeof(Nested::pad), error, ".tag within .struct has unexpected offset" +.assert Nested::ch = Nested::tag + .sizeof(Nested::tag), error, "Nested .struct has unexpected offset" +.assert Nested::anon = Nested::ch + .sizeof(Nested::ch), error, "Nested anonymous member .struct has unexpected offset" +.assert Nested::aa = Nested::anon, error, "Nested anonymous .struct member has unexpected offset" +.assert Nested::ab = Nested::aa + .sizeof(Nested::aa), error, "Nested anonymous .struct member has unexpected offset" +.assert Nested::chu = Nested::ab + .sizeof(Nested::ab), error, "Nested member .union has unexpected offset" +.assert Nested::chanon = Nested::chu + .sizeof(Nested::Chunion), error, "Nested anonymous member .union has unexpected offset" +.assert Nested::uc = Nested::chanon, error, "Nested anonymous .union member has unexpected offset" +.assert Nested::ud = Nested::chanon, error, "Nested anonymous .union member has unexpected offset" +.assert Nested::last = Nested::ud + .sizeof(Nested::ud), error, ".struct member has unexpected offset after anonymous nested .struct" + +; test .org + +start: + +.struct OrgStruct + ma .byte + mb .byte + .org $1234 + mc .byte + md .byte + .struct Nested + me .byte + .org $5678 + mf .byte + mg .byte + .endstruct + mh .byte +.endstruct + +.assert start <> (OrgStruct::mh+1), error, "Fatal test error: accidental code position conflict, move OrgStruct .org to another arbitrary address." +.assert * = start, error, ".org within .struct does not return to previous location at .endstruct" +.assert OrgStruct::ma = 0, error, ".struct with .org has unexpected offset" +.assert OrgStruct::mb = 1, error, ".struct with .org has unexpected offset" +.assert OrgStruct::mc = $1234, error, ".struct with .org has unexpected offset" +.assert OrgStruct::md = $1235, error, ".struct with .org has unexpected offset" +.assert OrgStruct::Nested::me = 0, error, "Nested .struct with .org has unexpected offset" +.assert OrgStruct::Nested::mf = $5678, error, "Nested .struct with .org has unexpected offset" +.assert OrgStruct::Nested::mg = $5679, error, "Nested .struct with .org has unexpected offset" +.assert OrgStruct::mh = $1239, error, ".struct with .org has unexpected offset" +.assert .sizeof(OrgStruct) = 8, error, ".struct with .org has unexpected .sizeof" + +.union OrgUnion + ma .byte + mb .word + .org $1234 + mc .byte + md .word +.endunion + +.assert start <> OrgUnion::md, error, "Fatal test error: accidental code position conflict, move OrgUnion .org to another arbitrary address." +.assert * = start, error, ".org within .union does not return to previous location at .endunion" +.assert OrgUnion::ma = 0, error, ".union with .org has unexpected offset" +.assert OrgUnion::mb = 0, error, ".union with .org has unexpected offset" +.assert OrgUnion::mc = $1234, error, ".union with .org has unexpected offset" +.assert OrgUnion::md = $1234, error, ".union with .org has unexpected offset" +.assert .sizeof(OrgUnion) = 2, error, ".union with .org has unexpected .sizeof" From 6cb8717c24d415448f451edbe3f949e9188fe1c1 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Sat, 16 Dec 2023 19:25:21 -0500 Subject: [PATCH 054/707] fix dangling space, mention .union in test comment --- doc/ca65.sgml | 2 +- test/asm/val/struct.s | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index e54b308d4..dde782a57 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4089,7 +4089,7 @@ See: , with the of a struct. - + Example: diff --git a/test/asm/val/struct.s b/test/asm/val/struct.s index b2bf08ea0..b6ef6f45d 100644 --- a/test/asm/val/struct.s +++ b/test/asm/val/struct.s @@ -1,4 +1,4 @@ -; test .struct feature +; test .struct and .union features .code From f6838be1621f4ef57c1224209c50e41ee0bcfe4d Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Sat, 16 Dec 2023 19:32:52 -0500 Subject: [PATCH 055/707] missing --- doc/ca65.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index dde782a57..9be63d035 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4875,8 +4875,8 @@ beginning of the structure. In the case of a union, all members are placed at the same offset, typically 0. Each named member also has a storage size which can be accessed with the - operator. The struct or union itself also -has a operator. The struct or union itself +also has a Declaration

From 0ff1b20f2a2420bbff8e162c54e52fa24561de3e Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Sat, 16 Dec 2023 19:52:57 -0500 Subject: [PATCH 056/707] nested struct example needs a .tag --- doc/ca65.sgml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 9be63d035..3d4899366 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -5016,6 +5016,7 @@ the new structure are added to the enclosing scope instead. Example: .endstruct .endstruct +O: .tag Object lda O + Object::named + Object::Point::ycoord lda O + Object::un2 From 302c4f7409b898ea5c1d63009b883e5887c2ea78 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Sun, 17 Dec 2023 05:01:06 -0500 Subject: [PATCH 057/707] clarify offsets of anonymous nested scope, missing quotes for names --- doc/ca65.sgml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 3d4899366..3120d9dd4 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4998,7 +4998,8 @@ the struct variable itself: Nested structures or unions are treated differently depending on whether they are anonymous. If named, a new structure definition is created within the enclosing scope, with its offsets beginning at 0. If anonymous, the members of -the new structure are added to the enclosing scope instead. Example: +the new structure are added to the enclosing scope instead, with offsets +continuing through that scope. Example: .struct Object @@ -5023,11 +5024,11 @@ O: .tag Object In this example, the first nested structure is named "Point", and its member offsets begin at 0. On the other hand, the two anonymous structures simply -continue to add members to the enclosing Object structure. +continue to add members to the enclosing "Object" structure. Note that an anonymous structure does not need a member name, since all of its members become part of the enclosing structure. The "unnamed" member in the -example is redundantly the same offset as its first member "un1. +example is redundantly the same offset as its first member "un1". Limitations

From 9892c8f6c45f3ad61c49ce78d22881161d21dbab Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Sun, 17 Dec 2023 05:40:00 -0500 Subject: [PATCH 058/707] using less generic names for the example to avoid confusion, adding cautionary example for what I think is the most error prone case --- doc/ca65.sgml | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 3120d9dd4..c5c6893da 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -5003,23 +5003,29 @@ continuing through that scope. Example: .struct Object - member .byte ; Object::member = 0 - named .struct Point ; Object::named = 1 + id .byte ; Object::id = 0 + target .struct Point ; Object::target = 1 xcoord .word ; Object::Point::xcoord = 0 ycoord .word ; Object::Point::ycoord = 2 .endstruct - unnamed .struct ; Object::unnamed = 5 - un1 .word ; Object::un1 = 5 - un2 .word ; Object::un2 = 7 + cost .struct ; Object::cost = 5 + price .word ; Object::price = 5 + tax .word ; Object::tax = 7 .endstruct .struct - un3 .word ; Object::un3 = 9 + radius .word ; Object::radius = 9 .endstruct .endstruct O: .tag Object - lda O + Object::named + Object::Point::ycoord - lda O + Object::un2 + lda O + Object::target + Object::Point::ycoord ; Named struct + lda O + Object::tax ; Anonymous + lda O + Object::radius ; Anonymous + + ; Be careful not to use a named nested structure without also adding the + ; offset to the nested structure itself. + lda O + Object::Point::ycoord ; Incorrect! + lda O + Object::target + Object::Point::ycoord ; Correct In this example, the first nested structure is named "Point", and its member @@ -5027,8 +5033,8 @@ offsets begin at 0. On the other hand, the two anonymous structures simply continue to add members to the enclosing "Object" structure. Note that an anonymous structure does not need a member name, since all of its -members become part of the enclosing structure. The "unnamed" member in the -example is redundantly the same offset as its first member "un1". +members become part of the enclosing structure. The "cost" member in the +example is redundantly the same offset as its first member "price". Limitations

From cd7c688dff5b0dfed2dec0fde9f2f24cd1b73ae9 Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 18 Dec 2023 15:30:53 +0800 Subject: [PATCH 059/707] Separated C preprocessor errors from other errors. --- src/cc65/error.c | 67 +++++++++++++++++------- src/cc65/error.h | 25 +++++++-- test/ref/Makefile | 3 +- test/ref/bug2312-preprocessor-error.c | 8 +++ test/ref/bug2312-preprocessor-error.cref | 2 + test/ref/custom-reference-error.c | 5 +- test/ref/custom-reference-error.cref | 11 ++-- 7 files changed, 91 insertions(+), 30 deletions(-) create mode 100644 test/ref/bug2312-preprocessor-error.c create mode 100644 test/ref/bug2312-preprocessor-error.cref diff --git a/src/cc65/error.c b/src/cc65/error.c index 2ad7133ed..5cd29b388 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -59,8 +59,10 @@ /* Count of errors/warnings */ -unsigned ErrorCount = 0; -unsigned WarningCount = 0; +unsigned PPErrorCount = 0; /* Pre-parser errors */ +unsigned PPWarningCount = 0; /* Pre-parser warnings */ +unsigned ErrorCount = 0; /* Errors occurred in parser and later translation phases */ +unsigned WarningCount = 0; /* Warnings occurred in parser and later translation phases */ unsigned RecentLineNo = 0; unsigned RecentErrorCount = 0; @@ -197,7 +199,7 @@ void Internal (const char* Format, ...) -static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va_list ap) +static void IntError (errcat_t EC, const char* Filename, unsigned LineNo, const char* Msg, va_list ap) /* Print an error message - internal function */ { fprintf (stderr, "%s:%u: Error: ", Filename, LineNo); @@ -208,7 +210,11 @@ static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line)); } - ++ErrorCount; + if (EC != EC_PP) { + ++ErrorCount; + } else { + ++PPErrorCount; + } if (RecentLineNo != LineNo) { RecentLineNo = LineNo; RecentErrorCount = 0; @@ -216,7 +222,7 @@ static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va ++RecentErrorCount; } - if (RecentErrorCount > 20 || ErrorCount > 200) { + if (RecentErrorCount > 20 || GetTotalErrors () > 200) { Fatal ("Too many errors"); } } @@ -228,18 +234,18 @@ void Error (const char* Format, ...) { va_list ap; va_start (ap, Format); - IntError (GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap); + IntError (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap); va_end (ap); } -void LIError (const LineInfo* LI, const char* Format, ...) +void LIError (errcat_t EC, const LineInfo* LI, const char* Format, ...) /* Print an error message with the line info given explicitly */ { va_list ap; va_start (ap, Format); - IntError (GetInputName (LI), GetInputLine (LI), Format, ap); + IntError (EC, GetInputName (LI), GetInputLine (LI), Format, ap); va_end (ap); } @@ -250,7 +256,7 @@ void PPError (const char* Format, ...) { va_list ap; va_start (ap, Format); - IntError (GetCurrentFilename(), GetCurrentLineNum(), Format, ap); + IntError (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap); va_end (ap); } @@ -262,13 +268,13 @@ void PPError (const char* Format, ...) -static void IntWarning (const char* Filename, unsigned LineNo, const char* Msg, va_list ap) +static void IntWarning (errcat_t EC, const char* Filename, unsigned LineNo, const char* Msg, va_list ap) /* Print a warning message - internal function */ { if (IS_Get (&WarningsAreErrors)) { /* Treat the warning as an error */ - IntError (Filename, LineNo, Msg, ap); + IntError (EC, Filename, LineNo, Msg, ap); } else if (IS_Get (&WarnEnable)) { @@ -279,7 +285,12 @@ static void IntWarning (const char* Filename, unsigned LineNo, const char* Msg, if (Line) { Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line)); } - ++WarningCount; + + if (EC != EC_PP) { + ++WarningCount; + } else { + ++PPWarningCount; + } } } @@ -291,18 +302,18 @@ void Warning (const char* Format, ...) { va_list ap; va_start (ap, Format); - IntWarning (GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap); + IntWarning (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap); va_end (ap); } -void LIWarning (const LineInfo* LI, const char* Format, ...) +void LIWarning (errcat_t EC, const LineInfo* LI, const char* Format, ...) /* Print a warning message with the line info given explicitly */ { va_list ap; va_start (ap, Format); - IntWarning (GetInputName (LI), GetInputLine (LI), Format, ap); + IntWarning (EC, GetInputName (LI), GetInputLine (LI), Format, ap); va_end (ap); } @@ -313,7 +324,7 @@ void PPWarning (const char* Format, ...) { va_list ap; va_start (ap, Format); - IntWarning (GetCurrentFilename(), GetCurrentLineNum(), Format, ap); + IntWarning (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap); va_end (ap); } @@ -398,16 +409,34 @@ void PPNote (const char* Format, ...) /*****************************************************************************/ -/* Code */ +/* Error summary */ /*****************************************************************************/ +unsigned GetTotalErrors (void) +/* Get total count of errors of all categories */ +{ + return PPErrorCount + ErrorCount; +} + + + +unsigned GetTotalWarnings (void) +/* Get total count of warnings of all categories */ +{ + return PPWarningCount + WarningCount; +} + + + void ErrorReport (void) /* Report errors (called at end of compile) */ { - unsigned int V = (ErrorCount != 0 ? 0 : 1); - Print (stdout, V, "%u errors and %u warnings generated.\n", ErrorCount, WarningCount); + unsigned TotalErrors = GetTotalErrors (); + unsigned TotalWarnings = GetTotalWarnings (); + unsigned int V = (TotalErrors != 0 ? 0 : 1); + Print (stdout, V, "%u errors and %u warnings generated.\n", TotalErrors, TotalWarnings); } diff --git a/src/cc65/error.h b/src/cc65/error.h index 83be8c782..4dce6cf91 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -55,9 +55,20 @@ +/* Error categories */ +typedef enum errcat_t errcat_t; +enum errcat_t { + EC_PP, /* Pre-parser phases */ + EC_PARSER, /* Parser and later phases */ +}; + + + /* Count of errors/warnings */ -extern unsigned ErrorCount; -extern unsigned WarningCount; +extern unsigned PPErrorCount; /* Pre-parser errors */ +extern unsigned PPWarningCount; /* Pre-parser warnings */ +extern unsigned ErrorCount; /* Errors occurred in parser and later translation phases */ +extern unsigned WarningCount; /* Warnings occurred in parser and later translation phases */ /* Warning and error options */ extern IntStack WarnEnable; /* Enable warnings */ @@ -98,7 +109,7 @@ void Internal (const char* Format, ...) attribute ((noreturn, format (printf, 1, void Error (const char* Format, ...) attribute ((format (printf, 1, 2))); /* Print an error message */ -void LIError (const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 2, 3))); +void LIError (errcat_t EC, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4))); /* Print an error message with the line info given explicitly */ void PPError (const char* Format, ...) attribute ((format (printf, 1, 2))); @@ -107,7 +118,7 @@ void PPError (const char* Format, ...) attribute ((format (printf, 1, 2))); void Warning (const char* Format, ...) attribute ((format (printf, 1, 2))); /* Print a warning message */ -void LIWarning (const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 2, 3))); +void LIWarning (errcat_t EC, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4))); /* Print a warning message with the line info given explicitly */ void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2))); @@ -130,6 +141,12 @@ void LINote (const LineInfo* LI, const char* Format, ...) attribute ((format (pr void PPNote (const char* Format, ...) attribute ((format (printf, 1, 2))); /* Print a note message. For use within the preprocessor */ +unsigned GetTotalErrors (void); +/* Get total count of errors of all categories */ + +unsigned GetTotalWarnings (void); +/* Get total count of warnings of all categories */ + void ErrorReport (void); /* Report errors (called at end of compile) */ diff --git a/test/ref/Makefile b/test/ref/Makefile index 9538fdee7..9ecb33c00 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -63,7 +63,8 @@ CUSTOMSOURCES = \ # exact error output is required ERRORSOURCES = \ custom-reference-error.c \ - bug1889-missing-identifier.c + bug1889-missing-identifier.c \ + bug2312-preprocessor-error.c SOURCES := $(filter-out $(CUSTOMSOURCES) $(ERRORSOURCES),$(wildcard *.c)) diff --git a/test/ref/bug2312-preprocessor-error.c b/test/ref/bug2312-preprocessor-error.c new file mode 100644 index 000000000..b7872f514 --- /dev/null +++ b/test/ref/bug2312-preprocessor-error.c @@ -0,0 +1,8 @@ +/* Bug #2312 - Error recovery from preprocessor errors at the end of a declaration */ + +typedef int A; /* ';' consumption triggers PP below */ + +#define /* PP error during ';' consumption */ + +A f(void); /* Should be OK */ +int A(void); /* Should be an error */ diff --git a/test/ref/bug2312-preprocessor-error.cref b/test/ref/bug2312-preprocessor-error.cref new file mode 100644 index 000000000..680950fd6 --- /dev/null +++ b/test/ref/bug2312-preprocessor-error.cref @@ -0,0 +1,2 @@ +bug2312-preprocessor-error.c:5: Error: Missing macro name +bug2312-preprocessor-error.c:8: Error: Redefinition of typedef 'A' as different kind of symbol diff --git a/test/ref/custom-reference-error.c b/test/ref/custom-reference-error.c index 857145fc0..a7c1b6c56 100644 --- a/test/ref/custom-reference-error.c +++ b/test/ref/custom-reference-error.c @@ -13,7 +13,10 @@ and then "make" again to confirm */ -short main(int argc, char* argv[]) +typedef short return_t; +#error /* produce an error */ + +return_t main(int argc, char* argv[]) { printf("%02x", 0x42); /* produce an error */ n = 0; /* produce an error */ diff --git a/test/ref/custom-reference-error.cref b/test/ref/custom-reference-error.cref index 728cc0e15..b21c72dce 100644 --- a/test/ref/custom-reference-error.cref +++ b/test/ref/custom-reference-error.cref @@ -1,5 +1,6 @@ -custom-reference-error.c:18: Error: Call to undeclared function 'printf' -custom-reference-error.c:19: Error: Undeclared identifier 'n' -custom-reference-error.c:21: Warning: Control reaches end of non-void function [-Wreturn-type] -custom-reference-error.c:21: Warning: Parameter 'argc' is never used -custom-reference-error.c:21: Warning: Parameter 'argv' is never used +custom-reference-error.c:17: Error: #error +custom-reference-error.c:21: Error: Call to undeclared function 'printf' +custom-reference-error.c:22: Error: Undeclared identifier 'n' +custom-reference-error.c:24: Warning: Control reaches end of non-void function [-Wreturn-type] +custom-reference-error.c:24: Warning: Parameter 'argc' is never used +custom-reference-error.c:24: Warning: Parameter 'argv' is never used From b876a6b213eb4fb8d821f4dba77079a3e7cb8917 Mon Sep 17 00:00:00 2001 From: acqn Date: Tue, 19 Dec 2023 19:30:50 +0800 Subject: [PATCH 060/707] Fixed cc65 exitcode when there are only preprocessor errors. --- src/cc65/main.c | 4 ++-- test/err/bug2312-pperror-only.c | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 test/err/bug2312-pperror-only.c diff --git a/src/cc65/main.c b/src/cc65/main.c index bef646cdd..7dc5417f6 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -1089,7 +1089,7 @@ int main (int argc, char* argv[]) Compile (InputFile); /* Create the output file if we didn't had any errors */ - if (PreprocessOnly == 0 && (ErrorCount == 0 || Debug)) { + if (PreprocessOnly == 0 && (GetTotalErrors () == 0 || Debug)) { /* Emit literals, do cleanup and optimizations */ FinishCompile (); @@ -1115,5 +1115,5 @@ int main (int argc, char* argv[]) DoneSegAddrSizes (); /* Return an apropriate exit code */ - return (ErrorCount > 0)? EXIT_FAILURE : EXIT_SUCCESS; + return (GetTotalErrors () > 0)? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/test/err/bug2312-pperror-only.c b/test/err/bug2312-pperror-only.c new file mode 100644 index 000000000..bdec33956 --- /dev/null +++ b/test/err/bug2312-pperror-only.c @@ -0,0 +1,8 @@ +/* Bug #2312 */ + +#error "Compiler should exit with failure" + +int main(void) +{ + return 0; +} From e5f9def572ae7f203ddee540f58b5e04e93567f9 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Fri, 29 Dec 2023 22:37:18 +0100 Subject: [PATCH 061/707] Added SPRCTL0 and SPRCTL1 bit definitions for ca65 --- asminc/lynx.inc | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index 403d15d07..a24044713 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -81,8 +81,42 @@ MATHJ = $FC6F ; Suzy Misc -SPRCTL0 = $FC80 -SPRCTL1 = $FC81 +SPRCTL0 = $FC80 +; Sprite bits-per-pixel definitions +BPP_MASK = %11000000 ; Mask for settings bits per pixel +BPP_1 = %00000000 +BPP_2 = %01000000 +BPP_3 = %10000000 +BPP_4 = %11000000 +; More sprite control 0 bit definitions +HFLIP = %00100000 +VFLIP = %00010000 +; Sprite types - redefined to reflect the reality caused by the shadow error +TYPE_SHADOW = %00000111 +TYPE_XOR = %00000110 +TYPE_NONCOLL = %00000101 ; Non-colliding +TYPE_NORMAL = %00000100 +TYPE_BOUNDARY = %00000011 +TYPE_BSHADOW = %00000010 ; Background shadow +TYPE_BACKNONCOLL = %00000001 ; Background non-colliding +TYPE_BACKGROUND = %00000000 + +SPRCTL1 = $FC81 +LITERAL = %10000000 +PACKED = %00000000 +ALGO3 = %01000000 ; Broken, do not set this bit! +; Sprite reload mask definitions +RELOAD_MASK = %00110000 +RENONE = %00000000 ; Reload nothing +REHV = %00010000 ; Reload hsize, vsize +REHVS = %00100000 ; Reload hsize, vsize, stretch +REHVST = %00110000 ; Reload hsize, vsize, stretch, tilt +; More sprite control 1 bit definitions +REUSEPAL = %00001000 +SKIP = %00000100 +DRAWUP = %00000010 +DRAWLEFT = %00000001 + SPRCOLL = $FC82 SPRINIT = $FC83 SUZYHREV = $FC88 From 061d907a11599cf3ad565ffbc155ce0e93156a72 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Fri, 29 Dec 2023 22:46:15 +0100 Subject: [PATCH 062/707] Fixed tabs instead of spaces --- asminc/lynx.inc | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index a24044713..198af415b 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -81,41 +81,41 @@ MATHJ = $FC6F ; Suzy Misc -SPRCTL0 = $FC80 +SPRCTL0 = $FC80 ; Sprite bits-per-pixel definitions -BPP_MASK = %11000000 ; Mask for settings bits per pixel -BPP_1 = %00000000 -BPP_2 = %01000000 -BPP_3 = %10000000 -BPP_4 = %11000000 +BPP_MASK = %11000000 ; Mask for settings bits per pixel +BPP_1 = %00000000 +BPP_2 = %01000000 +BPP_3 = %10000000 +BPP_4 = %11000000 ; More sprite control 0 bit definitions -HFLIP = %00100000 -VFLIP = %00010000 +HFLIP = %00100000 +VFLIP = %00010000 ; Sprite types - redefined to reflect the reality caused by the shadow error -TYPE_SHADOW = %00000111 -TYPE_XOR = %00000110 +TYPE_SHADOW = %00000111 +TYPE_XOR = %00000110 TYPE_NONCOLL = %00000101 ; Non-colliding -TYPE_NORMAL = %00000100 +TYPE_NORMAL = %00000100 TYPE_BOUNDARY = %00000011 TYPE_BSHADOW = %00000010 ; Background shadow TYPE_BACKNONCOLL = %00000001 ; Background non-colliding TYPE_BACKGROUND = %00000000 -SPRCTL1 = $FC81 -LITERAL = %10000000 -PACKED = %00000000 -ALGO3 = %01000000 ; Broken, do not set this bit! +SPRCTL1 = $FC81 +LITERAL = %10000000 +PACKED = %00000000 +ALGO3 = %01000000 ; Broken, do not set this bit! ; Sprite reload mask definitions -RELOAD_MASK = %00110000 -RENONE = %00000000 ; Reload nothing -REHV = %00010000 ; Reload hsize, vsize -REHVS = %00100000 ; Reload hsize, vsize, stretch -REHVST = %00110000 ; Reload hsize, vsize, stretch, tilt +RELOAD_MASK = %00110000 +RENONE = %00000000 ; Reload nothing +REHV = %00010000 ; Reload hsize, vsize +REHVS = %00100000 ; Reload hsize, vsize, stretch +REHVST = %00110000 ; Reload hsize, vsize, stretch, tilt ; More sprite control 1 bit definitions -REUSEPAL = %00001000 -SKIP = %00000100 -DRAWUP = %00000010 -DRAWLEFT = %00000001 +REUSEPAL = %00001000 +SKIP = %00000100 +DRAWUP = %00000010 +DRAWLEFT = %00000001 SPRCOLL = $FC82 SPRINIT = $FC83 From 66e354961c659bf7466542d577f0bf16811bb875 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Fri, 29 Dec 2023 22:48:36 +0100 Subject: [PATCH 063/707] Missed some tabs --- asminc/lynx.inc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index 198af415b..5ae17f6ef 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -95,22 +95,22 @@ VFLIP = %00010000 TYPE_SHADOW = %00000111 TYPE_XOR = %00000110 TYPE_NONCOLL = %00000101 ; Non-colliding -TYPE_NORMAL = %00000100 -TYPE_BOUNDARY = %00000011 +TYPE_NORMAL = %00000100 +TYPE_BOUNDARY = %00000011 TYPE_BSHADOW = %00000010 ; Background shadow TYPE_BACKNONCOLL = %00000001 ; Background non-colliding -TYPE_BACKGROUND = %00000000 +TYPE_BACKGROUND = %00000000 SPRCTL1 = $FC81 LITERAL = %10000000 PACKED = %00000000 -ALGO3 = %01000000 ; Broken, do not set this bit! +ALGO3 = %01000000 ; Broken, do not set this bit! ; Sprite reload mask definitions RELOAD_MASK = %00110000 -RENONE = %00000000 ; Reload nothing -REHV = %00010000 ; Reload hsize, vsize -REHVS = %00100000 ; Reload hsize, vsize, stretch -REHVST = %00110000 ; Reload hsize, vsize, stretch, tilt +RENONE = %00000000 ; Reload nothing +REHV = %00010000 ; Reload hsize, vsize +REHVS = %00100000 ; Reload hsize, vsize, stretch +REHVST = %00110000 ; Reload hsize, vsize, stretch, tilt ; More sprite control 1 bit definitions REUSEPAL = %00001000 SKIP = %00000100 From 096bd0b633a4a5c9086faaf50a4e86afcfee542c Mon Sep 17 00:00:00 2001 From: paul moore Date: Fri, 29 Dec 2023 17:02:45 -0800 Subject: [PATCH 064/707] bug 2319 --- src/cl65/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cl65/main.c b/src/cl65/main.c index 553fb9ca6..cd245470a 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -1305,6 +1305,9 @@ static void OptStaticLocals (const char* Opt attribute ((unused)), static void OptTarget (const char* Opt attribute ((unused)), const char* Arg) /* Set the target system */ { + if (FirstInput) { + Error ("Target must be specified before input files"); + } Target = FindTarget (Arg); if (Target == TGT_UNKNOWN) { Error ("No such target system: '%s'", Arg); From c262929a626d4c191046da85c480513a6d109c5e Mon Sep 17 00:00:00 2001 From: paul moore Date: Sun, 31 Dec 2023 10:14:53 -0800 Subject: [PATCH 065/707] doc cl65 change --- doc/cl65.sgml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/cl65.sgml b/doc/cl65.sgml index 24d2f5927..f48e1353c 100644 --- a/doc/cl65.sgml +++ b/doc/cl65.sgml @@ -261,6 +261,9 @@ different options for different files on the command line. As an example. translates main.c with full optimization and module.c with less optimization and debug info enabled. +Note that the target system (-t , --target) must be specified before any file +unless using the default target of c64 + The type of an input file is derived from its extension: From f3199e430857663528a1a10b5b5c908d4ff802bb Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 1 Jan 2024 14:48:03 +0800 Subject: [PATCH 066/707] Fixed type name output with K&R-style functions. --- src/cc65/datatype.c | 155 +++++++++++++++++++++++++++----------------- 1 file changed, 95 insertions(+), 60 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 9e0652526..e00e0c64d 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -1356,6 +1356,65 @@ const char* GetFullTypeName (const Type* T) +static void GetParameterList (StrBuf* ParamList, StrBuf* Buf, const FuncDesc* D, int Detailed) +{ + /* First argument */ + const SymEntry* Param = D->SymTab->SymHead; + unsigned I; + + if ((D->Flags & FD_OLDSTYLE) == 0) { + /* ANSI style */ + for (I = 0; I < D->ParamCount; ++I) { + CHECK (Param != 0 && (Param->Flags & SC_PARAM) != 0); + if (I > 0) { + SB_AppendStr (ParamList, ", "); + } + if (Detailed) { + if (SymIsRegVar (Param)) { + SB_AppendStr (ParamList, "register "); + } + if (!SymHasAnonName (Param)) { + SB_AppendStr (Buf, Param->Name); + } + } + SB_AppendStr (ParamList, SB_GetConstBuf (GetFullTypeNameBuf (Buf, Param->Type))); + SB_Clear (Buf); + /* Next argument */ + Param = Param->NextSym; + } + if ((D->Flags & FD_VARIADIC) == 0) { + if (D->ParamCount == 0 && (D->Flags & FD_EMPTY) == 0) { + SB_AppendStr (ParamList, "void"); + } + } else { + if (D->ParamCount > 0) { + SB_AppendStr (ParamList, ", ..."); + } else { + SB_AppendStr (ParamList, "..."); + } + } + } else { + /* K&R style */ + if (Detailed) { + for (I = 0; I < D->ParamCount; ++I) { + CHECK (Param != 0 && (Param->Flags & SC_PARAM) != 0); + if (I > 0) { + SB_AppendStr (ParamList, ", "); + } + if (!SymHasAnonName (Param)) { + SB_AppendStr (ParamList, Param->Name); + } + /* Next argument */ + Param = Param->NextSym; + } + } + SB_Clear (Buf); + } + SB_Terminate (ParamList); +} + + + static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBuf* East, const Type* T) /* Return the name string of the given type split into a western part and an ** eastern part. @@ -1395,34 +1454,11 @@ static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBu } else if (IsTypeFunc (T)) { - FuncDesc* D = GetFuncDesc (T); - struct StrBuf ParamList = AUTO_STRBUF_INITIALIZER; + struct StrBuf ParamList = AUTO_STRBUF_INITIALIZER; + const FuncDesc* D = GetFuncDesc (T); - /* First argument */ - SymEntry* Param = D->SymTab->SymHead; - unsigned I; - for (I = 0; I < D->ParamCount; ++I) { - CHECK (Param != 0 && (Param->Flags & SC_PARAM) != 0); - if (I > 0) { - SB_AppendStr (&ParamList, ", "); - } - SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); - SB_Clear (&Buf); - /* Next argument */ - Param = Param->NextSym; - } - if ((D->Flags & FD_VARIADIC) == 0) { - if (D->ParamCount == 0 && (D->Flags & FD_EMPTY) == 0) { - SB_AppendStr (&ParamList, "void"); - } - } else { - if (D->ParamCount > 0) { - SB_AppendStr (&ParamList, ", ..."); - } else { - SB_AppendStr (&ParamList, "..."); - } - } - SB_Terminate (&ParamList); + /* Get the parameter list string */ + GetParameterList (&ParamList, &Buf, D, 0); /* Join the existing West and East together */ if (!SB_IsEmpty (East)) { @@ -1600,37 +1636,8 @@ void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Get the function descriptor used in definition */ const FuncDesc* D = GetFuncDefinitionDesc (T); - /* Get the parameter list string. Start from the first parameter */ - SymEntry* Param = D->SymTab->SymHead; - unsigned I; - for (I = 0; I < D->ParamCount; ++I) { - CHECK (Param != 0 && (Param->Flags & SC_PARAM) != 0); - if (I > 0) { - SB_AppendStr (&ParamList, ", "); - } - if (SymIsRegVar (Param)) { - SB_AppendStr (&ParamList, "register "); - } - if (!SymHasAnonName (Param)) { - SB_AppendStr (&Buf, Param->Name); - } - SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); - SB_Clear (&Buf); - /* Next argument */ - Param = Param->NextSym; - } - if ((D->Flags & FD_VARIADIC) == 0) { - if (D->ParamCount == 0 && (D->Flags & FD_EMPTY) == 0) { - SB_AppendStr (&ParamList, "void"); - } - } else { - if (D->ParamCount > 0) { - SB_AppendStr (&ParamList, ", ..."); - } else { - SB_AppendStr (&ParamList, "..."); - } - } - SB_Terminate (&ParamList); + /* Get the parameter list string */ + GetParameterList (&ParamList, &Buf, D, 1); /* Get the function qualifiers */ if (GetQualifierTypeCodeNameBuf (&Buf, T->C, T_QUAL_NONE) > 0) { @@ -1641,16 +1648,44 @@ void PrintFuncSig (FILE* F, const char* Name, const Type* T) /* Get the signature string without the return type */ SB_Printf (&West, "%s%s (%s)", SB_GetConstBuf (&Buf), Name, SB_GetConstBuf (&ParamList)); - SB_Done (&Buf); - SB_Done (&ParamList); /* Complete with the return type */ GetFullTypeNameWestEast (&West, &East, GetFuncReturnType (T)); SB_Append (&West, &East); + + /* Check if the function is defined in K&R style */ + if ((D->Flags & FD_OLDSTYLE) != 0 && D->ParamCount > 0) { + /* First argument */ + const SymEntry* Param = D->SymTab->SymHead; + unsigned I; + + SB_Clear (&ParamList); + SB_Clear (&Buf); + for (I = 0; I < D->ParamCount; ++I) { + CHECK (Param != 0 && (Param->Flags & SC_PARAM) != 0); + SB_AppendChar (&ParamList, ' '); + if (SymIsRegVar (Param)) { + SB_AppendStr (&ParamList, "register "); + } + if (!SymHasAnonName (Param)) { + SB_AppendStr (&Buf, Param->Name); + } + SB_AppendStr (&ParamList, SB_GetConstBuf (GetFullTypeNameBuf (&Buf, Param->Type))); + SB_AppendChar (&ParamList, ';'); + SB_Clear (&Buf); + + /* Next argument */ + Param = Param->NextSym; + } + SB_Append (&West, &ParamList); + } + SB_Terminate (&West); /* Output */ fprintf (F, "%s", SB_GetConstBuf (&West)); + SB_Done (&ParamList); + SB_Done (&Buf); SB_Done (&East); SB_Done (&West); } From f734f43a35d05cb5a8980febdd62fafa86eb1c6c Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 1 Jan 2024 14:48:05 +0800 Subject: [PATCH 067/707] Removed extra 'const' qualifier in array-to-pointer and function-to-pointer conversions. --- src/cc65/datatype.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index e00e0c64d..a8b7735b0 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -539,7 +539,7 @@ const Type* AddressOf (const Type* T) Type* P = TypeAlloc (Size + 1); /* Create the return type... */ - P[0].C = T_PTR | (T[0].C & T_QUAL_ADDRSIZE) | T_QUAL_CONST; + P[0].C = T_PTR | (T[0].C & T_QUAL_ADDRSIZE); memcpy (P+1, T, Size * sizeof (Type)); /* ...and return it */ From 0b7d9d8216a4f94d76cad6f587f9277b50410836 Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 1 Jan 2024 14:48:05 +0800 Subject: [PATCH 068/707] Fixed missing calling convention and address size qualifiers in diagnosis on function types. --- src/cc65/datatype.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index a8b7735b0..b2511cf1b 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -1454,6 +1454,7 @@ static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBu } else if (IsTypeFunc (T)) { + int QualCount = 0; struct StrBuf ParamList = AUTO_STRBUF_INITIALIZER; const FuncDesc* D = GetFuncDesc (T); @@ -1467,13 +1468,27 @@ static struct StrBuf* GetFullTypeNameWestEast (struct StrBuf* West, struct StrBu SB_Clear (East); } + /* Add qualifiers */ + if ((GetQualifier (T) & ~T_QUAL_NEAR) != T_QUAL_NONE) { + QualCount = GetQualifierTypeCodeNameBuf (&Buf, T->C, T_QUAL_NEAR); + if (QualCount > 0) { + SB_AppendChar (&Buf, ' '); + } + } + if (SB_IsEmpty (West)) { - /* Just use the param list */ - SB_Printf (West, "(%s)", SB_GetConstBuf (&ParamList)); + /* Use no parentheses */ + SB_Terminate (&Buf); + + /* Append the param list to the West */ + SB_Printf (West, "%s(%s)", SB_GetConstBuf (&Buf), SB_GetConstBuf (&ParamList)); } else { - /* Append the param list to the existing West */ - SB_Printf (&Buf, "(%s)(%s)", SB_GetConstBuf (West), SB_GetConstBuf (&ParamList)); - SB_Printf (West, "%s", SB_GetConstBuf (&Buf)); + /* Append the existing West */ + SB_Append (&Buf, West); + SB_Terminate (&Buf); + + /* Append the param list to the West */ + SB_Printf (West, "(%s)(%s)", SB_GetConstBuf (&Buf), SB_GetConstBuf (&ParamList)); } SB_Done (&ParamList); From 4e820677ee1b6cce52505da7ff042eb8a9520ff7 Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 1 Jan 2024 15:03:45 +0800 Subject: [PATCH 069/707] ED_AddrExpr() and ED_IndExpr() need no return values. --- src/cc65/exprdesc.c | 6 ++---- src/cc65/exprdesc.h | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index a1af0bb8b..a21e56623 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -418,7 +418,7 @@ ExprDesc* ED_FinalizeRValLoad (ExprDesc* Expr) -ExprDesc* ED_AddrExpr (ExprDesc* Expr) +void ED_AddrExpr (ExprDesc* Expr) /* Take address of Expr. The result is always an rvalue */ { switch (Expr->Flags & E_MASK_LOC) { @@ -447,12 +447,11 @@ ExprDesc* ED_AddrExpr (ExprDesc* Expr) } break; } - return Expr; } -ExprDesc* ED_IndExpr (ExprDesc* Expr) +void ED_IndExpr (ExprDesc* Expr) /* Dereference Expr */ { switch (Expr->Flags & E_MASK_LOC) { @@ -486,7 +485,6 @@ ExprDesc* ED_IndExpr (ExprDesc* Expr) } break; } - return Expr; } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 93a8604c9..148485764 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -637,10 +637,10 @@ INLINE void ED_MarkExprAsRVal (ExprDesc* Expr) # define ED_MarkExprAsRVal(Expr) do { (Expr)->Flags &= ~E_RTYPE_LVAL; } while (0) #endif -ExprDesc* ED_AddrExpr (ExprDesc* Expr); +void ED_AddrExpr (ExprDesc* Expr); /* Take address of Expr */ -ExprDesc* ED_IndExpr (ExprDesc* Expr); +void ED_IndExpr (ExprDesc* Expr); /* Dereference Expr */ #if defined(HAVE_INLINE) From 88246f852d73bc52e4ac37ea1927e3d9e9c70c3d Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 1 Jan 2024 15:04:50 +0800 Subject: [PATCH 070/707] Removed RefineFuncDesc() as an unnecessary wrapper. --- src/cc65/symtab.c | 2 +- src/cc65/typeconv.c | 36 ++++-------------------------------- src/cc65/typeconv.h | 3 --- 3 files changed, 5 insertions(+), 36 deletions(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 3018c910d..c2c6bab27 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -741,7 +741,7 @@ static int HandleSymRedefinition (SymEntry* Sym, const Type* T, unsigned Flags) /* Refine the existing composite prototype with this new ** one. */ - RefineFuncDesc (Sym->Type, T); + TypeComposition (Sym->Type, T); } } diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 76658502d..25b693511 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -427,10 +427,6 @@ void TypeComposition (Type* lhs, const Type* rhs) ** type or this fails with a critical check. */ { - FuncDesc* F1; - FuncDesc* F2; - long LeftCount, RightCount; - /* Compose two types */ while (lhs->C != T_END) { @@ -445,8 +441,8 @@ void TypeComposition (Type* lhs, const Type* rhs) /* Check for special type elements */ if (IsTypeFunc (lhs)) { /* Compose the function descriptors */ - F1 = GetFuncDesc (lhs); - F2 = GetFuncDesc (rhs); + FuncDesc* F1 = GetFuncDesc (lhs); + FuncDesc* F2 = GetFuncDesc (rhs); /* If F1 has an empty parameter list (which does also mean, it is ** not a function definition, because the flag is reset in this @@ -470,8 +466,8 @@ void TypeComposition (Type* lhs, const Type* rhs) } } else if (IsTypeArray (lhs)) { /* Check member count */ - LeftCount = GetElementCount (lhs); - RightCount = GetElementCount (rhs); + long LeftCount = GetElementCount (lhs); + long RightCount = GetElementCount (rhs); /* Set composite type if it is requested */ if (LeftCount != UNSPECIFIED) { @@ -485,28 +481,4 @@ void TypeComposition (Type* lhs, const Type* rhs) ++lhs; ++rhs; } - - return; -} - - - -FuncDesc* RefineFuncDesc (Type* OldType, const Type* NewType) -/* Refine the existing function descriptor with a new one */ -{ - FuncDesc* Old = GetFuncDesc (OldType); - FuncDesc* New = GetFuncDesc (NewType); - - CHECK (Old != 0 && New != 0); - - if ((New->Flags & FD_EMPTY) == 0) { - if ((Old->Flags & FD_EMPTY) == 0) { - TypeComposition (OldType, NewType); - } else { - TypeCopy (OldType, NewType); - Old->Flags &= ~FD_EMPTY; - } - } - - return Old; } diff --git a/src/cc65/typeconv.h b/src/cc65/typeconv.h index 839c5e43e..1d79a446c 100644 --- a/src/cc65/typeconv.h +++ b/src/cc65/typeconv.h @@ -63,9 +63,6 @@ void TypeComposition (Type* lhs, const Type* rhs); ** type or this fails with a critical check. */ -FuncDesc* RefineFuncDesc (Type* OldType, const Type* NewType); -/* Refine the existing function descriptor with a new one */ - /* End of typeconv.h */ From acbd87b5764005b7798ae9b3f29c8a7b9e3eaf6b Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 1 Jan 2024 15:27:57 +0800 Subject: [PATCH 071/707] Renamed GetUnqualTypeCode() to GetUnderlyingTypeCode() for consistency with GetUnderlyingType(). --- src/cc65/datatype.c | 12 ++++++------ src/cc65/datatype.h | 14 +++++++------- src/cc65/expr.c | 6 +++--- src/cc65/initdata.c | 4 ++-- src/cc65/typecmp.c | 8 ++++---- src/cc65/typeconv.c | 2 +- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 9e0652526..46f62e922 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -216,7 +216,7 @@ unsigned BitSizeOf (const Type* T) unsigned SizeOf (const Type* T) /* Compute size (in bytes) of object represented by type array */ { - switch (GetUnqualTypeCode (T)) { + switch (GetUnderlyingTypeCode (T)) { case T_VOID: /* A void variable is a cc65 extension. @@ -368,7 +368,7 @@ static unsigned GetMinimalTypeSizeByBitWidth (unsigned BitWidth) -TypeCode GetUnqualTypeCode (const Type* Type) +TypeCode GetUnderlyingTypeCode (const Type* Type) /* Get the type code of the unqualified underlying type of Type. ** Return GetUnqualRawTypeCode (Type) if Type is not scalar. */ @@ -725,7 +725,7 @@ const Type* ArithmeticConvert (const Type* lhst, const Type* rhst) const Type* GetSignedType (const Type* T) /* Get signed counterpart of the integral type */ { - switch (GetUnqualTypeCode (T) & T_MASK_RANK) { + switch (GetUnderlyingTypeCode (T) & T_MASK_RANK) { case T_RANK_CHAR: return type_schar; @@ -739,7 +739,7 @@ const Type* GetSignedType (const Type* T) return type_long; default: - Internal ("Unknown type code: %lX", GetUnqualTypeCode (T)); + Internal ("Unknown type code: %lX", GetUnderlyingTypeCode (T)); return T; } } @@ -749,7 +749,7 @@ const Type* GetSignedType (const Type* T) const Type* GetUnsignedType (const Type* T) /* Get unsigned counterpart of the integral type */ { - switch (GetUnqualTypeCode (T) & T_MASK_RANK) { + switch (GetUnderlyingTypeCode (T) & T_MASK_RANK) { case T_RANK_CHAR: return type_uchar; @@ -763,7 +763,7 @@ const Type* GetUnsignedType (const Type* T) return type_ulong; default: - Internal ("Unknown type code: %lX", GetUnqualTypeCode (T)); + Internal ("Unknown type code: %lX", GetUnderlyingTypeCode (T)); return T; } } diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index 4f4b6f25e..dbe0eedaa 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -328,7 +328,7 @@ INLINE TypeCode GetQualifier (const Type* T) # define GetQualifier(T) ((T)->C & T_MASK_QUAL) #endif -TypeCode GetUnqualTypeCode (const Type* Type); +TypeCode GetUnderlyingTypeCode (const Type* Type); /* Get the type code of the unqualified underlying type of Type. ** Return GetUnqualRawTypeCode (Type) if Type is not scalar. */ @@ -359,30 +359,30 @@ INLINE TypeCode GetTypeClass (const Type* T) INLINE TypeCode GetTypeRank (const Type* T) /* Get the type rank of a type */ { - return (GetUnqualTypeCode (T) & T_MASK_RANK); + return (GetUnderlyingTypeCode (T) & T_MASK_RANK); } #else -# define GetTypeRank(T) (GetUnqualTypeCode (T) & T_MASK_RANK) +# define GetTypeRank(T) (GetUnderlyingTypeCode (T) & T_MASK_RANK) #endif #if defined(HAVE_INLINE) INLINE TypeCode GetSignedness (const Type* T) /* Get the signedness of a type */ { - return (GetUnqualTypeCode (T) & T_MASK_SIGN); + return (GetUnderlyingTypeCode (T) & T_MASK_SIGN); } #else -# define GetSignedness(T) (GetUnqualTypeCode (T) & T_MASK_SIGN) +# define GetSignedness(T) (GetUnderlyingTypeCode (T) & T_MASK_SIGN) #endif #if defined(HAVE_INLINE) INLINE TypeCode GetSizeModifier (const Type* T) /* Get the size modifier of a type */ { - return (GetUnqualTypeCode (T) & T_MASK_SIZE); + return (GetUnderlyingTypeCode (T) & T_MASK_SIZE); } #else -# define GetSizeModifier(T) (GetUnqualTypeCode (T) & T_MASK_SIZE) +# define GetSizeModifier(T) (GetUnderlyingTypeCode (T) & T_MASK_SIZE) #endif #if defined(HAVE_INLINE) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index cfddfa24e..0f3a6e110 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -129,7 +129,7 @@ unsigned CG_TypeOf (const Type* T) { unsigned CG_Type; - switch (GetUnqualTypeCode (T)) { + switch (GetUnderlyingTypeCode (T)) { case T_SCHAR: return CF_CHAR; @@ -188,7 +188,7 @@ unsigned CG_TypeOf (const Type* T) unsigned CG_CallFlags (const Type* T) /* Get the code generator flags for calling the function */ { - if (GetUnqualTypeCode (T) == T_FUNC) { + if (GetUnderlyingTypeCode (T) == T_FUNC) { return (T->A.F->Flags & FD_VARIADIC) ? 0 : CF_FIXARGC; } else { Error ("Illegal function type %04lX", T->C); @@ -291,7 +291,7 @@ static unsigned typeadjust (ExprDesc* lhs, const ExprDesc* rhs, int NoPush) void LimitExprValue (ExprDesc* Expr, int WarnOverflow) /* Limit the constant value of the expression to the range of its type */ { - switch (GetUnqualTypeCode (Expr->Type)) { + switch (GetUnderlyingTypeCode (Expr->Type)) { case T_INT: case T_SHORT: if (WarnOverflow && ((Expr->IVal < -0x8000) || (Expr->IVal > 0x7FFF))) { diff --git a/src/cc65/initdata.c b/src/cc65/initdata.c index 5401e577c..82cebefc2 100644 --- a/src/cc65/initdata.c +++ b/src/cc65/initdata.c @@ -679,7 +679,7 @@ static unsigned ParseVoidInit (Type* T) Size = 0; do { ExprDesc Expr = NoCodeConstExpr (hie1); - switch (GetUnqualTypeCode (&Expr.Type[0])) { + switch (GetUnderlyingTypeCode (&Expr.Type[0])) { case T_SCHAR: case T_UCHAR: @@ -747,7 +747,7 @@ static unsigned ParseVoidInit (Type* T) static unsigned ParseInitInternal (Type* T, int *Braces, int AllowFlexibleMembers) /* Parse initialization of variables. Return the number of data bytes. */ { - switch (GetUnqualTypeCode (T)) { + switch (GetUnderlyingTypeCode (T)) { case T_SCHAR: case T_UCHAR: diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index e8b790a69..a09c80304 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -259,8 +259,8 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) } /* Get the ranks of the left and right hands */ - LeftRank = (GetUnqualTypeCode (lhs) & T_MASK_RANK); - RightRank = (GetUnqualTypeCode (rhs) & T_MASK_RANK); + LeftRank = (GetUnderlyingTypeCode (lhs) & T_MASK_RANK); + RightRank = (GetUnderlyingTypeCode (rhs) & T_MASK_RANK); /* Bit-fields are considered compatible if they have the same ** signedness, bit-offset and bit-width. @@ -344,10 +344,10 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) case T_RANK_PTR: ++Result->Indirections; if (Result->Indirections == 1) { - if ((GetUnqualTypeCode (lhs + 1) & T_MASK_RANK) == T_RANK_VOID) { + if ((GetUnderlyingTypeCode (lhs + 1) & T_MASK_RANK) == T_RANK_VOID) { Result->F |= TCF_VOID_PTR_ON_LEFT; } - if ((GetUnqualTypeCode (rhs + 1) & T_MASK_RANK) == T_RANK_VOID) { + if ((GetUnderlyingTypeCode (rhs + 1) & T_MASK_RANK) == T_RANK_VOID) { Result->F |= TCF_VOID_PTR_ON_RIGHT; } } else { diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 25b693511..6e9fad69a 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -436,7 +436,7 @@ void TypeComposition (Type* lhs, const Type* rhs) } /* Check for sanity */ - CHECK (GetUnqualTypeCode (lhs) == GetUnqualTypeCode (rhs)); + CHECK (GetUnderlyingTypeCode (lhs) == GetUnderlyingTypeCode (rhs)); /* Check for special type elements */ if (IsTypeFunc (lhs)) { From 7aab84628dad035e3e14d0b837d99496723a1c67 Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 1 Jan 2024 16:11:30 +0800 Subject: [PATCH 072/707] Fixed calling convention parsing in type names and function parameter types. --- src/cc65/declare.c | 112 +++++++++++++++++++++++----------- test/val/bug2327-cconv-type.c | 111 +++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 35 deletions(-) create mode 100644 test/val/bug2327-cconv-type.c diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 8b7512730..2666a8d31 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -501,6 +501,31 @@ static void FixQualifiers (Type* DataType) T[0].C |= CodeAddrSizeQualifier (); } + } else { + + /* If we have remaining qualifiers, flag them as invalid */ + Q = T[0].C; + + if (Q & T_QUAL_NEAR) { + Error ("Invalid '__near__' qualifier"); + Q &= ~T_QUAL_NEAR; + } + if (Q & T_QUAL_FAR) { + Error ("Invalid '__far__' qualifier"); + Q &= ~T_QUAL_FAR; + } + if (Q & T_QUAL_FASTCALL) { + Error ("Invalid '__fastcall__' qualifier"); + Q &= ~T_QUAL_FASTCALL; + } + if (Q & T_QUAL_CDECL) { + Error ("Invalid '__cdecl__' qualifier"); + Q &= ~T_QUAL_CDECL; + } + + /* Clear the invalid qualifiers */ + T[0].C &= Q; + } ++T; } @@ -1990,7 +2015,7 @@ static void ParseAnsiParamList (FuncDesc* F) static void ParseFuncDecl (Declarator* D, declmode_t Mode, TypeCode Qualifiers) -/* Parse the argument list of a function with the enclosing parentheses */ +/* Parse the argument list of a function with the closing parenthesis */ { /* Create a new function descriptor */ FuncDesc* F = NewFuncDesc (); @@ -1998,9 +2023,6 @@ static void ParseFuncDecl (Declarator* D, declmode_t Mode, TypeCode Qualifiers) /* Enter a new lexical level */ EnterFunctionLevel (); - /* Skip the opening paren */ - NextToken (); - /* Check for several special parameter lists */ if (CurTok.Tok == TOK_RPAREN) { /* Parameter list is empty (K&R-style) */ @@ -2075,19 +2097,18 @@ static void ParseFuncDecl (Declarator* D, declmode_t Mode, TypeCode Qualifiers) -static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) +static void DirectDecl (DeclSpec* Spec, Declarator* D, TypeCode* RemQ, declmode_t Mode) /* Recursively process direct declarators. Build a type array in reverse order. */ { /* Read optional function or pointer qualifiers that modify the identifier - ** or token to the right. For convenience, we allow a calling convention - ** also for pointers here. If it's a pointer-to-function, the qualifier - ** later will be transfered to the function itself. If it's a pointer to - ** something else, it will be flagged as an error. + ** or token to the right. */ - TypeCode Qualifiers = OptionalQualifiers (T_QUAL_NONE, T_QUAL_ADDRSIZE | T_QUAL_CCONV); + TypeCode Qualifiers = *RemQ | OptionalQualifiers (*RemQ, T_QUAL_ADDRSIZE | T_QUAL_CCONV); /* Pointer to something */ if (CurTok.Tok == TOK_STAR) { + /* Qualifiers on the pointer itself */ + TypeCode Q = T_QUAL_NONE; /* Skip the star */ NextToken (); @@ -2098,17 +2119,30 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) } /* Allow const, restrict, and volatile qualifiers */ - Qualifiers |= OptionalQualifiers (Qualifiers, T_QUAL_CVR); + Q |= OptionalQualifiers (Qualifiers, T_QUAL_CVR); - /* Parse the type that the pointer points to */ - DirectDecl (Spec, D, Mode); + /* For convenience, we allow a calling convention also for pointers + ** here. If it's a pointer-to-function, the qualifier later will be + ** transfered to the function itself. If it's a pointer to something + ** else, it will be flagged as an error. + */ + *RemQ = T_QUAL_NONE; + + /* Parse the type that derives from the pointer */ + DirectDecl (Spec, D, RemQ, Mode); /* Add the type */ - AddTypeCodeToDeclarator (D, T_PTR | Qualifiers); + AddTypeCodeToDeclarator (D, T_PTR | Q | *RemQ); + + /* Return the calling convention and address size specifiers on the + ** pointee type. + */ + *RemQ = Qualifiers; return; } if (CurTok.Tok == TOK_LPAREN) { + int Nested = 0; SymEntry* Entry; /* An empty declaration cannot contain parentheses where an identifier @@ -2118,19 +2152,33 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) Spec->Flags |= DS_NO_EMPTY_DECL; } + /* Skip the opening paren */ + NextToken (); + /* We have to disambiguate the meanings of 'type (identifier' when ** the identifier can be a typedef'ed parameter type specifier or ** a declarator enclosed in parentheses in some cases. */ if (Mode == DM_IDENT_OR_EMPTY || /* If we are in a declaration... */ - NextTok.Tok == TOK_LPAREN || /* or the next token is one more paren... */ - NextTok.Tok == TOK_STAR || /* or a '*' ... */ - (NextTok.Tok == TOK_IDENT && /* or an identifier that... */ - ((Entry = FindSym (NextTok.Ident)) == 0 || /* is not a typedef. */ - !SymIsTypeDef (Entry)))) { + CurTok.Tok == TOK_LPAREN || /* or the next token is one more paren... */ + CurTok.Tok == TOK_STAR || /* or a '*' ... */ + (CurTok.Tok == TOK_IDENT && /* or an identifier that... */ + ((Entry = FindSym (CurTok.Ident)) == 0 || /* is not a typedef. */ + !SymIsTypeDef (Entry)))) { + Nested = 1; + } else { + /* Check for qualifiers */ + TypeCode Q = OptionalQualifiers (T_QUAL_NONE, T_QUAL_ADDRSIZE | T_QUAL_CCONV); + + if (Q != T_QUAL_NONE) { + Qualifiers |= Q; + Nested = 1; + } + } + + if (Nested) { /* Parse the direct declarator in parentheses */ - NextToken (); - DirectDecl (Spec, D, Mode); + DirectDecl (Spec, D, &Qualifiers, Mode); ConsumeRParen (); } else { /* This is a parameter type list in parentheses */ @@ -2160,6 +2208,9 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) while (CurTok.Tok == TOK_LBRACK || CurTok.Tok == TOK_LPAREN) { if (CurTok.Tok == TOK_LPAREN) { + /* Skip the opening paren */ + NextToken (); + /* Function declarator */ ParseFuncDecl (D, Mode, Qualifiers); @@ -2215,19 +2266,7 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) } } - /* If we have remaining qualifiers, flag them as invalid */ - if (Qualifiers & T_QUAL_NEAR) { - Error ("Invalid '__near__' qualifier"); - } - if (Qualifiers & T_QUAL_FAR) { - Error ("Invalid '__far__' qualifier"); - } - if (Qualifiers & T_QUAL_FASTCALL) { - Error ("Invalid '__fastcall__' qualifier"); - } - if (Qualifiers & T_QUAL_CDECL) { - Error ("Invalid '__cdecl__' qualifier"); - } + *RemQ = Qualifiers; } @@ -2288,6 +2327,8 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) ** Return 1 otherwise. */ { + TypeCode Q = T_QUAL_NONE; + /* Used to check if we have any errors during parsing this */ unsigned PrevErrorCount = ErrorCount; @@ -2303,11 +2344,12 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) InitDeclarator (D); /* Get additional derivation of the declarator and the identifier */ - DirectDecl (Spec, D, Mode); + DirectDecl (Spec, D, &Q, Mode); /* Add the base type */ NeedTypeSpace (D, TypeLen (Spec->Type) + 1); /* Bounds check */ TypeCopy (D->Type + D->Index, Spec->Type); + D->Type[D->Index].C |= Q; /* Use the storage class from the declspec */ D->StorageClass = Spec->StorageClass; diff --git a/test/val/bug2327-cconv-type.c b/test/val/bug2327-cconv-type.c new file mode 100644 index 000000000..678727278 --- /dev/null +++ b/test/val/bug2327-cconv-type.c @@ -0,0 +1,111 @@ +/* Bug #2327 - Calling conventions and address size specifiers of functions in type names and parameter types are not parsed correctly */ + +#include +#include + +unsigned failures; +int need_header = 1; +const char* test_header; + +/* Helpers */ +void set_header(const char* name) +{ + if (need_header == 0) + { + printf("\n"); + } + test_header = name; + need_header = 1; +} + +void print_header(void) +{ + if (need_header) + { + need_header = 0; + printf("<%s test>\n", test_header); + } +} + +#define CHECK(R, E) \ + do { \ + if ((R) != (E)) { \ + ++failures; \ + print_header(); \ + printf(" fail: %s = %d\n", #R, (R)); \ + } \ + } while (0); + +#define CHECK_RV() CHECK(rv, 42) +#define CHECK_SP() CHECK(x - (intptr_t)&x, 0) + +#define FUNC_QUAL __cdecl__ __near__ + +typedef int hoo_t(int __far__ __cdecl__ ()); +typedef int hoo_t(int __far__ (__cdecl__)()); /* Question: should this be rejected? */ +typedef int hoo_t(int __far__ (__cdecl__ ())); +typedef int hoo_t(int __far__ (__cdecl__ *)()); +typedef int hoo_t(int __far__ (__cdecl__ (*)())); +typedef int hoo_t(int __far__ ((__cdecl__ *)())); + +typedef int hoo_t(int __cdecl__ __far__ ()); +typedef int hoo_t(int (__cdecl__ __far__)()); /* Question: should this be rejected? */ +typedef int hoo_t(int (__cdecl__ __far__ ())); +typedef int hoo_t(int (__cdecl__ __far__ *)()); +typedef int hoo_t(int (__cdecl__ (__far__ *)())); +typedef int hoo_t(int ((__cdecl__ __far__ *)())); + +typedef int (FUNC_QUAL foo_t)(int, int); +typedef int (FUNC_QUAL *pfoo_t)(int, int); + +int FUNC_QUAL foo(int a, int b) +{ + return a * b; +} + +int (FUNC_QUAL * const pfoo)() = (int (FUNC_QUAL *)())foo; + +/* Incompatible and not working for cc65 if used as-is */ +int (*qfoo)(int, ...) = foo; + +int main(void) +{ + int rv; + intptr_t x; + + set_header("init"); + x = (intptr_t)&x; + CHECK_SP() + + set_header("foo"); + rv = foo((int8_t)-3, (int32_t)-14); + CHECK_RV() + CHECK_SP() + + set_header("pfoo"); +#if 0 + /* This would fail */ + rv = pfoo((int8_t)-6, (int32_t)-7); +#else + rv = ((pfoo_t)pfoo)((int8_t)-6, (int32_t)-7); +#endif + CHECK_RV() + CHECK_SP() + + set_header("qfoo"); +#if 0 + /* This would fail */ + rv = (qfoo)((int32_t)-6, (int8_t)-7); +#else + rv = ((foo_t *)qfoo)((int32_t)-6, (int8_t)-7); +#endif + CHECK_RV() + CHECK_SP() + + if (failures > 0) + { + printf("\nfailures: %u\n", failures); + } + + return failures; +} From 75461e13190976534eec4a1b8ce89f6ed03773ac Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Thu, 28 Dec 2023 21:50:13 +0100 Subject: [PATCH 073/707] Apple2: implement stat(2) and statvfs(3) --- asminc/stat.inc | 64 ++++++++++ asminc/statvfs.inc | 46 +++++++ doc/apple2.sgml | 37 +++++- doc/apple2enh.sgml | 39 +++++- doc/funcref.sgml | 171 +++++++++++++++++++++++++++ include/apple2.h | 42 +++++-- include/dirent.h | 36 ++---- include/sys/stat.h | 37 +++++- include/sys/statvfs.h | 74 ++++++++++++ include/sys/types.h | 43 ++++++- include/time.h | 12 +- libsrc/apple2/exec.s | 26 ++-- libsrc/apple2/filename.s | 11 +- libsrc/apple2/gettime.s | 56 ++------- libsrc/apple2/gmtime_dt.s | 73 ++++++++++++ libsrc/apple2/mktime_dt.s | 37 ++++++ libsrc/apple2/mli.inc | 7 +- libsrc/apple2/mli_file_info.s | 33 ++++++ libsrc/apple2/mli_file_info_direct.s | 22 ++++ libsrc/apple2/open.s | 1 + libsrc/apple2/stat.s | 129 ++++++++++++++++++++ libsrc/apple2/statvfs.s | 125 ++++++++++++++++++++ libsrc/apple2/targetutil/convert.c | 2 +- 23 files changed, 999 insertions(+), 124 deletions(-) create mode 100644 asminc/stat.inc create mode 100644 asminc/statvfs.inc create mode 100644 include/sys/statvfs.h create mode 100644 libsrc/apple2/gmtime_dt.s create mode 100644 libsrc/apple2/mktime_dt.s create mode 100644 libsrc/apple2/mli_file_info.s create mode 100644 libsrc/apple2/mli_file_info_direct.s create mode 100644 libsrc/apple2/stat.s create mode 100644 libsrc/apple2/statvfs.s diff --git a/asminc/stat.inc b/asminc/stat.inc new file mode 100644 index 000000000..e5248f06d --- /dev/null +++ b/asminc/stat.inc @@ -0,0 +1,64 @@ +;**************************************************************************** +;* * +;* stat.inc * +;* * +;* Stat struct * +;* * +;* * +;* * +;*(C) 2023 Colin Leroy-Mira * +;* * +;* * +;*This software is provided 'as-is', without any expressed or implied * +;*warranty. In no event will the authors be held liable for any damages * +;*arising from the use of this software. * +;* * +;*Permission is granted to anyone to use this software for any purpose, * +;*including commercial applications, and to alter it and redistribute it * +;*freely, subject to the following restrictions: * +;* * +;*1. The origin of this software must not be misrepresented; you must not * +;* claim that you wrote the original software. If you use this software * +;* in a product, an acknowledgment in the product documentation would be * +;* appreciated but is not required. * +;*2. Altered source versions must be plainly marked as such, and must not * +;* be misrepresented as being the original software. * +;*3. This notice may not be removed or altered from any source * +;* distribution. * +;* * +;**************************************************************************** + + .include "time.inc" + +;------------------------------------------------------------------------------ +; st_mode values + +S_IFDIR = $01 +S_IFREG = $02 + +;------------------------------------------------------------------------------ +; struct stat + +.struct stat + st_dev .dword + st_ino .dword + st_mode .byte + st_nlink .dword + st_uid .byte + st_gid .byte + st_size .dword + st_atim .tag timespec + st_ctim .tag timespec + st_mtim .tag timespec + .ifdef __APPLE2__ + st_access .byte + st_type .byte + st_auxtype .word + st_storagetype .byte + st_blocks .word + st_mod_date .word + st_mod_time .word + st_create_date .word + st_create_time .word + .endif +.endstruct diff --git a/asminc/statvfs.inc b/asminc/statvfs.inc new file mode 100644 index 000000000..8674b045d --- /dev/null +++ b/asminc/statvfs.inc @@ -0,0 +1,46 @@ +;**************************************************************************** +;* * +;* statvfs.inc * +;* * +;* Statvfs struct * +;* * +;* * +;* * +;*(C) 2023 Colin Leroy-Mira * +;* * +;* * +;*This software is provided 'as-is', without any expressed or implied * +;*warranty. In no event will the authors be held liable for any damages * +;*arising from the use of this software. * +;* * +;*Permission is granted to anyone to use this software for any purpose, * +;*including commercial applications, and to alter it and redistribute it * +;*freely, subject to the following restrictions: * +;* * +;*1. The origin of this software must not be misrepresented; you must not * +;* claim that you wrote the original software. If you use this software * +;* in a product, an acknowledgment in the product documentation would be * +;* appreciated but is not required. * +;*2. Altered source versions must be plainly marked as such, and must not * +;* be misrepresented as being the original software. * +;*3. This notice may not be removed or altered from any source * +;* distribution. * +;* * +;**************************************************************************** + +;------------------------------------------------------------------------------ +; struct statvfs + +.struct statvfs + f_bsize .dword + f_frsize .dword + f_blocks .dword + f_bfree .dword + f_bavail .dword + f_files .dword + f_ffree .dword + f_favail .dword + f_fsid .dword + f_flag .dword + f_namemax .dword +.endstruct diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 97724c147..f1603c428 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -321,14 +321,15 @@ Programs containing Apple ][ specific code may use the Apple ][ specific functions

-The functions listed below are special for the Apple ][. See -the for declaration and +The functions and variables listed below are special for the Apple ][. +See the for declaration and usage. _auxtype _dos_type _filetype +_datetime get_ostype rebootafterexit ser_apple2_slot @@ -569,6 +570,28 @@ program. See the discussion of the . +ProDOS date/time manipulation

+ + +The readdir and stat function return ProDOS timestamps in their file +creation/modification time attributes. You can convert them to more portable +time representations using either: + + + + DIO

@@ -630,6 +653,16 @@ url="ca65.html" name="assembler manual">. that can be used to set these variables. It is included in + + extern struct datetime _datetime; + + + Example A text file cannot be created with just the diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 11d4feb7e..e27501577 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -322,14 +322,15 @@ Programs containing enhanced Apple //e specific code may use the Enhanced Apple //e specific functions

-The functions listed below are special for the enhanced Apple //e. See -the for declaration and +The functions and variables listed below are special for the Apple ][. +See the for declaration and usage. _auxtype _dos_type _filetype +_datetime get_ostype rebootafterexit ser_apple2_slot @@ -575,6 +576,28 @@ program. See the discussion of the . +ProDOS date/time manipulation

+ + +The readdir and stat function return ProDOS timestamps in their file +creation/modification time attributes. You can convert them to more portable +time representations using either: + + + + DIO

@@ -619,7 +642,7 @@ url="ca65.html" name="assembler manual">. auxiliary type. Therefore, some additional mechanism for specifying the file types is needed. - Specifying the File Type and Auxiliary Type + Specifying the File Type, Auxiliary Type and creation date There are two global variables provided that allow the file type and auxiliary type to be specified before a call to . that can be used to set these variables. It is included in + + extern struct datetime _datetime; + + + Example A text file cannot be created with just the diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 524818b19..c8a818295 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -93,6 +93,8 @@ function. _dos_type + + rebootafterexit @@ -846,6 +848,20 @@ communication, see also testcode/lib/ser-test.c. (incomplete) +

+ + + + + + +

+ + + + + +

(incomplete) @@ -2851,6 +2867,79 @@ setting the time may not work. See also the platform-specific information. +gmtime_dt

+ + + +/ + +The function is only available as fastcall function, so it may only +be used in presence of a prototype. +This function is only available on Apple II. +On Apple II, you can't stat() an opened file. stat() before opening. + + + +#include +#include +#include +int main(void) +{ + struct stat st; + struct tm* tm; + if (stat ("/disk/file", &st) == 0) { + tm = gmtime_dt (&st.st_ctime); + if (tm) + printf ("File created on %s\n", asctime(tm)); + } +} + + + + + +mktime_dt

+ + + +/ + +The function is only available as fastcall function, so it may only +be used in presence of a prototype. +This function is only available on Apple II. + + + +#include +#include +#include +int main(void) +{ + struct stat st; + if (stat ("/disk/file", &st) == 0) { + printf ("File created on %s\n", + localtime (mktime_dt (&st.st_ctime))); + } +} + + + + + clrscr

@@ -6229,6 +6318,9 @@ be used in presence of a prototype. The returned pointer may point to a statically allocated instance of On the Apple II platform, the d_ctime and d_mtime returned are in the +ProDOS format. You can convert them to more portable time representations using +the ProDOS datetime conversion functions. On several platforms, namely the CBMs and the Atari, the disk drives get confused when opening/closing files between directory reads. So for example a program that reads the list of files on a disk, and after each call to @@ -7075,6 +7167,85 @@ be used in presence of a prototype. +stat

+ + + +/ + +The function is only available as fastcall function, so it may only +be used in presence of a prototype. +On the Apple II platform, the st_ctim, st_mtim and st_atim members are left +to zero, for size and performance reasons. The ProDOS creation and modification dates +are returned in the ProDOS format in st_ctime and st_mtime. The access date does +not exist. You can convert them to POSIX-style time representations using +the . + + + +#include <sys/stat.h> + +#define FILENAME "helloworld" +struct stat stbuf; +if (stat (FILENAME, &stbuf) == 0) { + printf ("%s size is %lu bytes (created on %s)\n", FILENAME, stbuf.st_size, +#ifndef __APPLE2__ + localtime (&stbuf.st_ctim.tv_sec) +#else + localtime (mktime_dt (&stbuf.st_ctime)) +#endif + ); +} else { + printf ("There was a problem stat'ing %s: %d\n", FILENAME, errno); +} + + + + + +statvfs

+ + + +/ + +The function is only available as fastcall function, so it may only +be used in presence of a prototype. +The function requires an absolute pathname. + + + +#include <sys/statvfs.h> + +#define FILENAME "/disk/helloworld" +struct statvfs stvbuf; +if (statvfs (FILENAME, &stvbuf) == 0) { + printf ("%s filesystem has %u blocks of %u size, %u of them free.\n", FILENAME, stvbuf.f_blocks, stvbuf.f_bsize, stvbuf.f_bfree); +} else { + printf ("There was a problem statvfs'ing %s: %d\n", FILENAME, errno); +} + + + + + strcasecmp

diff --git a/include/apple2.h b/include/apple2.h index 8b9a3e0ea..25995eec2 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -41,6 +41,7 @@ # error This module may only be used when compiling for the Apple ][! #endif +#include #include @@ -142,6 +143,27 @@ extern unsigned char _dos_type; ** ProDOS 8 2.4.x - 0x24 */ +/* struct stat.st_mode values */ +#define S_IFDIR 0x01 +#define S_IFREG 0x02 +#define S_IFBLK 0xFF +#define S_IFCHR 0xFF +#define S_IFIFO 0xFF +#define S_IFLNK 0xFF +#define S_IFSOCK 0xFF + +struct datetime { + struct { + unsigned day :5; + unsigned mon :4; + unsigned year :7; + } date; + struct { + unsigned char min; + unsigned char hour; + } time; +}; + /*****************************************************************************/ @@ -151,20 +173,10 @@ extern unsigned char _dos_type; /* The file stream implementation and the POSIX I/O functions will use the -** following struct to set the date and time stamp on files. This specificially +** following struct to set the date and time stamp on files. This specifically ** applies to the open and fopen functions. */ -extern struct { - struct { - unsigned day :5; - unsigned mon :4; - unsigned year :7; - } createdate; /* Current date: 0 */ - struct { - unsigned char min; - unsigned char hour; - } createtime; /* Current time: 0 */ -} _datetime; +extern struct datetime _datetime; /* The addresses of the static drivers */ #if !defined(__APPLE2ENH__) @@ -211,6 +223,12 @@ void rebootafterexit (void); #define _cpeekcolor() COLOR_WHITE #define _cpeekrevers() 0 +struct tm* __fastcall__ gmtime_dt (const struct datetime* dt); +/* Converts a ProDOS date/time structure to a struct tm */ + +time_t __fastcall__ mktime_dt (const struct datetime* dt); +/* Converts a ProDOS date/time structure to a time_t UNIX timestamp */ + /* End of apple2.h */ diff --git a/include/dirent.h b/include/dirent.h index 124c7f224..b95646833 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -33,6 +33,8 @@ #ifndef _DIRENT_H #define _DIRENT_H +#include + /*****************************************************************************/ @@ -46,31 +48,15 @@ typedef struct DIR DIR; #if defined(__APPLE2__) struct dirent { - char d_name[16]; - unsigned d_ino; - unsigned d_blocks; - unsigned long d_size; - unsigned char d_type; - struct { - unsigned day :5; - unsigned mon :4; - unsigned year :7; - } d_cdate; - struct { - unsigned char min; - unsigned char hour; - } d_ctime; - unsigned char d_access; - unsigned d_auxtype; - struct { - unsigned day :5; - unsigned mon :4; - unsigned year :7; - } d_mdate; - struct { - unsigned char min; - unsigned char hour; - } d_mtime; + char d_name[16]; + unsigned d_ino; + unsigned d_blocks; + unsigned long d_size; + unsigned char d_type; + struct datetime d_ctime; + unsigned char d_access; + unsigned d_auxtype; + struct datetime d_mtime; }; #define _DE_ISREG(t) ((t) != 0x0F) diff --git a/include/sys/stat.h b/include/sys/stat.h index d8fc09c75..0e1589d52 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -2,7 +2,7 @@ /* */ /* stat.h */ /* */ -/* Constants for the mode argument of open and creat */ +/* stat(2) definition */ /* */ /* */ /* */ @@ -11,6 +11,9 @@ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ +/* (C) 2023 Colin Leroy-Mira */ +/* EMail: colin@colino.net */ +/* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ /* warranty. In no event will the authors be held liable for any damages */ @@ -36,6 +39,10 @@ #ifndef _STAT_H #define _STAT_H +#include +#include +#include + /*****************************************************************************/ @@ -47,6 +54,30 @@ #define S_IREAD 0x01 #define S_IWRITE 0x02 +#define S_IFMT 0x03 + +struct stat { + dev_t st_dev; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + off_t st_size; + struct timespec st_atim; + struct timespec st_ctim; + struct timespec st_mtim; + #ifdef __APPLE2__ + unsigned char st_access; + unsigned char st_type; + unsigned int st_auxtype; + unsigned char st_storagetype; + unsigned int st_blocks; + struct datetime st_mtime; + struct datetime st_ctime; + #endif +}; + /*****************************************************************************/ @@ -55,5 +86,9 @@ +int __fastcall__ stat (const char* pathname, struct stat* statbuf); + + + /* End of stat.h */ #endif diff --git a/include/sys/statvfs.h b/include/sys/statvfs.h new file mode 100644 index 000000000..d9edc2f23 --- /dev/null +++ b/include/sys/statvfs.h @@ -0,0 +1,74 @@ +/*****************************************************************************/ +/* */ +/* statvfs.h */ +/* */ +/* statvfs(3) definition */ +/* */ +/* */ +/* */ +/* (C) 2023 Colin Leroy-Mira */ +/* EMail: colin@colino.net */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _STATVFS_H +#define _STATVFS_H + +#include + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +struct statvfs { + unsigned long f_bsize; + unsigned long f_frsize; + fsblkcnt_t f_blocks; + fsblkcnt_t f_bfree; + fsblkcnt_t f_bavail; + fsfilcnt_t f_files; + fsfilcnt_t f_ffree; + fsfilcnt_t f_favail; + unsigned long f_fsid; + unsigned long f_flag; + unsigned long f_namemax; +}; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +int __fastcall__ statvfs (const char* pathname, struct statvfs* buf); + + + +/* End of statvfs.h */ +#endif diff --git a/include/sys/types.h b/include/sys/types.h index e75dd7d46..89b91c5b4 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -50,6 +50,46 @@ typedef long int off_t; #endif +#ifndef _HAVE_dev_t +#define _HAVE_dev_t +typedef unsigned long int dev_t; +#endif + +#ifndef _HAVE_ino_t +#define _HAVE_ino_t +typedef unsigned long int ino_t; +#endif + +#ifndef _HAVE_nlink_t +#define _HAVE_nlink_t +typedef unsigned long int nlink_t; +#endif + +#ifndef _HAVE_uid_t +#define _HAVE_uid_t +typedef unsigned char uid_t; +#endif + +#ifndef _HAVE_gid_t +#define _HAVE_gid_t +typedef unsigned char gid_t; +#endif + +#ifndef _HAVE_mode_t +#define _HAVE_mode_t +typedef unsigned char mode_t; +#endif + +#ifndef _HAVE_fsblkcnt_t +#define _HAVE_fsblkcnt_t +typedef unsigned long int fsblkcnt_t; +#endif + +#ifndef _HAVE_fsfilcnt_t +#define _HAVE_fsfilcnt_t +typedef unsigned long int fsfilcnt_t; +#endif + /*****************************************************************************/ @@ -60,6 +100,3 @@ typedef long int off_t; /* End of types.h */ #endif - - - diff --git a/include/time.h b/include/time.h index bfc2ac435..6cd0c8068 100644 --- a/include/time.h +++ b/include/time.h @@ -37,6 +37,15 @@ #define _TIME_H +/* Forward declaration for target.h */ +typedef unsigned long time_t; +typedef unsigned long clock_t; + + + +#include + + /* NULL pointer */ #ifndef NULL @@ -49,9 +58,6 @@ typedef unsigned size_t; #endif -typedef unsigned long time_t; -typedef unsigned long clock_t; - /* Structure for broken down time */ struct tm { int tm_sec; diff --git a/libsrc/apple2/exec.s b/libsrc/apple2/exec.s index b8875e9ca..ec90f19bb 100644 --- a/libsrc/apple2/exec.s +++ b/libsrc/apple2/exec.s @@ -5,8 +5,8 @@ ; .export _exec - .import pushname, popname - .import popax, done, _exit + .import mli_file_info_direct + .import pushname, popname, popax, done, _exit .include "zeropage.inc" .include "errno.inc" @@ -17,13 +17,12 @@ typerr: lda #$4A ; "Incompatible file format" ; Cleanup name -oserr: jsr popname ; Preserves A - ; Set ___oserror - jmp ___mappederrno +mlierr: jsr popname +oserr: jmp ___mappederrno _exec: - ; Save cmdline + ; Store cmdline sta ptr4 stx ptr4+1 @@ -32,6 +31,9 @@ _exec: jsr pushname bne oserr + jsr mli_file_info_direct + bcs mlierr + ; ProDOS TechRefMan, chapter 5.1.5.1: ; "The complete or partial pathname of the system program ; is stored at $280, starting with a length byte." @@ -46,18 +48,6 @@ _exec: dey bpl :- - ; Set pushed name - lda sp - ldx sp+1 - sta mliparam + MLI::INFO::PATHNAME - stx mliparam + MLI::INFO::PATHNAME+1 - - ; Get file_type and aux_type - lda #GET_INFO_CALL - ldx #GET_INFO_COUNT - jsr callmli - bcs oserr - ; If we get here the program file at least exists so we copy ; the loader stub right now and patch it later to set params ldx #size - 1 diff --git a/libsrc/apple2/filename.s b/libsrc/apple2/filename.s index aaef6ec2d..0d4b6bedd 100644 --- a/libsrc/apple2/filename.s +++ b/libsrc/apple2/filename.s @@ -8,6 +8,7 @@ .import subysp, addysp, decsp1 .include "zeropage.inc" + .include "apple2.inc" .include "mli.inc" pushname: @@ -15,7 +16,7 @@ pushname: stx ptr1+1 ; Alloc pathname buffer - ldy #64+1 ; Max pathname length + zero + ldy #FILENAME_MAX jsr subysp ; Check for full pathname @@ -71,14 +72,14 @@ copy: lda (ptr1),y sta (sp),y beq setlen iny - cpy #64+1 ; Max pathname length + zero + cpy #FILENAME_MAX bcc copy ; Load oserror code lda #$40 ; "Invalid pathname" ; Free pathname buffer -addsp65:ldy #64+1 +addsp65:ldy #FILENAME_MAX bne addsp ; Branch always ; Alloc and set length byte @@ -93,5 +94,5 @@ setlen: tya popname: ; Cleanup stack - ldy #1 + 64+1 ; Length byte + max pathname length + zero -addsp: jmp addysp ; Preserves A + ldy #1 + FILENAME_MAX +addsp: jmp addysp ; Preserves A and X diff --git a/libsrc/apple2/gettime.s b/libsrc/apple2/gettime.s index 7467b0189..829aaab3b 100644 --- a/libsrc/apple2/gettime.s +++ b/libsrc/apple2/gettime.s @@ -4,7 +4,8 @@ ; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp); ; - .import pushax, steaxspidx, incsp1, incsp3, return0 + .import pushax, incsp1, incsp3, steaxspidx, return0 + .import _mktime_dt .include "time.inc" .include "zeropage.inc" @@ -29,42 +30,12 @@ _clock_gettime: jsr callmli bcs oserr - ; Get date - lda DATELO+1 - lsr - php ; Save month msb - cmp #70 ; Year < 70? - bcs :+ ; No, leave alone - adc #100 ; Move 19xx to 20xx -: sta TM + tm::tm_year - lda DATELO - tax ; Save day - plp ; Restore month msb - ror - lsr - lsr - lsr - lsr - beq erange ; [1..12] allows for validity check - tay - dey ; Move [1..12] to [0..11] - sty TM + tm::tm_mon - txa ; Restore day - and #%00011111 - sta TM + tm::tm_mday + ; Convert DATELO/TIMELO to time_t + lda #DATELO + jsr _mktime_dt - ; Get time - lda TIMELO+1 - sta TM + tm::tm_hour - lda TIMELO - sta TM + tm::tm_min - - ; Make time_t - lda #TM - jsr _mktime - - ; Store tv_sec + ; Store ldy #timespec::tv_sec jsr steaxspidx @@ -74,21 +45,8 @@ _clock_gettime: ; Return success jmp return0 - ; Load errno code -erange: lda #ERANGE - - ; Cleanup stack - jsr incsp3 ; Preserves A - - ; Set __errno - jmp ___directerrno - ; Cleanup stack oserr: jsr incsp3 ; Preserves A ; Set ___oserror jmp ___mappederrno - - .bss - -TM: .tag tm diff --git a/libsrc/apple2/gmtime_dt.s b/libsrc/apple2/gmtime_dt.s new file mode 100644 index 000000000..a0b8e9f4d --- /dev/null +++ b/libsrc/apple2/gmtime_dt.s @@ -0,0 +1,73 @@ +; +; Oliver Schmidt, 14.08.2018 +; Colin Leroy-Mira, 2023 +; +; struct tm * __fastcall__ gmtime_dt(const struct datetime *dt) +; + + .export _gmtime_dt, tm_buf + + .include "time.inc" + .include "zeropage.inc" + .include "errno.inc" + .include "mli.inc" + + ; Convert ProDOS date/time to a struct tm + ; source date address in AX + ; on stack: + ; destination struct + +_gmtime_dt: + sta ptr1 + stx ptr1+1 + + ; Get time + ldy #$03 + lda (ptr1),y + sta tm_buf + tm::tm_hour + dey + lda (ptr1),y + sta tm_buf + tm::tm_min + + ; Get date + dey + lda (ptr1),y + lsr + php ; Save month msb + cmp #70 ; Year < 70? + bcs :+ ; No, leave alone + adc #100 ; Move 19xx to 20xx +: sta tm_buf + tm::tm_year + + dey + lda (ptr1),y + tax ; Save day + plp ; Restore month msb + ror + lsr + lsr + lsr + lsr + beq erange ; [1..12] allows for validity check + tay + dey ; Move [1..12] to [0..11] + sty tm_buf + tm::tm_mon + txa ; Restore day + and #%00011111 + sta tm_buf + tm::tm_mday + + lda #tm_buf + rts + + ; Load errno code and return NULL +erange: lda #ERANGE + sta ___errno + lda #$00 + tax + rts + + .bss + +tm_buf: + .tag tm diff --git a/libsrc/apple2/mktime_dt.s b/libsrc/apple2/mktime_dt.s new file mode 100644 index 000000000..415f52b9e --- /dev/null +++ b/libsrc/apple2/mktime_dt.s @@ -0,0 +1,37 @@ +; +; Oliver Schmidt, 14.08.2018 +; Colin Leroy-Mira, 2023 +; +; time_t __fastcall__ mktime_dt(const struct datetime *dt) +; + + .import steaxspidx, pushax, incsp2, _gmtime_dt + .import tm_buf + .export _mktime_dt + + .include "time.inc" + .include "zeropage.inc" + .include "errno.inc" + .include "mli.inc" + + ; Convert ProDOS date/time to UNIX timestamp + ; source date address in AX + +_mktime_dt: + ; Convert to internal tm + jsr _gmtime_dt + cpx #$00 + bne :+ + cmp #$00 + beq err + + ; Make time_t +: lda #tm_buf + jmp _mktime + +err: lda #$00 + tax + sta sreg + sta sreg+1 + rts diff --git a/libsrc/apple2/mli.inc b/libsrc/apple2/mli.inc index 42363d9c9..382a071b0 100644 --- a/libsrc/apple2/mli.inc +++ b/libsrc/apple2/mli.inc @@ -83,8 +83,8 @@ EOF_COUNT = 2 AUX_TYPE .word STORAGE_TYPE .byte BLOCKS .word - MODE_DATE .word - MODE_TIME .word + MOD_DATE .word + MOD_TIME .word CREATE_DATE .word CREATE_TIME .word .endstruct @@ -139,3 +139,6 @@ LEVEL := $BF94 ; File level: used in open, flush, close MACHID := $BF98 ; Machine identification PFIXPTR := $BF9A ; If = 0, no prefix active KVERSION:= $BFFF ; Kernel version number + +; Max filename length +FILENAME_MAX = 64+1 diff --git a/libsrc/apple2/mli_file_info.s b/libsrc/apple2/mli_file_info.s new file mode 100644 index 000000000..16e01c07f --- /dev/null +++ b/libsrc/apple2/mli_file_info.s @@ -0,0 +1,33 @@ +; +; Colin Leroy-Mira, 2023 +; + + .export mli_file_info + .import pushname, popname, mli_file_info_direct + .import popax + .include "zeropage.inc" + .include "errno.inc" + .include "mli.inc" + + ; Calls ProDOS MLI GET_FILE_INFO on the filename + ; stored as C string in AX at top of stack + ; Returns with carry set on error, and sets errno +mli_file_info: + ; Get pathname + jsr popax + jsr pushname + bne oserr + + jsr mli_file_info_direct + php ; Save return status + + jsr popname ; Preserves A + + plp + bcs oserr + rts + +oserr: + jsr ___mappederrno + sec + rts diff --git a/libsrc/apple2/mli_file_info_direct.s b/libsrc/apple2/mli_file_info_direct.s new file mode 100644 index 000000000..c15ebc28f --- /dev/null +++ b/libsrc/apple2/mli_file_info_direct.s @@ -0,0 +1,22 @@ +; +; Colin Leroy-Mira, 2023 +; + + .export mli_file_info_direct + .include "zeropage.inc" + .include "mli.inc" + + ; Calls ProDOS MLI GET_FILE_INFO on the ProDOS style + ; filename stored on top of stack + ; Returns with carry set on error, and sets errno +mli_file_info_direct: + ; Set pushed name + lda sp + ldx sp+1 + sta mliparam + MLI::INFO::PATHNAME + stx mliparam + MLI::INFO::PATHNAME+1 + + ; Get file information + lda #GET_INFO_CALL + ldx #GET_INFO_COUNT + jmp callmli diff --git a/libsrc/apple2/open.s b/libsrc/apple2/open.s index 68c203cd6..38793a13e 100644 --- a/libsrc/apple2/open.s +++ b/libsrc/apple2/open.s @@ -18,6 +18,7 @@ .include "fcntl.inc" .include "mli.inc" .include "filedes.inc" + .include "time.inc" .segment "ONCE" diff --git a/libsrc/apple2/stat.s b/libsrc/apple2/stat.s new file mode 100644 index 000000000..f655b3e3f --- /dev/null +++ b/libsrc/apple2/stat.s @@ -0,0 +1,129 @@ +; +; Colin Leroy-Mira, 2023 +; +; int __fastcall__ stat(const char *pathname, struct stat *statbuf); +; + + .export _stat + .import __errno, _open,_close + .import mli_file_info + .import popax, pushax, pusha0, incsp2 + .include "zeropage.inc" + .include "errno.inc" + .include "fcntl.inc" + .include "filedes.inc" + .include "mli.inc" + .include "stat.inc" + +_stat: + ; Store statbuf pointer + sta ptr4 + sta stbuf + stx ptr4+1 + stx stbuf+1 + + ; Clear statbuf + lda #$00 + ldy #.sizeof(stat)-1 +: sta (ptr4),y + dey + bpl :- + + ; Reset errno + sta ___errno + + ; Store pathname + jsr popax + jsr pushax ; Push it back for mli_file_info + jsr pushax ; and for open + + jsr mli_file_info + + bcc got_info + jmp incsp2 ; Drop filename copy for open + +got_info: + ; st_dev + lda DEVNUM + lsr ; Shift right to cc65 representation + lsr + lsr + lsr + ldy #stat::st_dev + sta (ptr4),y + + ; st_mode (S_IFDIR/S_IFREG only) + lda mliparam + MLI::INFO::FILE_TYPE + ldy #stat::st_mode + cmp #$0f + bne is_reg + lda #S_IFDIR + bne set_st_mode + +is_reg: lda #S_IFREG + +set_st_mode: + sta (ptr4),y + + ; st_access through st_create_time + ldx #MLI::INFO::ACCESS + ldy #stat::st_access +: lda mliparam,x + sta (ptr4),y + inx + iny + cpy #stat::st_create_time + .sizeof(stat::st_create_time) + bne :- + + ; st_size + lda #O_RDONLY + jsr pusha0 + ldy #$04 + jsr _open + cmp #$FF + beq done + pha ; Save file descriptor for closing + + ; Get ProDOS's REF_NUM from file descriptor + jsr getfd + ; Get file information + sta mliparam + MLI::EOF::REF_NUM + lda #GET_EOF_CALL + ldx #EOF_COUNT + jsr callmli + bcs eoferr + + ; Get struct stat in ptr4 back, open destroyed it + lda stbuf + ldx stbuf+1 + sta ptr4 + stx ptr4+1 + + ; Store size + ldy #stat::st_size + lda mliparam + MLI::EOF::EOF + sta (ptr4),y + lda mliparam + MLI::EOF::EOF+1 + iny + sta (ptr4),y + lda mliparam + MLI::EOF::EOF+2 + iny + sta (ptr4),y + + ; Close file +eoferr: + pla + ldx #$00 + jsr _close + + ; Set return value if we had an error + lda ___errno + beq done + lda #$FF +done: + tax + rts + + .bss + +stbuf: .res 2 diff --git a/libsrc/apple2/statvfs.s b/libsrc/apple2/statvfs.s new file mode 100644 index 000000000..6274bb52b --- /dev/null +++ b/libsrc/apple2/statvfs.s @@ -0,0 +1,125 @@ +; +; Colin Leroy-Mira, 2023 +; +; int __fastcall__ statvfs(const char *pathname, struct statvfs *statvfsbuf); +; + + .export _statvfs + .import _dio_query_sectsize + .import mli_file_info, pushax, popax, popptr1 + .include "zeropage.inc" + .include "apple2.inc" + .include "errno.inc" + .include "mli.inc" + .include "statvfs.inc" + +_statvfs: + ; Store statbuf + sta ptr4 + stx ptr4+1 + + ; Clear statbuf + lda #$00 + ldy #.sizeof(statvfs)-1 +: sta (ptr4),y + dey + bpl :- + + ; Store pathname, keeping only volume name + jsr popptr1 + ldy #$00 + sty vol_sep + lda (ptr1),y + cmp #'/' ; Is the path absolute? + beq :+ + lda #EINVAL + jmp ___directerrno + +: iny + lda (ptr1),y + beq :+ ; End of string, no other / + cpy #FILENAME_MAX + beq :+ ; Max filename length reached + cmp #'/' + bne :- ; Not a slash, keep looking + sty vol_sep ; Register '/' index + lda #$00 + sta (ptr1),y ; Cut pathname at first slash +: lda ptr1 + ldx ptr1+1 + jsr pushax + + jsr mli_file_info + + php + ldy vol_sep ; Put slash back in pathname + lda #'/' + sta (ptr1),y + plp + + bcc got_info + + jmp ___mappederrno + +got_info: + ; f_fsid + lda DEVNUM + lsr ; Shift right to cc65 representation + lsr + lsr + lsr + ldy #statvfs::f_fsid + sta (ptr4),y + + ; total number of blocks + lda mliparam + MLI::INFO::AUX_TYPE + ldy #statvfs::f_blocks + sta (ptr4),y + lda mliparam + MLI::INFO::AUX_TYPE+1 + iny + sta (ptr4),y + + ; blocks free & avail + sec + lda mliparam + MLI::INFO::AUX_TYPE + sbc mliparam + MLI::INFO::BLOCKS + ldy #statvfs::f_bfree + sta (ptr4),y + ldy #statvfs::f_bavail + sta (ptr4),y + + lda mliparam + MLI::INFO::AUX_TYPE+1 + sbc mliparam + MLI::INFO::BLOCKS+1 + iny + sta (ptr4),y + ldy #statvfs::f_bfree+1 + sta (ptr4),y + + ; block sizes + jsr _dio_query_sectsize + ; low bytes + ldy #statvfs::f_bsize + sta (ptr4),y + ldy #statvfs::f_frsize + sta (ptr4),y + ; f_frsize high byte + iny + txa + sta (ptr4),y + ; f_bsize high byte + ldy #statvfs::f_bsize+1 + sta (ptr4),y + + ; f_namemax + lda #FILENAME_MAX + ldy #statvfs::f_namemax + sta (ptr4),y + + lda #$00 + sta ___errno + tax + rts + + .bss + +vol_sep:.res 1 diff --git a/libsrc/apple2/targetutil/convert.c b/libsrc/apple2/targetutil/convert.c index ea9273fc3..52dffa745 100644 --- a/libsrc/apple2/targetutil/convert.c +++ b/libsrc/apple2/targetutil/convert.c @@ -108,7 +108,7 @@ static unsigned get_dir_entry(char* p_name) } /* Field header_pointer directly follows field last_mod */ - cur_addr = *(unsigned*)(&dirent->d_mtime.hour + 1); + cur_addr = *(unsigned*)(&dirent->d_mtime.time.hour + 1); dhandle = dio_open(getcurrentdevice()); if (!dhandle) { From 075ece5fafef1834cf2c349c1e08658f452410d5 Mon Sep 17 00:00:00 2001 From: Stefan Date: Wed, 3 Jan 2024 16:35:12 +0100 Subject: [PATCH 074/707] Clean-up void is always fast --- include/rp6502.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/rp6502.h b/include/rp6502.h index 033684b72..2b40cfc71 100644 --- a/include/rp6502.h +++ b/include/rp6502.h @@ -72,8 +72,8 @@ void __fastcall__ ria_push_long (unsigned long val); void __fastcall__ ria_push_int (unsigned int val); #define ria_push_char(v) RIA.xstack = v -long __fastcall__ ria_pop_long (void); -int __fastcall__ ria_pop_int (void); +long ria_pop_long (void); +int ria_pop_int (void); #define ria_pop_char() RIA.xstack /* Set the RIA fastcall register */ @@ -118,9 +118,9 @@ long __fastcall__ ria_call_long_errno (unsigned char op); /* C API for the operating system. */ int __cdecl__ xreg (char device, char channel, unsigned char address, ...); -int __fastcall__ phi2 (void); -int __fastcall__ codepage (void); -long __fastcall__ lrand (void); +int phi2 (void); +int codepage (void); +long lrand (void); int __fastcall__ stdin_opt (unsigned long ctrl_bits, unsigned char str_length); int __fastcall__ read_xstack (void* buf, unsigned count, int fildes); int __fastcall__ read_xram (unsigned buf, unsigned count, int fildes); From dc9d2f0dbd2a7969e5e86501fa6727421512a8a1 Mon Sep 17 00:00:00 2001 From: Stefan Date: Wed, 3 Jan 2024 16:46:07 +0100 Subject: [PATCH 075/707] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f8a0d4ff2..eff5049f9 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ External contributors: * [Stephan Mühlstrasser](https://github.com/smuehlst): osic1p target * [Wayne Parham](https://github.com/WayneParham): Sym-1 target * [Dave Plummer](https://github.com/davepl): KIM-1 target +* [rumbledethumps](https://github.com/rumbledethumps): Picocomputer target *(The above list is incomplete, if you feel left out - please speak up or add yourself in a PR)* From 726b70a5342e57fe7744db55ed98a6e9c5cc884b Mon Sep 17 00:00:00 2001 From: jedeoric Date: Fri, 5 Jan 2024 00:45:03 +0100 Subject: [PATCH 076/707] add XMAINARGS and XGETARGV for Telestrat --- asminc/telestrat.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index c57bd3de8..7623c4d05 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -257,8 +257,11 @@ XBINDX = $28 ; Convert a number into hex and displays on chan XDECIM = $29 XHEXA = $2A ; Convert a number into hex +XMAINARGS = $2C ; Only available for Orix (Alternative OS) + XEDT = $2D ; Launch editor XINSER = $2E +XGETARGV = $2E ; Only available for Orix (Alternative OS) XSCELG = $2F ; Search a line in editor mode XOPEN = $30 ; Only in Orix From bcea5dfa8f353c0aa64c90cdbc4a05e19540d5ff Mon Sep 17 00:00:00 2001 From: jedeoric Date: Fri, 5 Jan 2024 00:46:15 +0100 Subject: [PATCH 077/707] fix comment telestrat --- asminc/telestrat.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asminc/telestrat.inc b/asminc/telestrat.inc index 7623c4d05..bbfabdf40 100644 --- a/asminc/telestrat.inc +++ b/asminc/telestrat.inc @@ -257,11 +257,11 @@ XBINDX = $28 ; Convert a number into hex and displays on chan XDECIM = $29 XHEXA = $2A ; Convert a number into hex -XMAINARGS = $2C ; Only available for Orix (Alternative OS) +XMAINARGS = $2C ; Only available for Orix XEDT = $2D ; Launch editor XINSER = $2E -XGETARGV = $2E ; Only available for Orix (Alternative OS) +XGETARGV = $2E ; Only available for Orix XSCELG = $2F ; Search a line in editor mode XOPEN = $30 ; Only in Orix From 169c9c0da0c86a2067a927af34a64f528ec2d31e Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Fri, 5 Jan 2024 19:38:51 +0100 Subject: [PATCH 078/707] Add strdup tests --- test/val/lib_common_strdup.c | 60 ++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 test/val/lib_common_strdup.c diff --git a/test/val/lib_common_strdup.c b/test/val/lib_common_strdup.c new file mode 100644 index 000000000..748317017 --- /dev/null +++ b/test/val/lib_common_strdup.c @@ -0,0 +1,60 @@ +#include +#include "unittest.h" + +#define SHORT_STR "abcdefghijklmnopqrstuvwxyz" + +#define MID_STR_LEN 700 /* Two pages and something */ +#define LONG_STR_LEN 40000UL /* Two long to duplicate */ +TEST +{ + char *dst; + char *src; + int i; + + dst = strdup(""); + ASSERT_IsTrue(dst != NULL, "strdup returned NULL") + ASSERT_IsTrue(!strcmp(dst, ""), "strings differ"); + free(dst); + + dst = strdup(SHORT_STR); + ASSERT_IsTrue(dst != NULL, "strdup returned NULL"); + ASSERT_IsTrue(strlen(dst) == strlen(SHORT_STR), "string lengths differ"); + ASSERT_IsTrue(!strcmp(dst, SHORT_STR), "strings differ"); + free(dst); + + src = malloc(MID_STR_LEN+1); + ASSERT_IsTrue(src != NULL, "Could not allocate source string"); + memset(src, 'a', MID_STR_LEN-1); + src[MID_STR_LEN] = '\0'; + + dst = strdup(src); + ASSERT_IsTrue(dst != NULL, "strdup returned NULL"); + printf("strlens %zu %zu\n", strlen(src), strlen(dst)); + ASSERT_IsTrue(strlen(dst) == strlen(src), "string lengths differ"); + ASSERT_IsTrue(!strcmp(dst, src), "strings differ"); + free(dst); + free(src); + + src = malloc(LONG_STR_LEN+1); + ASSERT_IsTrue(src != NULL, "Could not allocate source string"); + memset(src, 'a', LONG_STR_LEN-1); + src[LONG_STR_LEN] = '\0'; + + dst = strdup(src); + ASSERT_IsTrue(dst == NULL, "strdup did not return NULL"); + free(src); + + for (i = 254; i < 258; i++) { + src = malloc(i+1); + memset(src, 'a', i-1); + src[i] = '\0'; + + dst = strdup(src); + ASSERT_IsTrue(dst != NULL, "strdup returned NULL"); + ASSERT_IsTrue(strlen(dst) == strlen(src), "string lengths differ"); + ASSERT_IsTrue(!strcmp(dst, src), "strings differ"); + free (dst); + free(src); + } +} +ENDTEST From 29801a2fde4a78c9bc489d5367e109957411e5eb Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sat, 6 Jan 2024 17:53:24 +0100 Subject: [PATCH 079/707] remove extra format specifier, fixed #2330 --- test/val/bug1178-struct-copy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/val/bug1178-struct-copy.c b/test/val/bug1178-struct-copy.c index 7fb7e7803..322002c02 100644 --- a/test/val/bug1178-struct-copy.c +++ b/test/val/bug1178-struct-copy.c @@ -62,7 +62,7 @@ void dotest2(void) StructArray2[0] = test2; - printf ("test2: %d, %d, %d, %d, %d\n", + printf ("test2: %d, %d, %d, %d\n", (int)StructArray2[0].a, (int)StructArray2[0].b, (int)StructArray2[0].c, (int)StructArray2[0].d); if ((StructArray2[0].a != 42) || From 7ce982cc68212977cf86ed2cf0f123439393751e Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sun, 7 Jan 2024 10:19:48 +0100 Subject: [PATCH 080/707] Remove non-standard (and useless) include Fixes #2337 --- include/time.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/time.h b/include/time.h index 6cd0c8068..f8977ab0c 100644 --- a/include/time.h +++ b/include/time.h @@ -43,10 +43,6 @@ typedef unsigned long clock_t; -#include - - - /* NULL pointer */ #ifndef NULL #define NULL ((void *) 0) From 3a439e0e1b9c98fba7c3791d3bfb1074296ecb61 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Fri, 5 Jan 2024 19:39:03 +0100 Subject: [PATCH 081/707] Little strdup optimisation -12 bytes on disk -20 cycles per strdup -6 cycles per strlen called from strdup --- libsrc/common/strcspn.s | 8 ++-- libsrc/common/strdup.s | 93 ++++++++++++++++------------------------- libsrc/common/strlen.s | 15 +++---- libsrc/common/strspn.s | 8 ++-- 4 files changed, 51 insertions(+), 73 deletions(-) diff --git a/libsrc/common/strcspn.s b/libsrc/common/strcspn.s index 4bb01479a..418bf6ac2 100644 --- a/libsrc/common/strcspn.s +++ b/libsrc/common/strcspn.s @@ -7,13 +7,13 @@ .export _strcspn .import popptr1, _strlen - .importzp ptr1, ptr2, tmp1, tmp2 + .importzp ptr1, ptr4, tmp1, tmp2 _strcspn: - jsr _strlen ; get length in a/x and transfer s2 to ptr2 + jsr _strlen ; get length in a/x and transfer s2 to ptr4 ; Note: It does not make sense to ; have more than 255 test chars, so - ; we don't support a high byte here! (ptr2+1 is + ; we don't support a high byte here! (ptr4+1 is ; also unchanged in strlen then (important!)) ; -> the original implementation also ; ignored this case @@ -38,7 +38,7 @@ checkNext: iny check: cpy tmp1 ; compare with length of test character string beq endOfTestChars - cmp (ptr2),y ; found matching char? + cmp (ptr4),y ; found matching char? bne checkNext leave: txa ; restore position of finding diff --git a/libsrc/common/strdup.s b/libsrc/common/strdup.s index 3ab07bda1..94f2cd338 100644 --- a/libsrc/common/strdup.s +++ b/libsrc/common/strdup.s @@ -1,85 +1,62 @@ ; ; Ullrich von Bassewitz, 18.07.2000 +; Colin Leroy-Mira, 05.01.2024 ; ; char* __fastcall__ strdup (const char* S); ; -; Note: The code knowns which zero page locations are used by malloc. +; Note: The code knowns which zero page locations are used by malloc, +; memcpy and strlen. ; - .importzp sp, tmp1, ptr4 - .import pushax, decsp4, incsp4 - .import _strlen, _malloc, _memcpy + .importzp ptr2, ptr3, ptr4, tmp1, tmp2, tmp3 + .import _strlen_ptr4, _malloc, _memcpy, pushax .export _strdup .macpack cpu - .macpack generic _strdup: + ; Get length (and store source in ptr4) + sta ptr4 + stx ptr4+1 + stx tmp1 ; Backup high byte, which + jsr _strlen_ptr4 ; strlen may increment -; Since we need some place to store the intermediate results, allocate a -; stack frame. To make this somewhat more efficient, create the stackframe -; as needed for the final call to the memcpy function. - - pha ; decsp will destroy A (but not X) - jsr decsp4 ; Target/source - -; Store the pointer into the source slot - - ldy #1 - txa - sta (sp),y - pla -.if (.cpu .bitand CPU_ISET_65SC02) - sta (sp) + ; Add null byte for terminator +.if (.cpu .bitand ::CPU_ISET_65SC02) + inc a .else - dey - sta (sp),y + clc + adc #1 .endif - -; Get length of S (which is still in a/x) - - jsr _strlen - -; Calculate strlen(S)+1 (the space needed) - - add #1 - bcc @L1 + bne :+ inx -; Save the space we're about to allocate in ptr4 - -@L1: sta ptr4 - stx ptr4+1 - -; Allocate memory. _malloc will not use ptr4 + ; Store length +: sta tmp2 + stx tmp3 + ; Allocate memory jsr _malloc -; Store the result into the target stack slot - - ldy #2 - sta (sp),y ; Store low byte - sta tmp1 - txa ; Get high byte - iny - sta (sp),y ; Store high byte - -; Check for a NULL pointer - - ora tmp1 + ; Check for NULL + bne :+ + cpx #$00 beq OutOfMemory -; Copy the string. memcpy will return the target string which is exactly -; what we need here. It will also drop the allocated stack frame. + ; Push dest +: jsr pushax + ; Push source lda ptr4 - ldx ptr4+1 ; Load size - jmp _memcpy ; Copy string, drop stackframe + ldx tmp1 + jsr pushax -; Out of memory, return NULL (A = 0) + ; Push length + lda tmp2 + ldx tmp3 + + ; Copy and return the dest pointer + jmp _memcpy OutOfMemory: - tax - jmp incsp4 ; Drop stack frame - - + rts diff --git a/libsrc/common/strlen.s b/libsrc/common/strlen.s index 8d5bc20fc..c20ab78f9 100644 --- a/libsrc/common/strlen.s +++ b/libsrc/common/strlen.s @@ -2,19 +2,20 @@ ; Ullrich von Bassewitz, 31.05.1998 ; ; Note: strspn & strcspn call internally this function and rely on -; the usage of only ptr2 here! Keep in mind when appling changes +; the usage of only ptr4 here! Keep in mind when appling changes ; and check the other implementations too! ; ; size_t __fastcall__ strlen (const char* s); ; - .export _strlen - .importzp ptr2 + .export _strlen, _strlen_ptr4 + .importzp ptr4 .macpack cpu _strlen: - sta ptr2 ; Save s - stx ptr2+1 + sta ptr4 ; Save s + stx ptr4+1 +_strlen_ptr4: .if (.cpu .bitand ::CPU_ISET_HUC6280) clx cly @@ -27,11 +28,11 @@ _strlen: .endif .endif -L1: lda (ptr2),y +L1: lda (ptr4),y beq L9 iny bne L1 - inc ptr2+1 + inc ptr4+1 inx bne L1 diff --git a/libsrc/common/strspn.s b/libsrc/common/strspn.s index 6fda716be..7e3f707d1 100644 --- a/libsrc/common/strspn.s +++ b/libsrc/common/strspn.s @@ -7,13 +7,13 @@ .export _strspn .import popptr1, _strlen - .importzp ptr1, ptr2, tmp1, tmp2 + .importzp ptr1, ptr4, tmp1, tmp2 _strspn: - jsr _strlen ; get length in a/x and transfer s2 to ptr2 + jsr _strlen ; get length in a/x and transfer s2 to ptr4 ; Note: It does not make sense to ; have more than 255 test chars, so - ; we don't support a high byte here! (ptr2+1 is + ; we don't support a high byte here! (ptr4+1 is ; also unchanged in strlen then (important!)) ; -> the original implementation also ; ignored this case @@ -38,7 +38,7 @@ checkNext: iny check: cpy tmp1 ; compare with length of test character string beq leave - cmp (ptr2),y ; found matching char? + cmp (ptr4),y ; found matching char? bne checkNext foundTestChar: From df193c0947b890ea433e590e9042b0a9c6b537c0 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sun, 7 Jan 2024 22:58:45 +0100 Subject: [PATCH 082/707] Rework time functions a bit - mktime: Work unsigned as time_t's type implies (shifting Y2K38 bug to 2106) - mktime: Add unit tests - gmtime/localtime: factorize - gmtime/localtime: Add unit tests - mktime/gmtime/localtime: Size optimisation (-130 bytes wrt master) - mktime: Speed optimisation (from 23M cycles on the unit test to 2M) --- libsrc/common/_is_leap_year.h | 22 ++++++ libsrc/common/_is_leap_year.s | 23 ++++++ libsrc/common/{gmtime.c => _time_t_to_tm.c} | 11 +-- libsrc/common/gmtime.s | 20 +++++ libsrc/common/localtime.c | 60 --------------- libsrc/common/localtime.s | 29 +++++++ libsrc/common/mktime.c | 64 +++++++--------- test/val/lib_common_gmtime_localtime.c | 84 +++++++++++++++++++++ test/val/lib_common_mktime.c | 61 +++++++++++++++ 9 files changed, 268 insertions(+), 106 deletions(-) create mode 100644 libsrc/common/_is_leap_year.h create mode 100644 libsrc/common/_is_leap_year.s rename libsrc/common/{gmtime.c => _time_t_to_tm.c} (94%) create mode 100644 libsrc/common/gmtime.s delete mode 100644 libsrc/common/localtime.c create mode 100644 libsrc/common/localtime.s create mode 100644 test/val/lib_common_gmtime_localtime.c create mode 100644 test/val/lib_common_mktime.c diff --git a/libsrc/common/_is_leap_year.h b/libsrc/common/_is_leap_year.h new file mode 100644 index 000000000..378c462ff --- /dev/null +++ b/libsrc/common/_is_leap_year.h @@ -0,0 +1,22 @@ +/* +** _is_leap_year.h +** +** (C) Copyright 2024, Colin Leroy-Mira +** +*/ + + + +#ifndef __IS_LEAP_YEAR_H +#define __IS_LEAP_YEAR_H + + + +unsigned char __fastcall__ IsLeapYear (unsigned char Year); +/* Returns 1 if the given year is a leap year. Expects a year from 0 to 206, + * without 1900 added */ + + + +/* End of _is_leap_year.h */ +#endif diff --git a/libsrc/common/_is_leap_year.s b/libsrc/common/_is_leap_year.s new file mode 100644 index 000000000..d3136c1c8 --- /dev/null +++ b/libsrc/common/_is_leap_year.s @@ -0,0 +1,23 @@ +; +; Colin Leroy-Mira, 2024 +; +; unsigned char __fastcall__ IsLeapYear (unsigned char Year) +; Returns 1 in A if the given year is a leap year. Expects a year from 0 to 206, +; without 1900 added. +; + + .export _IsLeapYear + +_IsLeapYear: + ldx #$00 ; Prepare X for rts + cmp #$00 ; Y 0 (1900) is not a leap year + beq NotLeap + cmp #$C8 ; Y 200 (2100) is not a leap year + beq NotLeap + and #$03 ; Year % 4 == 0 means leap year + bne NotLeap + lda #$01 ; Return 1 + rts +NotLeap: + lda #$00 ; Return 0 + rts diff --git a/libsrc/common/gmtime.c b/libsrc/common/_time_t_to_tm.c similarity index 94% rename from libsrc/common/gmtime.c rename to libsrc/common/_time_t_to_tm.c index 85e9de3d0..684cff752 100644 --- a/libsrc/common/gmtime.c +++ b/libsrc/common/_time_t_to_tm.c @@ -42,18 +42,9 @@ /*****************************************************************************/ - -struct tm* __fastcall__ gmtime (const time_t* timep) +struct tm* __fastcall__ _time_t_to_tm (const time_t t) { static struct tm timebuf; - time_t t; - - /* Check the argument */ - if (timep == 0 || (long) (t = *timep) < 0) { - /* Invalid arg */ - return 0; - } - /* Since our ints are just 16 bits, split the given time into seconds, ** hours and days. Each of the values will fit in a 16 bit variable. ** The mktime routine will then do the rest. diff --git a/libsrc/common/gmtime.s b/libsrc/common/gmtime.s new file mode 100644 index 000000000..288b285eb --- /dev/null +++ b/libsrc/common/gmtime.s @@ -0,0 +1,20 @@ +; +; Colin Leroy-Mira, 2024 +; +; struct tm* __fastcall__ gmtime (const time_t* timep); +; + + .export _gmtime + .import __time_t_to_tm + .import ldeaxi + +_gmtime: + cpx #$00 ; Check for null pointer + bne :+ + cmp #$00 + beq no_pointer +: jsr ldeaxi ; Load value from pointer + jmp __time_t_to_tm ; Convert it + +no_pointer: + rts ; A/X already set diff --git a/libsrc/common/localtime.c b/libsrc/common/localtime.c deleted file mode 100644 index 48931ea62..000000000 --- a/libsrc/common/localtime.c +++ /dev/null @@ -1,60 +0,0 @@ -/*****************************************************************************/ -/* */ -/* localtime.c */ -/* */ -/* Convert calendar time into broken down local time */ -/* */ -/* */ -/* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -struct tm* __fastcall__ localtime (const time_t* timep) -{ - time_t t; - - /* Check for a valid time spec */ - if (timep == 0) { - return 0; - } - - /* Get the time and correct for the time zone offset */ - t = *timep + _tz.timezone; - - /* Use gmtime for conversion */ - return gmtime (&t); -} diff --git a/libsrc/common/localtime.s b/libsrc/common/localtime.s new file mode 100644 index 000000000..279442c9d --- /dev/null +++ b/libsrc/common/localtime.s @@ -0,0 +1,29 @@ +; +; Colin Leroy-Mira, 2024 +; +; struct tm* __fastcall__ localtime (const time_t* timep); +; + + .export _localtime + .import __time_t_to_tm, __tz + .import ldeaxi, tosaddeax, pusheax + .importzp sreg + +_localtime: + cpx #$00 ; Check for null pointer + bne :+ + cmp #$00 + beq no_pointer +: jsr ldeaxi ; Load value + jsr pusheax ; Push it + lda __tz+1+3 + sta sreg+1 + lda __tz+1+2 + sta sreg + ldx __tz+1+1 + lda __tz+1 + jsr tosaddeax ; Add _tz.timezone + jmp __time_t_to_tm ; Convert to struct tm + +no_pointer: + rts ; A/X already set diff --git a/libsrc/common/mktime.c b/libsrc/common/mktime.c index 275589dbb..c9ac1652c 100644 --- a/libsrc/common/mktime.c +++ b/libsrc/common/mktime.c @@ -36,7 +36,7 @@ #include #include #include - +#include "_is_leap_year.h" /*****************************************************************************/ @@ -67,14 +67,6 @@ static const unsigned MonthDays [] = { -static unsigned char __fastcall__ IsLeapYear (unsigned Year) -/* Returns 1 if the given year is a leap year */ -{ - return (((Year % 4) == 0) && ((Year % 100) != 0 || (Year % 400) == 0)); -} - - - time_t __fastcall__ mktime (register struct tm* TM) /* Make a time in seconds since 1/1/1970 from the broken down time in TM. ** A call to mktime does also correct the time in TM to contain correct @@ -82,13 +74,13 @@ time_t __fastcall__ mktime (register struct tm* TM) */ { register div_t D; - int Max; - unsigned DayCount; + static int Max; + static unsigned DayCount; /* Check if TM is valid */ if (TM == 0) { /* Invalid data */ - goto Error; + return (time_t) -1L; } /* Adjust seconds. */ @@ -96,27 +88,29 @@ time_t __fastcall__ mktime (register struct tm* TM) TM->tm_sec = D.rem; /* Adjust minutes */ - if (TM->tm_min + D.quot < 0) { - goto Error; - } TM->tm_min += D.quot; D = div (TM->tm_min, 60); TM->tm_min = D.rem; /* Adjust hours */ - if (TM->tm_hour + D.quot < 0) { - goto Error; - } TM->tm_hour += D.quot; D = div (TM->tm_hour, 24); TM->tm_hour = D.rem; /* Adjust days */ - if (TM->tm_mday + D.quot < 0) { - goto Error; - } TM->tm_mday += D.quot; + /* Adjust year */ + while (1) { + Max = 365UL + IsLeapYear (TM->tm_year); + if ((unsigned int)TM->tm_mday > Max) { + ++TM->tm_year; + TM->tm_mday -= Max; + } else { + break; + } + } + /* Adjust month and year. This is an iterative process, since changing ** the month will change the allowed days for this month. */ @@ -125,20 +119,17 @@ time_t __fastcall__ mktime (register struct tm* TM) /* Make sure, month is in the range 0..11 */ D = div (TM->tm_mon, 12); TM->tm_mon = D.rem; - if (TM->tm_year + D.quot < 0) { - goto Error; - } TM->tm_year += D.quot; /* Now check if mday is in the correct range, if not, correct month ** and eventually year and repeat the process. */ - if (TM->tm_mon == FEBRUARY && IsLeapYear (TM->tm_year + 1900)) { + if (TM->tm_mon == FEBRUARY && IsLeapYear (TM->tm_year)) { Max = 29; } else { Max = MonthLength[TM->tm_mon]; } - if (TM->tm_mday > Max) { + if ((unsigned int)TM->tm_mday > Max) { /* Must correct month and eventually, year */ if (TM->tm_mon == DECEMBER) { TM->tm_mon = JANUARY; @@ -157,19 +148,27 @@ time_t __fastcall__ mktime (register struct tm* TM) ** year. */ TM->tm_yday = MonthDays[TM->tm_mon] + TM->tm_mday - 1; - if (TM->tm_mon > FEBRUARY && IsLeapYear (TM->tm_year + 1900)) { + if (TM->tm_mon > FEBRUARY && IsLeapYear (TM->tm_year)) { ++TM->tm_yday; } /* Calculate days since 1/1/1970. In the complete epoch (1/1/1970 to - ** somewhere in 2038) all years dividable by 4 are leap years, so - ** dividing by 4 gives the days that must be added cause of leap years. + ** somewhere in 2106) all years dividable by 4 are leap years(1), + ** so dividing by 4 gives the days that must be added because of leap years. ** (and the last leap year before 1970 was 1968) + ** (1): Exception on 2100, which is not leap, and handled just after. */ DayCount = ((unsigned) (TM->tm_year-70)) * 365U + (((unsigned) (TM->tm_year-(68+1))) / 4) + TM->tm_yday; + /* Handle the 2100 exception */ + if (TM->tm_year == 200 && TM->tm_mon > FEBRUARY) { + DayCount--; + } else if (TM->tm_year > 200) { + DayCount--; + } + /* Calculate the weekday */ TM->tm_wday = (JAN_1_1970 + DayCount) % 7; @@ -182,11 +181,4 @@ time_t __fastcall__ mktime (register struct tm* TM) ((unsigned) TM->tm_min) * 60U + ((unsigned) TM->tm_sec) - _tz.timezone; - -Error: - /* Error exit */ - return (time_t) -1L; } - - - diff --git a/test/val/lib_common_gmtime_localtime.c b/test/val/lib_common_gmtime_localtime.c new file mode 100644 index 000000000..143d15831 --- /dev/null +++ b/test/val/lib_common_gmtime_localtime.c @@ -0,0 +1,84 @@ +#include +#include +#include + +int fails = 0; + +time_t timestamps[] = { + 0, + 0x2FFFFFFF, + 0x6FFFFFFF, + 0xF48656FF, + 0xF4865700, + 0xFC5A3EFF, + 0x6D6739FF, + 0x6D673A00, + 0xFFFFFFFF, +}; + +/* Values checked against glibc 2.37's implementation of ctime() */ +const char *dates_gmt[] = { + "Thu Jan 1 00:00:00 1970\n", + "Sun Jul 9 16:12:47 1995\n", + "Wed Jul 18 05:49:51 2029\n", + "Thu Dec 31 23:59:59 2099\n", + "Fri Jan 1 00:00:00 2100\n", + "Fri Feb 29 23:59:59 2104\n", + "Tue Feb 29 23:59:59 2028\n", + "Wed Mar 1 00:00:00 2028\n", + "Sun Feb 7 06:28:15 2106\n", + NULL +}; + +const char *dates_gmt_plus_one[] = { + "Thu Jan 1 01:00:00 1970\n", + "Sun Jul 9 17:12:47 1995\n", + "Wed Jul 18 06:49:51 2029\n", + "Fri Jan 1 00:59:59 2100\n", + "Fri Jan 1 01:00:00 2100\n", + "Sat Mar 1 00:59:59 2104\n", + "Wed Mar 1 00:59:59 2028\n", + "Wed Mar 1 01:00:00 2028\n", + "Thu Jan 1 00:59:59 1970\n", + NULL +}; + +int main (void) +{ + int i; + + for (i = 0; dates_gmt[i] != NULL; i++) { + struct tm *tm; + char *str; + + /* Check gmtime */ + tm = gmtime(×tamps[i]); + str = asctime(tm); + if (strcmp(str, dates_gmt[i])) { + fails++; + printf("gmtime: Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n", + timestamps[i], dates_gmt[i], str); + } + + /* Check localtime with UTC timezone */ + _tz.timezone = 0; + tm = localtime(×tamps[i]); + str = asctime(tm); + if (strcmp(str, dates_gmt[i])) { + fails++; + printf("localtime: Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n", + timestamps[i], dates_gmt[i], str); + } + + /* Check localtime at UTC+1 */ + _tz.timezone = 3600; + tm = localtime(×tamps[i]); + str = asctime(tm); + if (strcmp(str, dates_gmt_plus_one[i])) { + fails++; + printf("localtime: Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n", + timestamps[i], dates_gmt_plus_one[i], str); + } + } + return fails; +} diff --git a/test/val/lib_common_mktime.c b/test/val/lib_common_mktime.c new file mode 100644 index 000000000..832ce3834 --- /dev/null +++ b/test/val/lib_common_mktime.c @@ -0,0 +1,61 @@ +#include +#include +#include + +int fails = 0; + +time_t timestamps[] = { + 0, + 0x2FFFFFFF, + 0x6FFFFFFF, + 0xF48656FF, + 0xF4865700, + 0xFC5A3EFF, + 0x6D6739FF, + 0x6D673A00, + 0xFFFFFFFF, +}; + +/* Values checked against glibc 2.37's implementation of ctime() */ +const char *dates[] = { + "Thu Jan 1 00:00:00 1970\n", + "Sun Jul 9 16:12:47 1995\n", + "Wed Jul 18 05:49:51 2029\n", + "Thu Dec 31 23:59:59 2099\n", + "Fri Jan 1 00:00:00 2100\n", + "Fri Feb 29 23:59:59 2104\n", + "Tue Feb 29 23:59:59 2028\n", + "Wed Mar 1 00:00:00 2028\n", + "Sun Feb 7 06:28:15 2106\n", + NULL +}; + +int main (void) +{ + struct tm tm; + time_t t; + int i; + + /* Verify conversion both ways */ + for (t = 0x0FFFFFFF; ; t += 0x10000000) { + struct tm *tm = gmtime(&t); + time_t r = mktime(tm); + if (t != r) { + fails++; + printf("Unexpected result for t %lx: %lx\n", t, r); + } + if (t == 0xFFFFFFFF) { + break; + } + } + + for (i = 0; dates[i] != NULL; i++) { + char *str = ctime(×tamps[i]); + if (strcmp(str, dates[i])) { + fails++; + printf("Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n", + timestamps[i], dates[i], str); + } + } + return fails; +} From 2564aaa12c92e188f748ae59b7aae58c0c1dc4bd Mon Sep 17 00:00:00 2001 From: acqn Date: Wed, 10 Jan 2024 04:48:27 +0800 Subject: [PATCH 083/707] Refix for diagnosis on expected expressions. --- src/cc65/expr.c | 2 +- test/ref/bug1889-missing-identifier.c | 2 ++ test/ref/bug1889-missing-identifier.cref | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0f3a6e110..3ef141300 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1408,7 +1408,7 @@ static void Primary (ExprDesc* E) } else { /* Let's see if this is a C99-style declaration */ DeclSpec Spec; - ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT, SC_AUTO); + ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE, SC_AUTO); if ((Spec.Flags & DS_TYPE_MASK) != DS_NONE) { Error ("Mixed declarations and code are not supported in cc65"); diff --git a/test/ref/bug1889-missing-identifier.c b/test/ref/bug1889-missing-identifier.c index d9cf4aa52..a8140565f 100644 --- a/test/ref/bug1889-missing-identifier.c +++ b/test/ref/bug1889-missing-identifier.c @@ -3,6 +3,8 @@ int enum { a } x; inline enum { b }; +_Static_assert(); + int main(void) { return 0; diff --git a/test/ref/bug1889-missing-identifier.cref b/test/ref/bug1889-missing-identifier.cref index 7381d2032..6317657d1 100644 --- a/test/ref/bug1889-missing-identifier.cref +++ b/test/ref/bug1889-missing-identifier.cref @@ -1,3 +1,4 @@ bug1889-missing-identifier.c:3: Error: Identifier or ';' expected after declaration specifiers bug1889-missing-identifier.c:3: Warning: Implicit 'int' is an obsolete feature bug1889-missing-identifier.c:4: Error: Declaration specifier or identifier expected +bug1889-missing-identifier.c:6: Error: Expression expected From 94dfc08c0e439b46b0f1a0e625bca9609b02ff94 Mon Sep 17 00:00:00 2001 From: acqn Date: Wed, 10 Jan 2024 04:43:50 +0800 Subject: [PATCH 084/707] Fixed false "Non constant initializers" error messages on wrong places, which could be resulted from failed array declarations etc. --- src/cc65/expr.c | 12 +++++++++++- test/ref/custom-reference-error.c | 5 ++++- test/ref/custom-reference-error.cref | 3 ++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 3ef141300..9cf05d2dc 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -4305,8 +4305,13 @@ ExprDesc NoCodeConstExpr (void (*Func) (ExprDesc*)) if (!ED_IsConst (&Expr) || !ED_CodeRangeIsEmpty (&Expr)) { Error ("Constant expression expected"); /* To avoid any compiler errors, make the expression a valid const */ - Expr.Flags &= E_MASK_RTYPE | E_MASK_KEEP_RESULT; + Expr.Flags &= E_MASK_RTYPE | E_MASK_KEEP_MAKE; Expr.Flags |= E_LOC_NONE; + + /* Remove any non-constant code generated */ + if (!ED_CodeRangeIsEmpty (&Expr)) { + RemoveCodeRange (&Expr.Start, &Expr.End); + } } /* Return by value */ @@ -4331,6 +4336,11 @@ ExprDesc NoCodeConstAbsIntExpr (void (*Func) (ExprDesc*)) Error ("Constant integer expression expected"); /* To avoid any compiler errors, make the expression a valid const */ ED_MakeConstAbsInt (&Expr, 1); + + /* Remove any non-constant code generated */ + if (!ED_CodeRangeIsEmpty (&Expr)) { + RemoveCodeRange (&Expr.Start, &Expr.End); + } } /* Return by value */ diff --git a/test/ref/custom-reference-error.c b/test/ref/custom-reference-error.c index a7c1b6c56..e98fb024d 100644 --- a/test/ref/custom-reference-error.c +++ b/test/ref/custom-reference-error.c @@ -14,7 +14,7 @@ */ typedef short return_t; -#error /* produce an error */ +#error This is an/* produce an error */error return_t main(int argc, char* argv[]) { @@ -22,3 +22,6 @@ return_t main(int argc, char* argv[]) n = 0; /* produce an error */ /* produce a warning */ } + +int arr[main(0, 0)]; /* produce an error */ +int b = 0; diff --git a/test/ref/custom-reference-error.cref b/test/ref/custom-reference-error.cref index b21c72dce..9ffa581cd 100644 --- a/test/ref/custom-reference-error.cref +++ b/test/ref/custom-reference-error.cref @@ -1,6 +1,7 @@ -custom-reference-error.c:17: Error: #error +custom-reference-error.c:17: Error: #error: This is an error custom-reference-error.c:21: Error: Call to undeclared function 'printf' custom-reference-error.c:22: Error: Undeclared identifier 'n' custom-reference-error.c:24: Warning: Control reaches end of non-void function [-Wreturn-type] custom-reference-error.c:24: Warning: Parameter 'argc' is never used custom-reference-error.c:24: Warning: Parameter 'argv' is never used +custom-reference-error.c:26: Error: Constant integer expression expected From 8e43c4706f0b7cffa34155af8a2705a2c7ef8aae Mon Sep 17 00:00:00 2001 From: acqn Date: Wed, 10 Jan 2024 04:50:42 +0800 Subject: [PATCH 085/707] Added hierarchy info about source file inclusion in diagnostic output. Fixed presumed names of source files in disgnosis. Fixed line number of source files in debug output. --- src/cc65/codeseg.c | 2 +- src/cc65/error.c | 123 +++++++++++++++++++++++---------- src/cc65/error.h | 7 +- src/cc65/input.c | 165 +++++++++++++++++++++++++++++++++++++++----- src/cc65/input.h | 24 +++++-- src/cc65/lineinfo.c | 66 ++++++++++++++---- src/cc65/lineinfo.h | 41 ++++++++--- src/cc65/preproc.c | 8 +-- 8 files changed, 347 insertions(+), 89 deletions(-) diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 9f1bf4cc5..f4970b586 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -1471,7 +1471,7 @@ void CS_Output (CodeSeg* S) /* Add line debug info */ if (DebugInfo) { WriteOutput ("\t.dbg\tline, \"%s\", %u\n", - GetInputName (LI), GetInputLine (LI)); + GetActualFileName (LI), GetActualLineNum (LI)); } } /* Output the code */ diff --git a/src/cc65/error.c b/src/cc65/error.c index 5cd29b388..d6e7d7cbd 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -120,13 +120,46 @@ Collection DiagnosticStrBufs; +void PrintFileInclusionInfo (const LineInfo* LI) +/* Print hierarchy of file inclusion */ +{ + if (LI->IncFiles != 0) { + unsigned FileCount = CollCount (LI->IncFiles); + if (FileCount > 0) { + const char* Str = "In file included from %s:%u%c\n"; + + while (FileCount-- > 0) { + LineInfoFile* LIF = CollAtUnchecked (LI->IncFiles, FileCount); + char C = FileCount > 0 ? ',' : ':'; + + fprintf (stderr, Str, LIF->Name, LIF->LineNum, C); + Str = " from %s:%u%c\n"; + } + } + } +} + + + +static LineInfo* GetDiagnosticLI (void) +/* Get the line info where the diagnostic info refers to */ +{ + if (CurTok.LI) { + return CurTok.LI; + } else { + return GetCurLineInfo (); + } +} + + + static const char* GetDiagnosticFileName (void) /* Get the source file name where the diagnostic info refers to */ { if (CurTok.LI) { - return GetInputName (CurTok.LI); + return GetPresumedFileName (CurTok.LI); } else { - return GetCurrentFilename (); + return GetCurrentFileName (); } } @@ -136,7 +169,7 @@ static unsigned GetDiagnosticLineNum (void) /* Get the source line number where the diagnostic info refers to */ { if (CurTok.LI) { - return GetInputLine (CurTok.LI); + return GetPresumedLineNum (CurTok.LI); } else { return GetCurrentLineNum (); } @@ -199,10 +232,18 @@ void Internal (const char* Format, ...) -static void IntError (errcat_t EC, const char* Filename, unsigned LineNo, const char* Msg, va_list ap) +static void IntError (errcat_t EC, LineInfo* LI, const char* Msg, va_list ap) /* Print an error message - internal function */ { - fprintf (stderr, "%s:%u: Error: ", Filename, LineNo); + unsigned LineNo = GetPresumedLineNum (LI); + + /* Print file inclusion if appropriate */ + if (HasFileInclusionChanged (LI)) { + PrintFileInclusionInfo (LI); + } + RememberCheckedLI (LI); + + fprintf (stderr, "%s:%u: Error: ", GetPresumedFileName (LI), LineNo); vfprintf (stderr, Msg, ap); fprintf (stderr, "\n"); @@ -229,23 +270,23 @@ static void IntError (errcat_t EC, const char* Filename, unsigned LineNo, const -void Error (const char* Format, ...) -/* Print an error message */ +void LIError (errcat_t EC, LineInfo* LI, const char* Format, ...) +/* Print an error message with the line info given explicitly */ { va_list ap; va_start (ap, Format); - IntError (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap); + IntError (EC, LI, Format, ap); va_end (ap); } -void LIError (errcat_t EC, const LineInfo* LI, const char* Format, ...) -/* Print an error message with the line info given explicitly */ +void Error (const char* Format, ...) +/* Print an error message */ { va_list ap; va_start (ap, Format); - IntError (EC, GetInputName (LI), GetInputLine (LI), Format, ap); + IntError (EC_PARSER, GetDiagnosticLI (), Format, ap); va_end (ap); } @@ -256,7 +297,7 @@ void PPError (const char* Format, ...) { va_list ap; va_start (ap, Format); - IntError (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap); + IntError (EC_PP, GetCurLineInfo (), Format, ap); va_end (ap); } @@ -268,17 +309,25 @@ void PPError (const char* Format, ...) -static void IntWarning (errcat_t EC, const char* Filename, unsigned LineNo, const char* Msg, va_list ap) +static void IntWarning (errcat_t EC, LineInfo* LI, const char* Msg, va_list ap) /* Print a warning message - internal function */ { if (IS_Get (&WarningsAreErrors)) { /* Treat the warning as an error */ - IntError (EC, Filename, LineNo, Msg, ap); + IntError (EC, LI, Msg, ap); } else if (IS_Get (&WarnEnable)) { - fprintf (stderr, "%s:%u: Warning: ", Filename, LineNo); + unsigned LineNo = GetPresumedLineNum (LI); + + /* Print file inclusion if appropriate */ + if (HasFileInclusionChanged (LI)) { + PrintFileInclusionInfo (LI); + } + RememberCheckedLI (LI); + + fprintf (stderr, "%s:%u: Warning: ", GetPresumedFileName (LI), LineNo); vfprintf (stderr, Msg, ap); fprintf (stderr, "\n"); @@ -297,23 +346,23 @@ static void IntWarning (errcat_t EC, const char* Filename, unsigned LineNo, cons -void Warning (const char* Format, ...) -/* Print a warning message */ +void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...) +/* Print a warning message with the line info given explicitly */ { va_list ap; va_start (ap, Format); - IntWarning (EC_PARSER, GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap); + IntWarning (EC, LI, Format, ap); va_end (ap); } -void LIWarning (errcat_t EC, const LineInfo* LI, const char* Format, ...) -/* Print a warning message with the line info given explicitly */ +void Warning (const char* Format, ...) +/* Print a warning message */ { va_list ap; va_start (ap, Format); - IntWarning (EC, GetInputName (LI), GetInputLine (LI), Format, ap); + IntWarning (EC_PARSER, GetDiagnosticLI (), Format, ap); va_end (ap); } @@ -324,7 +373,7 @@ void PPWarning (const char* Format, ...) { va_list ap; va_start (ap, Format); - IntWarning (EC_PP, GetCurrentFilename(), GetCurrentLineNum(), Format, ap); + IntWarning (EC_PP, GetCurLineInfo (), Format, ap); va_end (ap); } @@ -365,33 +414,33 @@ void ListWarnings (FILE* F) -static void IntNote (const char* Filename, unsigned LineNo, const char* Msg, va_list ap) +static void IntNote (const LineInfo* LI, const char* Msg, va_list ap) /* Print a note message - internal function */ { - fprintf (stderr, "%s:%u: Note: ", Filename, LineNo); + fprintf (stderr, "%s:%u: Note: ", GetPresumedFileName (LI), GetPresumedLineNum (LI)); vfprintf (stderr, Msg, ap); fprintf (stderr, "\n"); } -void Note (const char* Format, ...) -/* Print a note message */ -{ - va_list ap; - va_start (ap, Format); - IntNote (GetDiagnosticFileName (), GetDiagnosticLineNum (), Format, ap); - va_end (ap); -} - - - void LINote (const LineInfo* LI, const char* Format, ...) /* Print a note message with the line info given explicitly */ { va_list ap; va_start (ap, Format); - IntNote (GetInputName (LI), GetInputLine (LI), Format, ap); + IntNote (LI, Format, ap); + va_end (ap); +} + + + +void Note (const char* Format, ...) +/* Print a note message */ +{ + va_list ap; + va_start (ap, Format); + IntNote (GetDiagnosticLI (), Format, ap); va_end (ap); } @@ -402,7 +451,7 @@ void PPNote (const char* Format, ...) { va_list ap; va_start (ap, Format); - IntNote (GetCurrentFilename(), GetCurrentLineNum(), Format, ap); + IntNote (GetDiagnosticLI (), Format, ap); va_end (ap); } diff --git a/src/cc65/error.h b/src/cc65/error.h index 4dce6cf91..5af862f9f 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -100,6 +100,9 @@ struct StrBuf; +void PrintFileInclusionInfo (const LineInfo* LI); +/* Print hierarchy of file inclusion */ + void Fatal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2))); /* Print a message about a fatal error and die */ @@ -109,7 +112,7 @@ void Internal (const char* Format, ...) attribute ((noreturn, format (printf, 1, void Error (const char* Format, ...) attribute ((format (printf, 1, 2))); /* Print an error message */ -void LIError (errcat_t EC, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4))); +void LIError (errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4))); /* Print an error message with the line info given explicitly */ void PPError (const char* Format, ...) attribute ((format (printf, 1, 2))); @@ -118,7 +121,7 @@ void PPError (const char* Format, ...) attribute ((format (printf, 1, 2))); void Warning (const char* Format, ...) attribute ((format (printf, 1, 2))); /* Print a warning message */ -void LIWarning (errcat_t EC, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4))); +void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4))); /* Print a warning message with the line info given explicitly */ void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2))); diff --git a/src/cc65/input.c b/src/cc65/input.c index 89c471687..fcf7f32f3 100644 --- a/src/cc65/input.c +++ b/src/cc65/input.c @@ -91,10 +91,11 @@ struct IFile { /* Struct that describes an active input file */ typedef struct AFile AFile; struct AFile { - unsigned Line; /* Line number for this file */ + unsigned LineNum; /* Actual line number for this file */ FILE* F; /* Input file stream */ IFile* Input; /* Points to corresponding IFile */ int SearchPath; /* True if we've added a path for this file */ + unsigned LineOffs; /* Offset to presumed line number for this file */ char* PName; /* Presumed name of the file */ PPIfStack IfStack; /* PP #if stack */ int MissingNL; /* Last input line was missing a newline */ @@ -111,6 +112,7 @@ static Collection* CurrentInputStack; /* Counter for the __COUNTER__ macro */ static unsigned MainFileCounter; +LineInfo* PrevDiagnosticLI; @@ -163,10 +165,11 @@ static AFile* NewAFile (IFile* IF, FILE* F) AFile* AF = (AFile*) xmalloc (sizeof (AFile)); /* Initialize the fields */ - AF->Line = 0; - AF->F = F; - AF->Input = IF; - AF->PName = 0; + AF->LineNum = 0; + AF->F = F; + AF->Input = IF; + AF->LineOffs = 0; + AF->PName = 0; AF->IfStack.Index = -1; AF->MissingNL = 0; @@ -285,7 +288,7 @@ void OpenMainFile (const char* Name) /* Update the line infos, so we have a valid line info even at start of ** the main file before the first line is read. */ - UpdateLineInfo (MainFile->Input, MainFile->Line, Line); + UpdateCurrentLineInfo (Line); /* Initialize the __COUNTER__ counter */ MainFileCounter = 0; @@ -553,7 +556,7 @@ int NextLine (void) if (!Input->MissingNL || SB_NotEmpty (Line)) { /* Accept files without a newline at the end */ - ++Input->Line; + ++Input->LineNum; /* Assume no new line */ Input->MissingNL = 1; @@ -569,7 +572,7 @@ int NextLine (void) if (C == '\n') { /* We got a new line */ - ++Input->Line; + ++Input->LineNum; /* If the \n is preceeded by a \r, remove the \r, so we can read ** DOS/Windows files under *nix. @@ -605,7 +608,7 @@ int NextLine (void) InitLine (Line); /* Create line information for this line */ - UpdateLineInfo (Input->Input, Input->Line, Line); + UpdateCurrentLineInfo (Line); /* Done */ return C != EOF || SB_NotEmpty (Line); @@ -645,15 +648,145 @@ int PreprocessNextLine (void) -const char* GetInputFile (const struct IFile* IF) -/* Return a filename from an IFile struct */ +static LineInfoFile* NewLineInfoFile (const AFile* AF) +{ + const char* Name = AF->PName == 0 ? AF->Input->Name : AF->PName; + unsigned Len = strlen (Name); + + /* Allocate memory for the file info and the file name */ + LineInfoFile* LIF = xmalloc (sizeof (LineInfoFile) + Len); + + /* Copy info */ + LIF->InputFile = AF->Input; + LIF->LineNum = AF->LineNum + AF->LineOffs; + memcpy (LIF->Name, Name, Len + 1); + + return LIF; +} + + + +void GetFileInclusionInfo (struct LineInfo* LI) +/* Get info about source file inclusion for LineInfo struct */ +{ + unsigned FileCount = CollCount (&AFiles); + + CHECK (FileCount > 0); + + /* Get the correct index */ + --FileCount; + + if (LI->IncFiles != 0) { + FreeFileInclusionInfo (LI); + } + LI->IncFiles = 0; + + if (LI->File != 0) { + xfree (LI->File); + } + + /* Copy info from the AFile */ + LI->File = NewLineInfoFile (CollAtUnchecked (&AFiles, FileCount)); + + /* Remember the actual line number */ + LI->ActualLineNum = ((AFile*)CollAtUnchecked (&AFiles, FileCount))->LineNum; + + if (FileCount > 0) { + /* The file is included from another */ + + /* Always use a new collection */ + LI->IncFiles = NewCollection (); + + while (FileCount-- > 0) { + /* Copy info from the AFile */ + LineInfoFile* LIF = NewLineInfoFile (CollAtUnchecked (&AFiles, FileCount)); + + /* Add this file */ + CollAppend (LI->IncFiles, LIF); + } + } +} + + + +void FreeFileInclusionInfo (struct LineInfo* LI) +/* Free info about source file inclusion for LineInfo struct */ +{ + if (LI->File != 0) { + xfree (LI->File); + LI->File = 0; + } + + if (LI->IncFiles != 0) { + unsigned I; + for (I = 0; I < CollCount (LI->IncFiles); ++I) { + CollAtUnchecked (LI->IncFiles, I); + } + FreeCollection (LI->IncFiles); + LI->IncFiles = 0; + } +} + + + +static int IsDifferentLineInfoFile (const LineInfoFile* Lhs, const LineInfoFile* Rhs) +/* Return true if the two files are different */ +{ + /* If the input files are the same but their presumed names are different, + ** we still consider the files same. + */ + return Lhs->InputFile != Rhs->InputFile || Lhs->LineNum != Rhs->LineNum; +} + + + +int HasFileInclusionChanged (const struct LineInfo* LI) +/* Return true if file inclusion has changed from last time */ +{ + if (LI->File != 0) { + LineInfo* PrevLI = GetPrevCheckedLI (); + + if (LI == PrevLI) { + return 0; + } + + if (PrevLI == 0) { + return 1; + } + + if (LI->IncFiles != 0) { + unsigned I; + + if (PrevLI->IncFiles == 0 || + CollCount (LI->IncFiles) != CollCount (PrevLI->IncFiles)) { + return 1; + } + + for (I = 0; I < CollCount (LI->IncFiles); ++I) { + /* If this refers to a different file, then the inclusion has changed */ + if (IsDifferentLineInfoFile (CollAtUnchecked (LI->IncFiles, I), + CollAtUnchecked (PrevLI->IncFiles, I))) { + return 1; + } + } + } + } + + /* Unchanged */ + return 0; +} + + + +const char* GetInputFileName (const struct IFile* IF) +/* Return the name of the file from an IFile struct */ { return IF->Name; } -const char* GetCurrentFilename (void) +const char* GetCurrentFileName (void) /* Return the name of the current input file */ { unsigned AFileCount = CollCount (&AFiles); @@ -674,7 +807,7 @@ unsigned GetCurrentLineNum (void) unsigned AFileCount = CollCount (&AFiles); if (AFileCount > 0) { const AFile* AF = CollLast (&AFiles); - return AF->Line; + return AF->LineNum + AF->LineOffs; } else { /* No open file */ return 0; @@ -684,18 +817,18 @@ unsigned GetCurrentLineNum (void) void SetCurrentLineNum (unsigned LineNum) -/* Set the line number in the current input file */ +/* Set the presumed line number in the current input file */ { unsigned AFileCount = CollCount (&AFiles); if (AFileCount > 0) { AFile* AF = CollLast (&AFiles); - AF->Line = LineNum; + AF->LineOffs = LineNum - AF->LineNum; } } -void SetCurrentFilename (const char* Name) +void SetCurrentFileName (const char* Name) /* Set the presumed name of the current input file */ { unsigned AFileCount = CollCount (&AFiles); diff --git a/src/cc65/input.h b/src/cc65/input.h index 9457bdf9b..9a5a76949 100644 --- a/src/cc65/input.h +++ b/src/cc65/input.h @@ -52,6 +52,10 @@ +/* Forwards */ +struct IFile; +struct LineInfo; + /* An enum that describes different types of input files. The members are ** choosen so that it is possible to combine them to bitsets */ @@ -61,9 +65,6 @@ typedef enum { IT_USRINC = 0x04, /* User include file (using "") */ } InputType; -/* Forward for an IFile structure */ -struct IFile; - /* The current input line */ extern StrBuf* Line; @@ -125,10 +126,19 @@ int PreprocessNextLine (void); ** main file. */ -const char* GetInputFile (const struct IFile* IF); -/* Return a filename from an IFile struct */ +void GetFileInclusionInfo (struct LineInfo* LI); +/* Get info about source file inclusion for LineInfo struct */ -const char* GetCurrentFilename (void); +void FreeFileInclusionInfo (struct LineInfo* LI); +/* Free info about source file inclusion for LineInfo struct */ + +int HasFileInclusionChanged (const struct LineInfo* LI); +/* Return true if file inclusion has changed from last time */ + +const char* GetInputFileName (const struct IFile* IF); +/* Return the name of the file from an IFile struct */ + +const char* GetCurrentFileName (void); /* Return the name of the current input file */ unsigned GetCurrentLineNum (void); @@ -137,7 +147,7 @@ unsigned GetCurrentLineNum (void); void SetCurrentLineNum (unsigned LineNum); /* Set the line number in the current input file */ -void SetCurrentFilename (const char* Name); +void SetCurrentFileName (const char* Name); /* Set the presumed name of the current input file */ unsigned GetCurrentCounter (void); diff --git a/src/cc65/lineinfo.c b/src/cc65/lineinfo.c index f5c2e2689..8639d27e9 100644 --- a/src/cc65/lineinfo.c +++ b/src/cc65/lineinfo.c @@ -56,6 +56,9 @@ /* Global pointer to line information for the current line */ static LineInfo* CurLineInfo = 0; +/* Global pointer to previously checked line information about file inclusion hierarchy */ +static LineInfo* PrevCheckedLI = 0; + /*****************************************************************************/ @@ -64,7 +67,7 @@ static LineInfo* CurLineInfo = 0; -static LineInfo* NewLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line) +static LineInfo* NewLineInfo (const StrBuf* Line) /* Create and return a new line info. Ref count will be 1. */ { unsigned Len; @@ -87,8 +90,9 @@ static LineInfo* NewLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* L /* Initialize the fields */ LI->RefCount = 1; - LI->InputFile = F; - LI->LineNum = LineNum; + LI->File = 0; + LI->IncFiles = 0; + GetFileInclusionInfo (LI); /* Copy the line, replacing tabs by spaces in the given line since tabs ** will give rather arbitrary results when used in the output later, and @@ -117,6 +121,7 @@ static LineInfo* NewLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* L static void FreeLineInfo (LineInfo* LI) /* Free a LineInfo structure */ { + FreeFileInclusionInfo (LI); xfree (LI); } @@ -156,8 +161,8 @@ LineInfo* GetCurLineInfo (void) -void UpdateLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line) -/* Update the line info - called if a new line is read */ +void UpdateCurrentLineInfo (const StrBuf* Line) +/* Update the current line info - called if a new line is read */ { /* If a current line info exists, release it */ if (CurLineInfo) { @@ -172,23 +177,60 @@ void UpdateLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line) } /* Create a new line info */ - CurLineInfo = NewLineInfo (F, LineNum, Line); + CurLineInfo = NewLineInfo (Line); } -const char* GetInputName (const LineInfo* LI) -/* Return the file name from a line info */ +void RememberCheckedLI (LineInfo* LI) +/* Remember the latest checked line info struct */ +{ + if (PrevCheckedLI != LI) { + if (PrevCheckedLI != 0) { + ReleaseLineInfo (PrevCheckedLI); + } + PrevCheckedLI = UseLineInfo (LI); + } +} + + + +LineInfo* GetPrevCheckedLI (void) +/* Get the latest checked line info struct */ +{ + return PrevCheckedLI; +} + + + +const char* GetPresumedFileName (const LineInfo* LI) +/* Return the presumed file name from a line info */ { PRECONDITION (LI != 0); - return GetInputFile (LI->InputFile); + return LI->File->Name; } -unsigned GetInputLine (const LineInfo* LI) -/* Return the line number from a line info */ +unsigned GetPresumedLineNum (const LineInfo* LI) +/* Return the presumed line number from a line info */ { PRECONDITION (LI != 0); - return LI->LineNum; + return LI->File->LineNum; +} + + + +const char* GetActualFileName (const struct LineInfo* LI) +/* Return the actual name of the source file from a line info struct */ +{ + return LI->File != 0 ? GetInputFileName (LI->File->InputFile) : ""; +} + + + +unsigned GetActualLineNum (const struct LineInfo* LI) +/* Return the actual line number of the source file from a line info struct */ +{ + return LI->ActualLineNum; } diff --git a/src/cc65/lineinfo.h b/src/cc65/lineinfo.h index f365b4f01..02e77cd9c 100644 --- a/src/cc65/lineinfo.h +++ b/src/cc65/lineinfo.h @@ -60,15 +60,24 @@ struct IFile; +/* Struct that describes an input file for line info */ +typedef struct LineInfoFile LineInfoFile; +struct LineInfoFile { + struct IFile* InputFile; /* Points to corresponding IFile */ + unsigned LineNum; /* Presumed line number for this file */ + char Name[1]; /* Presumed name of the file */ +}; + /* The text for the actual line is allocated at the end of the structure, so ** the size of the structure varies. */ typedef struct LineInfo LineInfo; struct LineInfo { - unsigned RefCount; /* Reference counter */ - struct IFile* InputFile; /* Input file for this line */ - unsigned LineNum; /* Line number */ - char Line[1]; /* Source code line */ + unsigned RefCount; /* Reference counter */ + LineInfoFile* File; /* Presumed input files for this line */ + unsigned ActualLineNum; /* Actual line number for this file */ + struct Collection* IncFiles; /* Presumed inclusion input files */ + char Line[1]; /* Text of source code line */ }; @@ -92,14 +101,26 @@ LineInfo* GetCurLineInfo (void); ** increased, use UseLineInfo for that purpose. */ -void UpdateLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line); -/* Update the line info - called if a new line is read */ +void UpdateCurrentLineInfo (const StrBuf* Line); +/* Update the current line info - called if a new line is read */ -const char* GetInputName (const LineInfo* LI); -/* Return the file name from a line info */ +void RememberCheckedLI (struct LineInfo* LI); +/* Remember the latest checked line info struct */ -unsigned GetInputLine (const LineInfo* LI); -/* Return the line number from a line info */ +LineInfo* GetPrevCheckedLI (void); +/* Get the latest checked line info struct */ + +const char* GetPresumedFileName (const LineInfo* LI); +/* Return the presumed file name from a line info */ + +unsigned GetPresumedLineNum (const LineInfo* LI); +/* Return the presumed line number from a line info */ + +const char* GetActualFileName (const struct LineInfo* LI); +/* Return the actual name of the source file from a line info struct */ + +unsigned GetActualLineNum (const struct LineInfo* LI); +/* Return the actual line number of the source file from a line info struct */ diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 0a9b94bf2..66cbb2a9d 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -842,7 +842,7 @@ static void AddPreLine (StrBuf* Str) SB_AppendChar (Str, '\n'); } SB_Printf (&Comment, "#line %u \"%s\"\n", - GetCurrentLineNum () - ContinuedLines, GetCurrentFilename ()); + GetCurrentLineNum () - ContinuedLines, GetCurrentFileName ()); SB_Append (Str, &Comment); } else { /* Output new lines */ @@ -2943,7 +2943,7 @@ static void DoLine (void) StrBuf Filename = AUTO_STRBUF_INITIALIZER; if (SB_GetString (Line, &Filename)) { SB_Terminate (&Filename); - SetCurrentFilename (SB_GetConstBuf (&Filename)); + SetCurrentFileName (SB_GetConstBuf (&Filename)); } else { PPError ("Invalid filename for #line directive"); LineNum = 0; @@ -3220,7 +3220,7 @@ void HandleSpecialMacro (Macro* M, const char* Name) } else if (strcmp (Name, "__FILE__") == 0) { /* Replace __FILE__ with the current filename */ StrBuf B = AUTO_STRBUF_INITIALIZER; - SB_InitFromString (&B, GetCurrentFilename ()); + SB_InitFromString (&B, GetCurrentFileName ()); SB_Clear (&M->Replacement); Stringize (&B, &M->Replacement); SB_Done (&B); @@ -3332,7 +3332,7 @@ void Preprocess (void) PLine = InitLine (PLine); if (Verbosity > 1 && SB_NotEmpty (Line)) { - printf ("%s:%u: %.*s\n", GetCurrentFilename (), GetCurrentLineNum (), + printf ("%s:%u: %.*s\n", GetCurrentFileName (), GetCurrentLineNum (), (int) SB_GetLen (Line), SB_GetConstBuf (Line)); } From 2682fc0b7934743f59b564e550b7bc3d262f494e Mon Sep 17 00:00:00 2001 From: acqn Date: Wed, 10 Jan 2024 04:51:20 +0800 Subject: [PATCH 086/707] Fixed regression on comparison to null pointer. --- src/cc65/expr.c | 18 ++++++------ src/cc65/exprdesc.c | 41 ++++++++++++++++++++++---- src/cc65/exprdesc.h | 16 +++++++++- test/val/nullptr.c | 71 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 16 deletions(-) create mode 100644 test/val/nullptr.c diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0f3a6e110..74005cb04 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1991,7 +1991,7 @@ void hie10 (ExprDesc* Expr) if (ED_IsConstAbs (Expr)) { /* Constant numeric expression */ Expr->IVal = !Expr->IVal; - } else if (ED_IsAddrExpr (Expr)) { + } else if (ED_IsEntityAddr (Expr)) { /* Address != NULL, so !Address == 0 */ ED_MakeConstBool (Expr, 0); } else { @@ -2445,8 +2445,8 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ } /* Check for numeric constant operands */ - if ((ED_IsAddrExpr (Expr) && ED_IsNullPtr (&Expr2)) || - (ED_IsNullPtr (Expr) && ED_IsAddrExpr (&Expr2))) { + if ((ED_IsEntityAddr (Expr) && ED_IsNullPtr (&Expr2)) || + (ED_IsNullPtr (Expr) && ED_IsEntityAddr (&Expr2))) { /* Object addresses are inequal to null pointer */ Expr->IVal = (Tok != TOK_EQ); @@ -2477,8 +2477,8 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */ pop (ltype); } - } else if (ED_IsAddrExpr (Expr) && - ED_IsAddrExpr (&Expr2) && + } else if (ED_IsEntityAddr (Expr) && + ED_IsEntityAddr (&Expr2) && Expr->Sym == Expr2.Sym) { /* Evaluate the result for static addresses */ @@ -3944,10 +3944,10 @@ static void hieQuest (ExprDesc* Expr) NextToken (); /* Parse second expression. Remember for later if it is a NULL pointer - ** expression, then load it into the primary. + ** constant expression, then load it into the primary. */ ExprWithCheck (hie0, &Expr2); - Expr2IsNULL = ED_IsNullPtr (&Expr2); + Expr2IsNULL = ED_IsNullPtrConstant (&Expr2); if (!IsTypeVoid (Expr2.Type) && ED_YetToLoad (&Expr2) && (!ConstantCond || !ED_IsConst (&Expr2))) { @@ -3991,10 +3991,10 @@ static void hieQuest (ExprDesc* Expr) ConsumeColon (); /* Parse third expression. Remember for later if it is a NULL pointer - ** expression, then load it into the primary. + ** constant expression, then load it into the primary. */ ExprWithCheck (hieQuest, &Expr3); - Expr3IsNULL = ED_IsNullPtr (&Expr3); + Expr3IsNULL = ED_IsNullPtrConstant (&Expr3); if (!IsTypeVoid (Expr3.Type) && ED_YetToLoad (&Expr3) && (!ConstantCond || !ED_IsConst (&Expr3))) { diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index a21e56623..08be1091d 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -255,7 +255,7 @@ int ED_IsConstTrue (const ExprDesc* Expr) { /* Non-zero arithmetics and objects addresses are boolean true */ return (ED_IsConstAbsInt (Expr) && Expr->IVal != 0) || - (ED_IsAddrExpr (Expr)); + ED_IsEntityAddr (Expr); } @@ -331,12 +331,41 @@ int ED_IsZPInd (const ExprDesc* Expr) int ED_IsNullPtr (const ExprDesc* Expr) -/* Return true if the given expression is a NULL pointer constant */ +/* Return true if the given expression is a null pointer. +** Note: A null pointer constant converted to a pointer type is a null pointer. +*/ { - return (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE)) == - (E_LOC_NONE|E_RTYPE_RVAL) && - Expr->IVal == 0 && - IsClassInt (Expr->Type); + return ED_IsConstAbs (Expr) && + Expr->IVal == 0 && + (IsClassInt (Expr->Type) || IsTypePtr (Expr->Type)); +} + + + +int ED_IsNullPtrConstant (const ExprDesc* Expr) +/* Return true if the given expression is a null pointer constant. +** Note: An integer constant expression with value 0, or such an +** expression cast to void* is a null pointer constant. However, a +** null pointer constant converted to a pointer type is just a null +** pointer, not necessarily a constant in ISO C. +*/ +{ + return ED_IsConstAbs (Expr) && + Expr->IVal == 0 && + (IsClassInt (Expr->Type) || + (IsTypePtr (Expr->Type) && IsTypeVoid (Expr->Type + 1) && + GetQualifier (Expr->Type + 1) == T_QUAL_NONE)); +} + + + +int ED_IsEntityAddr (const ExprDesc* Expr) +/* Return true if the expression denotes the address of an object or function. +*/ +{ + return ED_IsAddrExpr (Expr) && + Expr->Sym != 0 && + (IsClassPtr (Expr->Type) || IsTypeFunc (Expr->Type)); } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 148485764..f6009a8a9 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -582,7 +582,21 @@ int ED_IsZPInd (const ExprDesc* Expr); /* Return true if the expression is located on the zeropage */ int ED_IsNullPtr (const ExprDesc* Expr); -/* Return true if the given expression is a NULL pointer constant */ +/* Return true if the given expression is a null pointer. +** Note: A null pointer constant converted to a pointer type is a null pointer. +*/ + +int ED_IsNullPtrConstant (const ExprDesc* Expr); +/* Return true if the given expression is a null pointer constant. +** Note: An integer constant expression with value 0, or such an +** expression cast to void* is a null pointer constant. However, a +** null pointer constant converted to a pointer type is just a null +** pointer, not necessarily a constant in ISO C. +*/ + +int ED_IsEntityAddr (const ExprDesc* Expr); +/* Return true if the expression denotes the address of an object or function. +*/ int ED_IsBool (const ExprDesc* Expr); /* Return true if the expression can be treated as a boolean, that is, it can diff --git a/test/val/nullptr.c b/test/val/nullptr.c new file mode 100644 index 000000000..e64b82ee2 --- /dev/null +++ b/test/val/nullptr.c @@ -0,0 +1,71 @@ +/* Bug # - Pointer compared to null pointer constant */ + +#include + +unsigned failures; + +struct S { + char a[4]; +} *p; + +#define TEST_NULL(E) \ + do { \ + a = (E) == 0 && !(E); \ + if (!a) \ + { \ + ++failures; \ + printf("failed: " #E " should be null\n"); \ + } \ + } while(0); + +#define TEST_NON_NULL(E) \ + do { \ + a = (E) != 0 && !!(E) && (E); \ + if (!a) \ + { \ + ++failures; \ + printf("failed: " #E " should be non-null\n"); \ + } \ + } while(0); + +int main() +{ + int a; + + /* Null pointer constant (per ISO C) compared equal to null pointer constant */ + TEST_NULL((void*)0) + + /* Null pointer compared equal to null pointer constant */ + TEST_NULL((char*)0) + + /* Null pointer obtained with -> */ + TEST_NULL(((struct S*)0)->a) + + /* Null pointer obtained with -> */ + TEST_NULL(p->a) + + /* Null pointer obtained with cast and -> */ + TEST_NULL(((struct S*)(a = 0))->a) + + /* Null pointer obtained with cast and -> */ + TEST_NULL((a = 0, ((struct S*)a)->a)) + + /* Non-null pointer obtained with cast and -> */ + TEST_NON_NULL(((struct S*)(long)(a = 0x1234))->a) + + /* Non-null pointer obtained with cast and -> */ + TEST_NON_NULL((a = 0x1234, ((struct S*)a)->a)) + + /* Non-null pointer obtained with cast and -> */ + TEST_NON_NULL(((struct S*)&a)->a) + + /* Non-null pointer obtained with cast and -> */ + TEST_NON_NULL(((struct S*)&main)->a) + + if (failures != 0) + { + printf("failures: %u\n", failures); + } + + return failures; +} From 38dac907e8f3afcf269601a977f65a55cb44ad42 Mon Sep 17 00:00:00 2001 From: acqn Date: Wed, 10 Jan 2024 04:51:59 +0800 Subject: [PATCH 087/707] Cleanup for symbol types and flags. --- src/cc65/asmstmt.c | 25 +++---- src/cc65/compile.c | 57 ++++++++------- src/cc65/declare.c | 38 +++++----- src/cc65/expr.c | 31 ++++---- src/cc65/exprdesc.h | 2 +- src/cc65/goto.c | 2 +- src/cc65/locals.c | 47 ++++++------ src/cc65/pragma.c | 2 +- src/cc65/symentry.c | 97 ++++++++++++++++--------- src/cc65/symentry.h | 142 ++++++++++++++++++++++++++----------- src/cc65/symtab.c | 169 ++++++++++++++++++++++++-------------------- src/cc65/symtab.h | 7 +- 12 files changed, 364 insertions(+), 255 deletions(-) diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index 166d05434..8521f0a81 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -80,9 +80,9 @@ static void AsmErrorSkip (void) -static SymEntry* AsmGetSym (unsigned Arg, unsigned Type) -/* Find the symbol with the name currently in NextTok. The symbol must be of -** the given type. On errors, NULL is returned. +static SymEntry* AsmGetSym (unsigned Arg, int OnStack) +/* Find the symbol with the name currently in NextTok. The symbol must be on +** the stack if OnStack is true. On errors, NULL is returned. */ { SymEntry* Sym; @@ -110,8 +110,8 @@ static SymEntry* AsmGetSym (unsigned Arg, unsigned Type) /* We found the symbol - skip the name token */ NextToken (); - /* Check if we have a global symbol */ - if ((Sym->Flags & Type) != Type) { + /* Check if the symbol is on the stack */ + if ((Sym->Flags & SC_STORAGEMASK) != SC_AUTO ? OnStack : !OnStack) { Error ("Type of argument %u differs from format specifier", Arg); AsmErrorSkip (); return 0; @@ -218,23 +218,24 @@ static void ParseGVarArg (StrBuf* T, unsigned Arg) */ { /* Parse the symbol name parameter and check the type */ - SymEntry* Sym = AsmGetSym (Arg, SC_STATIC); + SymEntry* Sym = AsmGetSym (Arg, 0); if (Sym == 0) { /* Some sort of error */ return; } - /* Check for external linkage */ - if (Sym->Flags & (SC_EXTERN | SC_STORAGE | SC_FUNC)) { - /* External linkage or a function */ + /* Get the correct asm name */ + if ((Sym->Flags & SC_TYPEMASK) == SC_FUNC || SymIsGlobal (Sym)) { + /* External or internal linkage or a function */ SB_AppendChar (T, '_'); SB_AppendStr (T, Sym->Name); - } else if (Sym->Flags & SC_REGISTER) { + } else if ((Sym->Flags & SC_STORAGEMASK) == SC_REGISTER) { + /* Register variable */ char Buf[32]; xsprintf (Buf, sizeof (Buf), "regbank+%d", Sym->V.R.RegOffs); SB_AppendStr (T, Buf); } else { - /* Static variable */ + /* Local static variable */ SB_AppendStr (T, LocalDataLabelName (Sym->V.L.Label)); } } @@ -248,7 +249,7 @@ static void ParseLVarArg (StrBuf* T, unsigned Arg) char Buf [16]; /* Parse the symbol name parameter and check the type */ - SymEntry* Sym = AsmGetSym (Arg, SC_AUTO); + SymEntry* Sym = AsmGetSym (Arg, 1); if (Sym == 0) { /* Some sort of error */ return; diff --git a/src/cc65/compile.c b/src/cc65/compile.c index aaa017453..108c80a28 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -121,15 +121,13 @@ static void Parse (void) } /* Read the declaration specifier */ - ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT, SC_EXTERN | SC_STATIC); + ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT, SC_NONE); /* Don't accept illegal storage classes */ - if ((Spec.StorageClass & SC_TYPEMASK) == 0) { - if ((Spec.StorageClass & SC_AUTO) != 0 || - (Spec.StorageClass & SC_REGISTER) != 0) { - Error ("Illegal storage class"); - Spec.StorageClass = SC_EXTERN | SC_STATIC; - } + if ((Spec.StorageClass & SC_STORAGEMASK) == SC_AUTO || + (Spec.StorageClass & SC_STORAGEMASK) == SC_REGISTER) { + Error ("Illegal storage class"); + Spec.StorageClass &= ~SC_STORAGEMASK; } /* Check if this is only a type declaration */ @@ -172,26 +170,26 @@ static void Parse (void) ** - if the storage class is explicitly specified as static, ** - or if there is an initialization. ** - ** This means that "extern int i;" will not get storage allocated. + ** This means that "extern int i;" will not get storage allocated + ** in this translation unit. */ - if ((Decl.StorageClass & SC_FUNC) != SC_FUNC && + if ((Decl.StorageClass & SC_TYPEMASK) != SC_FUNC && (Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { - if ((Spec.Flags & DS_DEF_STORAGE) != 0 || - (Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC || - ((Decl.StorageClass & SC_EXTERN) != 0 && + /* The variable is visible in the file scope */ + if ((Decl.StorageClass & SC_STORAGEMASK) == SC_NONE || + (Decl.StorageClass & SC_STORAGEMASK) == SC_STATIC || + ((Decl.StorageClass & SC_STORAGEMASK) == SC_EXTERN && CurTok.Tok == TOK_ASSIGN)) { - /* We will allocate storage */ - Decl.StorageClass |= SC_STORAGE; - } else { - /* It's a declaration */ - Decl.StorageClass |= SC_DECL; + /* We will allocate storage in this translation unit */ + Decl.StorageClass |= SC_TU_STORAGE; } } /* If this is a function declarator that is not followed by a comma ** or semicolon, it must be followed by a function body. */ - if ((Decl.StorageClass & SC_FUNC) != 0) { + if ((Decl.StorageClass & SC_TYPEMASK) == SC_FUNC) { + /* The function is now visible in the file scope */ if (CurTok.Tok == TOK_LCURLY) { /* A definition */ Decl.StorageClass |= SC_DEF; @@ -205,8 +203,6 @@ static void Parse (void) } } else { /* Just a declaration */ - Decl.StorageClass |= SC_DECL; - FuncDef = GetFuncDesc (Decl.Type); if ((FuncDef->Flags & (FD_EMPTY | FD_OLDSTYLE)) == FD_OLDSTYLE) { /* A parameter list without types is only allowed in a @@ -224,7 +220,7 @@ static void Parse (void) SymUseAttr (Sym, &Decl); /* Reserve storage for the variable if we need to */ - if (Decl.StorageClass & SC_STORAGE) { + if (Decl.StorageClass & SC_TU_STORAGE) { /* Get the size of the variable */ unsigned Size = SizeOf (Decl.Type); @@ -327,9 +323,13 @@ static void Parse (void) } /* Make the symbol zeropage according to the segment address size */ - if ((Sym->Flags & SC_STATIC) != 0) { - if (GetSegAddrSize (GetSegName (CS->CurDSeg)) == ADDR_SIZE_ZP) { - Sym->Flags |= SC_ZEROPAGE; + if ((Sym->Flags & SC_TYPEMASK) == SC_NONE) { + if (SymIsGlobal (Sym) || + (Sym->Flags & SC_STORAGEMASK) == SC_STATIC || + (Sym->Flags & SC_STORAGEMASK) == SC_REGISTER) { + if (GetSegAddrSize (GetSegName (CS->CurDSeg)) == ADDR_SIZE_ZP) { + Sym->Flags |= SC_ZEROPAGE; + } } } @@ -517,7 +517,10 @@ void Compile (const char* FileName) ** global variables. */ for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) { - if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) { + /* Is it a global (with or without static) tentative declaration of + ** an uninitialized variable? + */ + if ((Entry->Flags & (SC_TU_STORAGE | SC_DEF)) == SC_TU_STORAGE) { /* Assembly definition of uninitialized global variable */ SymEntry* TagSym = GetESUTagSym (Entry->Type); unsigned Size = SizeOf (Entry->Type); @@ -552,9 +555,9 @@ void Compile (const char* FileName) Entry->Name, GetFullTypeName (Entry->Type)); } - } else if (!SymIsDef (Entry) && (Entry->Flags & SC_FUNC) == SC_FUNC) { + } else if (!SymIsDef (Entry) && (Entry->Flags & SC_TYPEMASK) == SC_FUNC) { /* Check for undefined functions */ - if ((Entry->Flags & (SC_EXTERN | SC_STATIC)) == SC_STATIC && SymIsRef (Entry)) { + if ((Entry->Flags & SC_STORAGEMASK) == SC_STATIC && SymIsRef (Entry)) { Warning ("Static function '%s' used but never defined", Entry->Name); } diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 2666a8d31..f93305f01 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -91,7 +91,7 @@ static unsigned ParseOneStorageClass (void) switch (CurTok.Tok) { case TOK_EXTERN: - StorageClass = SC_EXTERN | SC_STATIC; + StorageClass = SC_EXTERN; NextToken (); break; @@ -101,7 +101,7 @@ static unsigned ParseOneStorageClass (void) break; case TOK_REGISTER: - StorageClass = SC_REGISTER | SC_STATIC; + StorageClass = SC_REGISTER; NextToken (); break; @@ -136,9 +136,9 @@ static int ParseStorageClass (DeclSpec* Spec) } while (StorageClass != 0) { - if (Spec->StorageClass == 0) { - Spec->StorageClass = StorageClass; - } else if (Spec->StorageClass == StorageClass) { + if ((Spec->StorageClass & SC_STORAGEMASK) == 0) { + Spec->StorageClass |= StorageClass; + } else if ((Spec->StorageClass & SC_STORAGEMASK) == StorageClass) { Warning ("Duplicate storage class specifier"); } else { Error ("Conflicting storage class specifier"); @@ -618,12 +618,12 @@ static SymEntry* ForwardESU (const char* Name, unsigned Flags, unsigned* DSFlags */ SymEntry* TagEntry = FindTagSym (Name); if (TagEntry == 0) { - if ((Flags & SC_ESUTYPEMASK) != SC_ENUM) { + if ((Flags & SC_TYPEMASK) != SC_ENUM) { TagEntry = AddStructSym (Name, Flags, 0, 0, DSFlags); } else { TagEntry = AddEnumSym (Name, Flags, 0, 0, DSFlags); } - } else if ((TagEntry->Flags & SC_TYPEMASK) != (Flags & SC_ESUTYPEMASK)) { + } else if ((TagEntry->Flags & SC_TYPEMASK) != (Flags & SC_TYPEMASK)) { /* Already defined, but not the same type class */ Error ("Symbol '%s' is already different kind", Name); } @@ -798,7 +798,7 @@ static SymEntry* ParseEnumSpec (const char* Name, unsigned* DSFlags) } /* Add an entry of the enumerator to the symbol table */ - AddConstSym (Ident, NewType, SC_ENUMERATOR | SC_CONST, EnumVal); + AddConstSym (Ident, NewType, SC_DEF | SC_ENUMERATOR, EnumVal); /* Use this type for following members */ MemberType = NewType; @@ -1825,8 +1825,8 @@ static void ParseOldStyleParamDeclList (FuncDesc* F attribute ((unused))) /* We accept only auto and register as storage class specifiers, but ** we ignore all this, since we use auto anyway. */ - if ((Spec.StorageClass & SC_AUTO) == 0 && - (Spec.StorageClass & SC_REGISTER) == 0) { + if ((Spec.StorageClass & SC_STORAGEMASK) != SC_AUTO && + (Spec.StorageClass & SC_STORAGEMASK) != SC_REGISTER) { Error ("Illegal storage class"); } @@ -1942,12 +1942,12 @@ static void ParseAnsiParamList (FuncDesc* F) ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE, SC_AUTO); /* We accept only auto and register as storage class specifiers */ - if ((Spec.StorageClass & SC_AUTO) == SC_AUTO) { - Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF; - } else if ((Spec.StorageClass & SC_REGISTER) == SC_REGISTER) { - Spec.StorageClass = SC_REGISTER | SC_STATIC | SC_PARAM | SC_DEF; + if ((Spec.StorageClass & SC_STORAGEMASK) == SC_REGISTER) { + Spec.StorageClass = SC_REGISTER | SC_PARAM | SC_DEF; } else { - Error ("Illegal storage class"); + if ((Spec.StorageClass & SC_STORAGEMASK) != SC_AUTO) { + Error ("Illegal storage class"); + } Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF; } @@ -2355,7 +2355,9 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) D->StorageClass = Spec->StorageClass; /* If we have a function, add a special symbol type */ - if (IsTypeFunc (D->Type)) { + if (Mode != DM_ACCEPT_PARAM_IDENT && + IsTypeFunc (D->Type) && + (D->StorageClass & SC_TYPEMASK) == SC_NONE) { D->StorageClass |= SC_FUNC; } @@ -2479,9 +2481,9 @@ void ParseDeclSpec (DeclSpec* Spec, typespec_t TSFlags, unsigned DefStorage) ParseTypeSpec (Spec, TSFlags | TS_STORAGE_CLASS_SPEC | TS_FUNCTION_SPEC); /* If no explicit storage class is given, use the default */ - if (Spec->StorageClass == 0) { + if ((Spec->StorageClass & SC_STORAGEMASK) == 0) { Spec->Flags |= DS_DEF_STORAGE; - Spec->StorageClass = DefStorage; + Spec->StorageClass |= DefStorage; } } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 0f3a6e110..64b6d30bf 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1223,8 +1223,8 @@ static void Primary (ExprDesc* E) NextToken (); /* Check for illegal symbol types */ - CHECK ((Sym->Flags & SC_LABEL) != SC_LABEL); - if (Sym->Flags & SC_ESUTYPEMASK) { + CHECK ((Sym->Flags & SC_TYPEMASK) != SC_LABEL); + if ((Sym->Flags & SC_TYPEMASK) == SC_TYPEDEF) { /* Cannot use type symbols */ Error ("Variable identifier expected"); /* Assume an int type to make E valid */ @@ -1244,7 +1244,7 @@ static void Primary (ExprDesc* E) /* Enum or some other numeric constant */ E->Flags = E_LOC_NONE | E_RTYPE_RVAL; E->IVal = Sym->V.ConstVal; - } else if ((Sym->Flags & SC_AUTO) == SC_AUTO) { + } else if ((Sym->Flags & SC_STORAGEMASK) == SC_AUTO) { /* Local variable. If this is a parameter for a variadic ** function, we have to add some address calculations, and the ** address is not const. @@ -1258,26 +1258,25 @@ static void Primary (ExprDesc* E) E->Flags = E_LOC_STACK | E_RTYPE_LVAL; E->IVal = Sym->V.Offs; } - } else if ((Sym->Flags & SC_FUNC) == SC_FUNC) { + } else if ((Sym->Flags & SC_TYPEMASK) == SC_FUNC) { /* Function */ E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL; E->Name = (uintptr_t) Sym->Name; - } else if ((Sym->Flags & SC_REGISTER) == SC_REGISTER) { + } else if ((Sym->Flags & SC_STORAGEMASK) == SC_REGISTER) { /* Register variable, zero page based */ E->Flags = E_LOC_REGISTER | E_RTYPE_LVAL; E->Name = Sym->V.R.RegOffs; - } else if ((Sym->Flags & SC_STATIC) == SC_STATIC) { - /* Static variable */ - if (Sym->Flags & (SC_EXTERN | SC_STORAGE | SC_DECL)) { - E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL; - E->Name = (uintptr_t) Sym->Name; - } else { - E->Flags = E_LOC_STATIC | E_RTYPE_LVAL; - E->Name = Sym->V.L.Label; - } - } else { + } else if (SymIsGlobal (Sym)) { + /* Global variable */ + E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL; + E->Name = (uintptr_t) Sym->Name; + } else if ((Sym->Flags & SC_STORAGEMASK) == SC_STATIC) { /* Local static variable */ E->Flags = E_LOC_STATIC | E_RTYPE_LVAL; + E->Name = Sym->V.L.Label; + } else { + /* Other */ + E->Flags = E_LOC_STATIC | E_RTYPE_LVAL; E->Name = Sym->V.Offs; } @@ -1311,7 +1310,7 @@ static void Primary (ExprDesc* E) } else { Warning ("Call to undeclared function '%s'", Ident); } - Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC); + Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_REF | SC_FUNC); E->Type = Sym->Type; E->Flags = E_LOC_GLOBAL | E_RTYPE_RVAL; E->Name = (uintptr_t) Sym->Name; diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 148485764..936bd591d 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -98,7 +98,7 @@ enum { E_LOC_NONE = 0x0000, /* Pure rvalue with no storage */ E_LOC_ABS = 0x0001, /* Absolute numeric addressed variable */ E_LOC_GLOBAL = 0x0002, /* Global variable */ - E_LOC_STATIC = 0x0004, /* Static variable */ + E_LOC_STATIC = 0x0004, /* Local static variable */ E_LOC_REGISTER = 0x0008, /* Register variable */ E_LOC_STACK = 0x0010, /* Value on the stack */ E_LOC_PRIMARY = 0x0020, /* Temporary in primary register */ diff --git a/src/cc65/goto.c b/src/cc65/goto.c index 44ae0595e..e96ad6c4c 100644 --- a/src/cc65/goto.c +++ b/src/cc65/goto.c @@ -92,7 +92,7 @@ void GotoStatement (void) /* Find array size */ if (!IsTypeArray (arr->Type) || SizeOf (arr->Type) == 0 || - !(arr->Flags & SC_STATIC) || + (arr->Flags & SC_STORAGEMASK) != SC_STATIC || SizeOf (GetElementType(arr->Type)) != 2) { Error ("Expected a static array"); } else if (GetElementCount (arr->Type) > 127) { diff --git a/src/cc65/locals.c b/src/cc65/locals.c index b8738992f..28e263bb8 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -304,7 +304,7 @@ static void ParseAutoDecl (Declarator* Decl) /* Static local variables. */ - Decl->StorageClass = (Decl->StorageClass & ~SC_AUTO) | SC_STATIC; + Decl->StorageClass = (Decl->StorageClass & ~SC_STORAGEMASK) | SC_STATIC; /* Generate a label, but don't define it */ DataLabel = GetLocalDataLabel (); @@ -451,24 +451,27 @@ static int ParseOneDecl (DeclSpec* Spec) /* Read the declarator */ NeedClean = ParseDecl (Spec, &Decl, DM_IDENT_OR_EMPTY); - /* Check if there are any non-extern storage classes set for function - ** declarations. Function can only be declared inside functions with the - ** 'extern' storage class specifier or no storage class specifier at all. + /* Check if there are explicitly specified non-external storage classes + ** for function declarations. */ - if ((Decl.StorageClass & SC_FUNC) == SC_FUNC) { - - /* Check if there are explicitly specified non-external storage classes */ + if ((Decl.StorageClass & SC_TYPEMASK) == SC_FUNC) { + /* Function can only be declared inside functions with the 'extern' + ** storage class specifier or no storage class specifier at all. + ** Note: this declaration is always checked for compatibility with + ** other declarations of the same symbol, but does not necessarily + ** make the symbol globally visible. This is tricky. + */ if ((Spec->Flags & DS_DEF_STORAGE) != DS_DEF_STORAGE && - (Decl.StorageClass & SC_EXTERN) == 0 && + (Decl.StorageClass & SC_STORAGEMASK) != SC_EXTERN && (Decl.StorageClass & SC_STORAGEMASK) != 0) { Error ("Illegal storage class on function"); } /* The default storage class could be wrong. Just clear them */ Decl.StorageClass &= ~SC_STORAGEMASK; - - /* This is always an extern declaration */ - Decl.StorageClass |= SC_DECL | SC_EXTERN; + } else if ((Decl.StorageClass & SC_STORAGEMASK) != SC_EXTERN) { + /* If the symbol is not marked as external, it will be defined now */ + Decl.StorageClass |= SC_DEF; } /* If we don't have a name, this was flagged as an error earlier. @@ -478,12 +481,6 @@ static int ParseOneDecl (DeclSpec* Spec) AnonName (Decl.Ident, "param"); } - /* If the symbol is not marked as external, it will be defined now */ - if ((Decl.StorageClass & SC_DECL) == 0 && - (Decl.StorageClass & SC_EXTERN) == 0) { - Decl.StorageClass |= SC_DEF; - } - /* Handle anything that needs storage (no functions, no typdefs) */ if ((Decl.StorageClass & SC_DEF) == SC_DEF && (Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { @@ -492,20 +489,20 @@ static int ParseOneDecl (DeclSpec* Spec) ** convert the declaration to "auto" if this is not possible. */ int Reg = 0; /* Initialize to avoid gcc complains */ - if ((Decl.StorageClass & SC_REGISTER) != 0 && + if ((Decl.StorageClass & SC_STORAGEMASK) == SC_REGISTER && (Reg = F_AllocRegVar (CurrentFunc, Decl.Type)) < 0) { /* No space for this register variable, convert to auto */ - Decl.StorageClass = (Decl.StorageClass & ~SC_REGISTER) | SC_AUTO; + Decl.StorageClass = (Decl.StorageClass & ~SC_STORAGEMASK) | SC_AUTO; } /* Check the variable type */ - if ((Decl.StorageClass & SC_REGISTER) == SC_REGISTER) { + if ((Decl.StorageClass & SC_STORAGEMASK) == SC_REGISTER) { /* Register variable */ ParseRegisterDecl (&Decl, Reg); - } else if ((Decl.StorageClass & SC_AUTO) == SC_AUTO) { + } else if ((Decl.StorageClass & SC_STORAGEMASK) == SC_AUTO) { /* Auto variable */ ParseAutoDecl (&Decl); - } else if ((Decl.StorageClass & SC_STATIC) == SC_STATIC) { + } else if ((Decl.StorageClass & SC_STORAGEMASK) == SC_STATIC) { /* Static variable */ ParseStaticDecl (&Decl); } else { @@ -514,7 +511,7 @@ static int ParseOneDecl (DeclSpec* Spec) } else { - if ((Decl.StorageClass & SC_EXTERN) == SC_EXTERN) { + if ((Decl.StorageClass & SC_STORAGEMASK) == SC_EXTERN) { /* External identifier - may not get initialized */ if (CurTok.Tok == TOK_ASSIGN) { Error ("Cannot initialize extern variable '%s'", Decl.Ident); @@ -524,8 +521,8 @@ static int ParseOneDecl (DeclSpec* Spec) } } - if ((Decl.StorageClass & SC_EXTERN) == SC_EXTERN || - (Decl.StorageClass & SC_FUNC) == SC_FUNC) { + if ((Decl.StorageClass & SC_STORAGEMASK) == SC_EXTERN || + (Decl.StorageClass & SC_TYPEMASK) == SC_FUNC) { /* Add the global symbol to both of the global and local symbol ** tables. */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index db306040d..b9394494b 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -630,7 +630,7 @@ static void WrappedCallPragma (pragma_scope_t Scope, StrBuf* B) Entry = FindSym(Name); /* Check if the name is valid */ - if (Entry && (Entry->Flags & SC_FUNC) == SC_FUNC) { + if (Entry && (Entry->Flags & SC_TYPEMASK) == SC_FUNC) { PushWrappedCall(Entry, (unsigned int) Val); Entry->Flags |= SC_REF; diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index 30ebe7dd8..56f6ffbb0 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -88,7 +88,7 @@ void FreeSymEntry (SymEntry* E) TypeFree (E->Type); xfree (E->AsmName); - if (E->Flags & SC_LABEL) { + if ((E->Flags & SC_TYPEMASK) == SC_LABEL) { for (i = 0; i < CollCount (E->V.L.DefsOrRefs); i++) { xfree (CollAt (E->V.L.DefsOrRefs, i)); } @@ -109,21 +109,17 @@ void DumpSymEntry (FILE* F, const SymEntry* E) unsigned Val; } SCFlagTable; - static SCFlagTable ESUTypes[] = { - { "SC_TYPEDEF", SC_TYPEDEF }, - { "SC_UNION", SC_UNION }, - { "SC_STRUCT", SC_STRUCT }, - { "SC_ENUM", SC_ENUM }, - }; - static SCFlagTable Types[] = { - { "SC_BITFIELD", SC_BITFIELD }, - { "SC_STRUCTFIELD", SC_STRUCTFIELD }, - { "SC_ENUMERATOR", SC_ENUMERATOR }, - { "SC_CONST", SC_CONST }, + { "SC_NONE", SC_NONE }, + { "SC_STRUCT", SC_STRUCT }, + { "SC_UNION", SC_UNION }, + { "SC_ENUM", SC_ENUM }, { "SC_LABEL", SC_LABEL }, - { "SC_PARAM", SC_PARAM }, + { "SC_BITFIELD", SC_BITFIELD }, + { "SC_TYPEDEF", SC_TYPEDEF }, + { "SC_ENUMERATOR", SC_ENUMERATOR }, { "SC_FUNC", SC_FUNC }, + { "SC_ARRAY", SC_ARRAY }, }; static SCFlagTable Storages[] = { @@ -131,11 +127,31 @@ void DumpSymEntry (FILE* F, const SymEntry* E) { "SC_REGISTER", SC_REGISTER }, { "SC_STATIC", SC_STATIC }, { "SC_EXTERN", SC_EXTERN }, - { "SC_STORAGE", SC_STORAGE }, + }; + + static SCFlagTable Properties[] = { + { "SC_CONST", SC_CONST }, + { "SC_STRUCTFIELD", SC_STRUCTFIELD }, + { "SC_PARAM", SC_PARAM }, + { "SC_DEFTYPE", SC_DEFTYPE }, { "SC_ZEROPAGE", SC_ZEROPAGE }, - { "SC_DECL", SC_DECL }, + { "SC_HAVEALIGN", SC_HAVEALIGN }, + { "SC_HAVEATTR", SC_HAVEATTR }, + { "SC_TU_STORAGE", SC_TU_STORAGE }, + { "SC_ASSIGN_INIT", SC_ASSIGN_INIT }, + { "SC_ALIAS", SC_ALIAS }, + { "SC_FICTITIOUS", SC_FICTITIOUS }, + { "SC_HAVEFAM", SC_HAVEFAM }, + { "SC_HAVECONST", SC_HAVECONST }, + }; + + static SCFlagTable Status[] = { { "SC_DEF", SC_DEF }, { "SC_REF", SC_REF }, + { "SC_GOTO", SC_GOTO }, + { "SC_GOTO_IND", SC_GOTO_IND }, + { "SC_LOCALSCOPE", SC_LOCALSCOPE }, + { "SC_NOINLINEDEF", SC_NOINLINEDEF }, }; unsigned I; @@ -152,28 +168,38 @@ void DumpSymEntry (FILE* F, const SymEntry* E) /* Print the flags */ SymFlags = E->Flags; fprintf (F, " Flags:"); - /* Enum, struct, union and typedefs */ - if ((SymFlags & SC_ESUTYPEMASK) != 0) { - for (I = 0; I < sizeof (ESUTypes) / sizeof (ESUTypes[0]); ++I) { - if ((SymFlags & SC_ESUTYPEMASK) == ESUTypes[I].Val) { - SymFlags &= ~SC_ESUTYPEMASK; - fprintf (F, " %s", ESUTypes[I].Name); + /* Symbol types */ + if ((SymFlags & SC_TYPEMASK) != 0) { + for (I = 0; I < sizeof (Types) / sizeof (Types[0]); ++I) { + if ((SymFlags & SC_TYPEMASK) == Types[I].Val) { + SymFlags &= ~SC_TYPEMASK; + fprintf (F, " %s", Types[I].Name); break; } } } - /* Other type flags */ - for (I = 0; I < sizeof (Types) / sizeof (Types[0]) && SymFlags != 0; ++I) { - if ((SymFlags & Types[I].Val) == Types[I].Val) { - SymFlags &= ~Types[I].Val; - fprintf (F, " %s", Types[I].Name); + /* Storage classes */ + if ((SymFlags & SC_STORAGEMASK) != 0) { + for (I = 0; I < sizeof (Storages) / sizeof (Storages[0]); ++I) { + if ((SymFlags & SC_STORAGEMASK) == Storages[I].Val) { + SymFlags &= ~SC_STORAGEMASK; + fprintf (F, " %s", Storages[I].Name); + break; + } } } - /* Storage flags */ - for (I = 0; I < sizeof (Storages) / sizeof (Storages[0]) && SymFlags != 0; ++I) { - if ((SymFlags & Storages[I].Val) == Storages[I].Val) { - SymFlags &= ~Storages[I].Val; - fprintf (F, " %s", Storages[I].Name); + /* Special property flags */ + for (I = 0; I < sizeof (Properties) / sizeof (Properties[0]) && SymFlags != 0; ++I) { + if ((SymFlags & Properties[I].Val) == Properties[I].Val) { + SymFlags &= ~Properties[I].Val; + fprintf (F, " %s", Properties[I].Name); + } + } + /* Status flags */ + for (I = 0; I < sizeof (Status) / sizeof (Status[0]) && SymFlags != 0; ++I) { + if ((SymFlags & Status[I].Val) == Status[I].Val) { + SymFlags &= ~Status[I].Val; + fprintf (F, " %s", Status[I].Name); } } if (SymFlags != 0) { @@ -199,9 +225,10 @@ int SymIsOutputFunc (const SymEntry* Sym) /* Symbol must be a function which is defined and either extern or ** static and referenced. */ - return IsTypeFunc (Sym->Type) && - SymIsDef (Sym) && - (Sym->Flags & (SC_REF | SC_EXTERN)); + return IsTypeFunc (Sym->Type) && + SymIsDef (Sym) && + ((Sym->Flags & SC_REF) || + (Sym->Flags & SC_STORAGEMASK) != SC_STATIC); } @@ -272,7 +299,7 @@ void SymCvtRegVarToAuto (SymEntry* Sym) /* Convert a register variable to an auto variable */ { /* Change the storage class */ - Sym->Flags = (Sym->Flags & ~(SC_REGISTER | SC_STATIC | SC_EXTERN)) | SC_AUTO; + Sym->Flags = (Sym->Flags & ~SC_STORAGEMASK) | SC_AUTO; /* Transfer the stack offset from register save area to actual offset */ Sym->V.Offs = Sym->V.R.SaveOffs; diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 639221625..7bfc18ea4 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -68,47 +68,88 @@ struct CodeEntry; -/* Storage classes and flags */ +/* Symbol types and flags */ #define SC_NONE 0x0000U /* Nothing */ -#define SC_STRUCT 0x0001U /* Struct */ -#define SC_UNION 0x0002U /* Union */ -#define SC_ENUM 0x0003U /* Enum */ -#define SC_TYPEDEF 0x0004U /* Typedef */ -#define SC_ESUTYPEMASK 0x0007U /* Mask for above types */ -#define SC_ENUMERATOR 0x0008U /* An enumerator */ -#define SC_BITFIELD 0x0010U /* A bit-field inside a struct or union */ -#define SC_TYPEMASK 0x001FU /* Mask for above types */ -#define SC_FUNC 0x0020U /* A function */ -#define SC_LABEL 0x0040U /* A goto code label */ -#define SC_CONST 0x0080U /* A numeric constant with a type */ -#define SC_PARAM 0x0100U /* A function parameter */ -#define SC_DEFTYPE 0x0200U /* Parameter has default type (=int, old style) */ -#define SC_STRUCTFIELD 0x0400U /* Struct or union field */ +/* Types of symbols */ +#define SC_STRUCT 0x0001U /* Struct tag */ +#define SC_UNION 0x0002U /* Union tag */ +#define SC_ENUM 0x0003U /* Enum tag */ +#define SC_LABEL 0x0004U /* A goto code label */ +#define SC_BITFIELD 0x0005U /* A bit-field inside a struct or union */ +#define SC_TYPEDEF 0x0006U /* A typedef */ +#define SC_ENUMERATOR 0x0007U /* An enumerator */ -#define SC_ZEROPAGE 0x0800U /* Symbol marked as zeropage */ +/* Note: These symbol types might be checked as bit-flags occasionally. +** So don't share their unique bits with other symbol types. +*/ +#define SC_FUNC 0x0008U /* A function */ +#define SC_ARRAY 0x0010U /* UNUSED: An array */ +#define SC_TYPEMASK 0x001FU /* Mask for symbol types all above */ -#define SC_DEF 0x1000U /* Symbol is defined */ -#define SC_REF 0x2000U /* Symbol is referenced */ -#define SC_DECL 0x4000U /* Symbol is declared in global scope */ -#define SC_STORAGE 0x8000U /* Symbol with associated storage */ +/* Additional property of the symbols */ +#define SC_CONST 0x0020U /* A numeric constant with a type */ +#define SC_STRUCTFIELD 0x0040U /* A struct or union field */ +#define SC_PARAM 0x0080U /* A function parameter */ +#define SC_DEFTYPE 0x0100U /* An old-style parameter with default type (=int) */ -#define SC_AUTO 0x010000U /* Auto variable */ -#define SC_REGISTER 0x020000U /* Register variable */ -#define SC_STATIC 0x040000U /* Static - not to be confused with other *_STATIC */ -#define SC_EXTERN 0x080000U /* Extern linkage */ -#define SC_STORAGEMASK 0x0F0000U /* Storage type mask */ +/* Address property of the symbol */ +#define SC_ZEROPAGE 0x0200U /* Symbol marked as on zeropage */ -#define SC_HAVEATTR 0x100000U /* Symbol has attributes */ +/* Additional attributes of the symbol */ +#define SC_HAVEALIGN 0x0400U /* UNUSED: Symbol has special alignment */ +#define SC_HAVEATTR 0x0800U /* Symbol has attributes */ -#define SC_GOTO 0x200000U -#define SC_SPADJUSTMENT 0x400000U -#define SC_GOTO_IND 0x800000U /* Indirect goto */ +/* Special property of declaration */ +#define SC_TU_STORAGE 0x1000U /* Symbol has allocated storage in the TU */ +#define SC_ASSIGN_INIT 0x2000U /* Symbol is to be initialized with assignment code */ -#define SC_ALIAS 0x01000000U /* Alias of global or anonymous field */ -#define SC_FICTITIOUS 0x02000000U /* Symbol is fictitious (for error recovery) */ -#define SC_HAVEFAM 0x04000000U /* Type has a Flexible Array Member */ -#define SC_HAVECONST 0x08000000U /* Type has a const member */ +#define SC_ALIAS 0x4000U /* Symbol is an alias */ +#define SC_FICTITIOUS 0x8000U /* Symbol is fictitious (for error recovery) */ +#define SC_HAVEFAM 0x010000U /* Struct/union has a Flexible Array Member */ +#define SC_HAVECONST 0x020000U /* Struct/union has a const member */ + +/* Status of the symbol */ +#define SC_DEF 0x040000U /* Symbol is defined */ +#define SC_REF 0x080000U /* Symbol is referenced */ +#define SC_GOTO 0x100000U /* Symbol is destination of a goto */ +#define SC_GOTO_IND 0x200000U /* Symbol is destination of an indirect goto */ +#define SC_LOCALSCOPE 0x400000U /* Symbol is invisible in file scope */ +#define SC_NOINLINEDEF 0x800000U /* Symbol may never have an inline definition */ + +/* To figure out the linkage of an object or function symbol Sym: +** - external linkage: +** SymIsGlobal (Sym) && (Sym->Flags & SC_STORAGEMASK) != SC_STATIC +** - internal linkage: +** SymIsGlobal (Sym) && (Sym->Flags & SC_STORAGEMASK) == SC_STATIC +** - no linkage: +** !SymIsGlobal (Sym) +** +** To figure out the storage class of a symbol by its SC_ flags: +** +** - no explicit storage class specifiers (in file scope): +** (flags & SC_STORAGEMASK) == SC_NONE +** - no explicit storage class specifiers (in block scope): +** (flags & SC_STORAGEMASK) == SC_AUTO +** - extern: +** (flags & SC_STORAGEMASK) == SC_EXTERN +** - static: +** (flags & SC_STORAGEMASK) == SC_STATIC +** - auto: +** (flags & SC_STORAGEMASK) == SC_AUTO +** - register: +** (flags & SC_STORAGEMASK) == SC_REGISTER +** - typedef (per ISO C): +** (flags & SC_TYPEMASK) == SC_TYPEDEF +** +** Note: SC_TYPEDEF can be also used as a flag. +*/ +#define SC_AUTO 0x01000000U /* Auto storage class */ +#define SC_REGISTER 0x02000000U /* Register storage class */ +#define SC_STATIC 0x03000000U /* Static storage class */ +#define SC_EXTERN 0x04000000U /* Extern storage class */ +#define SC_THREAD 0x08000000U /* UNSUPPORTED: Thread-local storage class */ +#define SC_STORAGEMASK 0x0F000000U /* Storage type mask */ @@ -214,14 +255,37 @@ void FreeSymEntry (SymEntry* E); void DumpSymEntry (FILE* F, const SymEntry* E); /* Dump the given symbol table entry to the file in readable form */ +int SymIsOutputFunc (const SymEntry* Sym); +/* Return true if this is a function that must be output */ + +#if defined(HAVE_INLINE) +INLINE int SymIsArray (const SymEntry* Sym) +/* Return true if the given entry is an array entry */ +{ + return ((Sym->Flags & SC_TYPEMASK) == SC_ARRAY); +} +#else +# define SymIsArray(Sym) (((Sym)->Flags & SC_TYPEMASK) == SC_ARRAY) +#endif + #if defined(HAVE_INLINE) INLINE int SymIsBitField (const SymEntry* Sym) /* Return true if the given entry is a bit-field entry */ { - return ((Sym->Flags & SC_BITFIELD) == SC_BITFIELD); + return ((Sym->Flags & SC_TYPEMASK) == SC_BITFIELD); } #else -# define SymIsBitField(Sym) (((Sym)->Flags & SC_BITFIELD) == SC_BITFIELD) +# define SymIsBitField(Sym) (((Sym)->Flags & SC_TYPEMASK) == SC_BITFIELD) +#endif + +#if defined(HAVE_INLINE) +INLINE int SymIsLabel (const SymEntry* Sym) +/* Return true if the given entry is a label entry */ +{ + return ((Sym)->Flags & SC_TYPEMASK) == SC_LABEL; +} +#else +# define SymIsLabel(Sym) (((Sym)->Flags & SC_TYPEMASK) == SC_LABEL) #endif #if defined(HAVE_INLINE) @@ -257,17 +321,13 @@ INLINE int SymIsRef (const SymEntry* Sym) #if defined(HAVE_INLINE) INLINE int SymIsRegVar (const SymEntry* Sym) /* Return true if the given entry is a register variable */ -/* ### HACK! Fix the ugly type flags! */ { - return ((Sym->Flags & (SC_REGISTER | SC_TYPEMASK)) == SC_REGISTER); + return ((Sym->Flags & (SC_STORAGEMASK | SC_TYPEMASK)) == (SC_REGISTER | SC_NONE)); } #else -# define SymIsRegVar(Sym) (((Sym)->Flags & (SC_REGISTER | SC_TYPEMASK)) == SC_REGISTER) +# define SymIsRegVar(Sym) (((Sym)->Flags & (SC_STORAGEMASK | SC_TYPEMASK)) == (SC_REGISTER | SC_NONE)) #endif -int SymIsOutputFunc (const SymEntry* Sym); -/* Return true if this is a function that must be output */ - #if defined(HAVE_INLINE) INLINE int SymHasFlexibleArrayMember (const SymEntry* Sym) /* Return true if the given entry has a flexible array member */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index c2c6bab27..a76e60450 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -165,22 +165,22 @@ static void CheckSymTable (SymTable* Tab) /* Ignore typedef entries */ if (!SymIsTypeDef (Entry)) { - /* Check if the symbol is one with storage, and it if it was - ** defined but not used. - */ - if (((Flags & SC_AUTO) || (Flags & SC_STATIC)) && (Flags & SC_EXTERN) == 0) { + /* Check if the symbol has non-external linkage and is defined but not used */ + if (!SymIsGlobal (Entry) || (Flags & SC_STORAGEMASK) == SC_STATIC) { if (SymIsDef (Entry) && !SymIsRef (Entry) && !SymHasAttr (Entry, atUnused)) { if (Flags & SC_PARAM) { if (IS_Get (&WarnUnusedParam)) { Warning ("Parameter '%s' is never used", Entry->Name); } - } else if (Flags & SC_FUNC) { + } else if ((Flags & SC_TYPEMASK) == SC_FUNC) { if (IS_Get (&WarnUnusedFunc)) { Warning ("Function '%s' is defined but never used", Entry->Name); } - } else if (!IsAnonName (Entry->Name)) { - if (IS_Get (&WarnUnusedVar)) { + } else if ((Flags & SC_TYPEMASK) == SC_NONE) { + if (IS_Get (&WarnUnusedVar) && + !IsAnonName (Entry->Name) && + (Flags & SC_CONST) != SC_CONST) { Warning ("Variable '%s' is defined but never used", Entry->Name); } } @@ -188,7 +188,7 @@ static void CheckSymTable (SymTable* Tab) } /* If the entry is a label, check if it was defined in the function */ - if (Flags & SC_LABEL) { + if ((Flags & SC_TYPEMASK) == SC_LABEL) { if (!SymIsDef (Entry)) { /* Undefined label */ Error ("Undefined label: '%s'", Entry->Name); @@ -716,7 +716,7 @@ static int HandleSymRedefinition (SymEntry* Sym, const Type* T, unsigned Flags) Sym = 0; } - } else if ((Sym->Flags & SC_FUNC) == SC_FUNC) { + } else if ((Sym->Flags & SC_TYPEMASK) == SC_FUNC) { /* In case of a function, use the new type descriptor, since it ** contains pointers to the new symbol tables that are needed if @@ -863,7 +863,6 @@ SymEntry* AddEnumSym (const char* Name, unsigned Flags, const Type* Type, SymTab } else { TagEntry->V.E.SymTab = Tab; TagEntry->V.E.Type = Type; - TagEntry->Flags &= ~SC_DECL; TagEntry->Flags |= SC_DEF; /* Remember this is the first definition of this type */ @@ -1047,7 +1046,7 @@ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name)); if (Entry) { - if ((Entry->Flags & SC_CONST) != SC_CONST) { + if ((Entry->Flags & SC_TYPEMASK) != (Flags & SC_TYPEMASK)) { Error ("Symbol '%s' is already different kind", Name); } else { Error ("Multiple definition for constant '%s'", Name); @@ -1056,7 +1055,7 @@ SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val } /* Create a new entry */ - Entry = NewSymEntry (Name, Flags); + Entry = NewSymEntry (Name, Flags | SC_CONST); /* We only have integer constants for now */ Entry->Type = TypeDup (T); @@ -1167,7 +1166,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) /* Optimizer will need the information about the value of SP adjustment ** later, so let's preserve it. */ - E = NewSymEntry (LocalDataLabelName (DOR->LateSP_Label), SC_SPADJUSTMENT); + E = NewSymEntry (LocalDataLabelName (DOR->LateSP_Label), 0); E->V.SPAdjustment = StackPtr - DOR->StackPtr; AddSymEntry (SPAdjustTab, E); } @@ -1236,38 +1235,32 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs Entry = FindSymInTable (Tab, Name, HashStr (Name)); if (Entry) { - int CheckExtern = 0; if ((Flags & SC_STRUCTFIELD) == 0) { while (Entry && (Entry->Flags & SC_ALIAS) == SC_ALIAS) { /* Get the aliased entry */ Entry = Entry->V.A.Field; - /* Check for conflict with local storage class */ - CheckExtern = 1; } } /* We have a symbol with this name already */ if (HandleSymRedefinition (Entry, T, Flags)) { Entry = 0; - } else if ((Flags & SC_ESUTYPEMASK) != SC_TYPEDEF) { + } else if ((Flags & SC_TYPEMASK) != SC_TYPEDEF) { /* Redefinitions are not allowed */ if (SymIsDef (Entry) && (Flags & SC_DEF) == SC_DEF) { Error ("Multiple definition of '%s'", Entry->Name); Entry = 0; - } else if (CheckExtern) { - if ((Flags & (SC_AUTO | SC_REGISTER)) != 0) { - Error ("Declaration of '%s' with no linkage follows extern declaration", Name); - Entry = 0; - } else if ((Flags & SC_DEF) != 0 && (Flags & SC_EXTERN) == 0) { - /* If a static declaration follows a non-static declaration, - ** then it is an error. - */ - Error ("Static declaration of '%s' follows extern declaration", Name); - Entry = 0; - } } else if ((Flags & SC_STRUCTFIELD) != 0) { Error ("Duplicate member '%s'", Entry->Name); Entry = 0; + } else if (Entry->Owner == SymTab0) { + if ((Flags & SC_STORAGEMASK) == SC_AUTO || + (Flags & SC_STORAGEMASK) == SC_REGISTER || + (Flags & SC_STORAGEMASK) == SC_STATIC) { + Error ("Declaration of '%s' with no linkage follows extern declaration", + Name); + Entry = 0; + } } } @@ -1290,20 +1283,20 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs Entry->Type = TypeDup (T); if ((Flags & SC_STRUCTFIELD) == SC_STRUCTFIELD || - (Flags & SC_ESUTYPEMASK) == SC_TYPEDEF) { + (Flags & SC_TYPEMASK) == SC_TYPEDEF) { if ((Flags & SC_ALIAS) != SC_ALIAS) { Entry->V.Offs = Offs; } - } else if ((Flags & SC_AUTO) == SC_AUTO) { + } else if ((Flags & SC_STORAGEMASK) == SC_AUTO) { Entry->V.Offs = Offs; - } else if ((Flags & SC_REGISTER) == SC_REGISTER) { + } else if ((Flags & SC_STORAGEMASK) == SC_REGISTER) { Entry->V.R.RegOffs = Offs; Entry->V.R.SaveOffs = StackPtr; - } else if ((Flags & SC_EXTERN) == SC_EXTERN || - (Flags & SC_FUNC) == SC_FUNC) { + } else if ((Flags & SC_STORAGEMASK) == SC_EXTERN || + (Flags & SC_TYPEMASK) == SC_FUNC) { Entry->V.L.Label = Offs; SymSetAsmName (Entry); - } else if ((Flags & SC_STATIC) == SC_STATIC) { + } else if ((Flags & SC_STORAGEMASK) == SC_STATIC) { /* Generate the assembler name from the data label number */ Entry->V.L.Label = Offs; Entry->AsmName = xstrdup (LocalDataLabelName (Entry->V.L.Label)); @@ -1348,49 +1341,63 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) Entry = FindGlobalSym (Name); } + /* Do we have a symbol with this name already? */ if (Entry) { - /* We have a symbol with this name already */ + /* Check if the symbol refers to some different type of things */ if (HandleSymRedefinition (Entry, T, Flags)) { Entry = 0; - } else if ((Entry->Flags & (SC_AUTO | SC_REGISTER)) != 0) { - /* Check for local storage class conflict */ + } else if (Entry->Owner != SymTab0) { + /* The previous declaration has no linkage. The current declaration + ** has either external or internal linkage. Either way it is an + ** error since the two declarations would be referring to different + ** objects with the same identifier. + */ Error ("Extern declaration of '%s' follows declaration with no linkage", Name); Entry = 0; - } else if ((Flags & SC_ESUTYPEMASK) != SC_TYPEDEF) { - /* If a static declaration follows a non-static declaration, then - ** the result is undefined. - ** Most compilers choose to either give an error at compile time, - ** or remove the extern property for a link time error if used. + } else if ((Flags & SC_TYPEMASK) != SC_TYPEDEF) { + /* The C standard specifies that the result is undefined if the + ** same thing has both internal and external linkage. Most + ** compilers choose to either give an error at compile time, or + ** remove the external linkage for a link time error if used + ** outside the current translation unit. We choose to give an + ** error at compile time in this case. */ - if (SymTab == SymTab0 && - (Flags & SC_EXTERN) == 0 && - (Entry->Flags & SC_EXTERN) != 0) { - Error ("Static declaration of '%s' follows non-static declaration", Name); - Entry = 0; - } else if ((Flags & SC_EXTERN) != 0 && - (Entry->Owner == SymTab0 || (Entry->Flags & SC_DEF) != 0) && - (Entry->Flags & SC_EXTERN) == 0) { - /* It is OK if a global extern declaration follows a global - ** non-static declaration, but an error if either of them is - ** local, as the two would be referring to different objects. - ** It is an error as well if a global non-static declaration - ** follows a global static declaration. + if ((Entry->Flags & SC_STORAGEMASK) != SC_STATIC) { + /* The previous declaration is a non-static declaration of an + ** object or function that has external linkage. */ - if (Entry->Owner == SymTab0) { - if ((Flags & SC_STORAGE) == 0) { - /* The C standard specifies that a later extern declaration will keep - ** the previously declared internal or external linkage unchanged. - ** Though not required by the standard, we are warning on this case. - */ - Flags &= ~SC_EXTERN; - Warning ("Extern declaration of '%s' follows static declaration, linkage unchanged", Name); - } else { - Error ("Non-static declaration of '%s' follows static declaration", Name); - Entry = 0; - } - } else { - Error ("Extern declaration of '%s' follows static declaration", Name); + if ((Flags & SC_STORAGEMASK) == SC_STATIC) { + /* It is a static declaration of an object or function that + ** has internal linkage. Conflicted wih the previous one. + */ + Error ("Static declaration of '%s' follows non-static declaration", + Name); + Entry = 0; + } + } else if ((Flags & SC_STORAGEMASK) != SC_STATIC) { + /* The previous declaration is a static declaration of an + ** object or function that has internal linkage. + */ + if ((Flags & SC_STORAGEMASK) == SC_EXTERN || + (Flags & SC_TYPEMASK) == SC_FUNC) { + /* The C standard specifies that an extern declaration + ** shall keep the previously declared internal linkage + ** unchanged. For a function declaration with no storage + ** class specifiers, it is treated as if with 'extern'. + ** We give a warning although it is not required by the + ** standard. + */ + Flags &= ~SC_STORAGEMASK; + Warning ("Extern declaration of '%s' follows static declaration", + Name); + } else if ((Flags & SC_STORAGEMASK) == SC_NONE) { + /* It is a non-extern-or-static declaration of an object in + ** file scope that has external linkage. Conflicted wih the + ** previous one. + */ + Error ("Non-static declaration of '%s' follows static declaration", + Name); Entry = 0; } } @@ -1486,14 +1493,22 @@ SymTable* GetLabelSymTab (void) -int SymIsLocal (SymEntry* Sym) -/* Return true if the symbol is defined in the highest lexical level */ +int SymIsLocal (const SymEntry* Sym) +/* Return true if the symbol is declared in the highest lexical level */ { return (Sym->Owner == SymTab || Sym->Owner == TagTab); } +int SymIsGlobal (const SymEntry* Sym) +/* Return true if the symbol is declared in the file scope level */ +{ + return (Sym->Owner == SymTab0 || Sym->Owner == TagTab0); +} + + + void MakeZPSym (const char* Name) /* Mark the given symbol as zero page symbol */ { @@ -1553,7 +1568,9 @@ void EmitExternals (void) Entry = SymTab->SymHead; while (Entry) { unsigned Flags = Entry->Flags; - if (Flags & SC_EXTERN) { + if (Entry->Owner == SymTab0 && + (Flags & SC_STORAGEMASK) != SC_STATIC && + ((Flags & SC_TYPEMASK) == SC_FUNC || (Flags & SC_TYPEMASK) == SC_NONE)) { /* Only defined or referenced externs */ if (SymIsRef (Entry) && !SymIsDef (Entry)) { /* An import */ @@ -1587,18 +1604,18 @@ void EmitDebugInfo (void) } Sym = SymTab->SymHead; while (Sym) { - if ((Sym->Flags & (SC_CONST | SC_TYPEMASK)) == 0) { - if (Sym->Flags & SC_AUTO) { + if ((Sym->Flags & SC_TYPEMASK) == 0) { + if ((Sym->Flags & SC_STORAGEMASK) == SC_AUTO) { AddTextLine ("%s, \"%s\", \"00\", auto, %d", Head, Sym->Name, Sym->V.Offs); - } else if (Sym->Flags & SC_REGISTER) { + } else if ((Sym->Flags & SC_STORAGEMASK) == SC_REGISTER) { AddTextLine ("%s, \"%s\", \"00\", register, \"regbank\", %d", Head, Sym->Name, Sym->V.R.RegOffs); } else if (SymIsRef (Sym) && !SymIsDef (Sym)) { AddTextLine ("%s, \"%s\", \"00\", %s, \"%s\"", Head, Sym->Name, - (Sym->Flags & SC_EXTERN)? "extern" : "static", + (Sym->Flags & SC_STORAGEMASK) != SC_STATIC ? "extern" : "static", Sym->AsmName); } } diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index 38edddcb0..53b0df4eb 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -211,8 +211,11 @@ SymTable* GetFieldSymTab (void); SymTable* GetLabelSymTab (void); /* Return the label symbol table */ -int SymIsLocal (SymEntry* Sym); -/* Return true if the symbol is defined in the highest lexical level */ +int SymIsLocal (const SymEntry* Sym); +/* Return true if the symbol is declared in the highest lexical level */ + +int SymIsGlobal (const SymEntry* Sym); +/* Return true if the symbol is declared in the file scope level */ void MakeZPSym (const char* Name); /* Mark the given symbol as zero page symbol */ From 2138f3c902f2bcbe538a62fae5e7e36c36ea2c2a Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Wed, 10 Jan 2024 21:24:55 -0800 Subject: [PATCH 088/707] add clock() to RP6502 --- include/rp6502.h | 1 + include/time.h | 2 ++ libsrc/rp6502/clock.c | 7 +++++++ 3 files changed, 10 insertions(+) create mode 100644 libsrc/rp6502/clock.c diff --git a/include/rp6502.h b/include/rp6502.h index 2b40cfc71..61664c78f 100644 --- a/include/rp6502.h +++ b/include/rp6502.h @@ -101,6 +101,7 @@ long __fastcall__ ria_call_long_errno (unsigned char op); #define RIA_OP_CODEPAGE 0x03 #define RIA_OP_LRAND 0x04 #define RIA_OP_STDIN_OPT 0x05 +#define RIA_OP_CLOCK 0x0F #define RIA_OP_CLOCK_GETRES 0x10 #define RIA_OP_CLOCK_GETTIME 0x11 #define RIA_OP_CLOCK_SETTIME 0x12 diff --git a/include/time.h b/include/time.h index f8977ab0c..5eb6f144a 100644 --- a/include/time.h +++ b/include/time.h @@ -86,6 +86,8 @@ struct tm { # define CLOCKS_PER_SEC 135 /* FIXME */ #elif defined(__GEOS__) # define CLOCKS_PER_SEC 1 +#elif defined (__RP6502__) +# define CLOCKS_PER_SEC 100 #elif defined(__TELESTRAT__) # define CLOCKS_PER_SEC 10 #elif defined(__ATARI__) || defined (__LYNX__) diff --git a/libsrc/rp6502/clock.c b/libsrc/rp6502/clock.c new file mode 100644 index 000000000..f8756f553 --- /dev/null +++ b/libsrc/rp6502/clock.c @@ -0,0 +1,7 @@ +#include +#include + +clock_t __fastcall__ clock (void) +{ + return ria_call_long (RIA_OP_CLOCK); +} From 44b2e48e3ef556b9b462106152ad2a4bc89bf39c Mon Sep 17 00:00:00 2001 From: Christian Groessler Date: Thu, 11 Jan 2024 17:40:27 +0100 Subject: [PATCH 089/707] mention John Dunning as original author --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eff5049f9..500299730 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,10 @@ For details look at the [Website](https://cc65.github.io). ## People -Project founder: +Project founders: -* Ullrich von Bassewitz +* John R. Dunning: original implementation of the C compiler and runtime library, Atari hosted +* Ullrich von Bassewitz: move the code to modern systems, completely rewritten runtime library Core team members: From 6ab3c0c75fe921e55f841cc357832173044bfe81 Mon Sep 17 00:00:00 2001 From: Christian Groessler Date: Thu, 11 Jan 2024 19:40:41 +0100 Subject: [PATCH 090/707] elaborate more about Uz's contributions --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 500299730..11c3bb0ff 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,10 @@ For details look at the [Website](https://cc65.github.io). Project founders: * John R. Dunning: original implementation of the C compiler and runtime library, Atari hosted -* Ullrich von Bassewitz: move the code to modern systems, completely rewritten runtime library +* Ullrich von Bassewitz: + * move the code to modern systems + * rewrite most parts of the compiler + * complete rewrite of the runtime library Core team members: From 3d0dc5815329de351f72b75afe9f01184464ff3b Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 13 Jan 2024 00:46:14 +0800 Subject: [PATCH 091/707] Fixed visibility of undeclared functions and objects. --- src/cc65/compile.c | 23 +++++++++++------------ src/cc65/symtab.c | 30 +++++++++++++++++++++++------- src/cc65/symtab.h | 4 ++-- test/err/bug2304-var-use.c | 15 +++++++++++++++ test/misc/Makefile | 6 ++++++ test/misc/bug2304-implicit-func.c | 21 +++++++++++++++++++++ 6 files changed, 78 insertions(+), 21 deletions(-) create mode 100644 test/err/bug2304-var-use.c create mode 100644 test/misc/bug2304-implicit-func.c diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 108c80a28..f14774658 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -163,19 +163,19 @@ static void Parse (void) break; } - /* Check if we must reserve storage for the variable. We do this, - ** - ** - if it is not a typedef or function, - ** - if we don't had a storage class given ("int i") - ** - if the storage class is explicitly specified as static, - ** - or if there is an initialization. - ** - ** This means that "extern int i;" will not get storage allocated - ** in this translation unit. - */ + /* The symbol is now visible in the file scope */ if ((Decl.StorageClass & SC_TYPEMASK) != SC_FUNC && (Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { - /* The variable is visible in the file scope */ + /* Check if we must reserve storage for the variable. We do this, + ** + ** - if it is not a typedef or function, + ** - if we don't had a storage class given ("int i") + ** - if the storage class is explicitly specified as static, + ** - or if there is an initialization. + ** + ** This means that "extern int i;" will not get storage allocated + ** in this translation unit. + */ if ((Decl.StorageClass & SC_STORAGEMASK) == SC_NONE || (Decl.StorageClass & SC_STORAGEMASK) == SC_STATIC || ((Decl.StorageClass & SC_STORAGEMASK) == SC_EXTERN && @@ -189,7 +189,6 @@ static void Parse (void) ** or semicolon, it must be followed by a function body. */ if ((Decl.StorageClass & SC_TYPEMASK) == SC_FUNC) { - /* The function is now visible in the file scope */ if (CurTok.Tok == TOK_LCURLY) { /* A definition */ Decl.StorageClass |= SC_DEF; diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index a76e60450..69484456f 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -557,8 +557,10 @@ static SymEntry* FindSymInTable (const SymTable* T, const char* Name, unsigned H -static SymEntry* FindSymInTree (const SymTable* Tab, const char* Name) -/* Find the symbol with the given name in the table tree that starts with T */ +static SymEntry* FindVisibleSymInTree (const SymTable* Tab, const char* Name) +/* Find the visible symbol with the given name in the table tree that starts +** with Tab. +*/ { /* Get the hash over the name */ unsigned Hash = HashStr (Name); @@ -574,7 +576,7 @@ static SymEntry* FindSymInTree (const SymTable* Tab, const char* Name) } /* Bail out if we found it */ - if (E != 0) { + if (E != 0 && (Tab != SymTab0 || (E->Flags & SC_LOCALSCOPE) == 0)) { return E; } @@ -589,9 +591,9 @@ static SymEntry* FindSymInTree (const SymTable* Tab, const char* Name) SymEntry* FindSym (const char* Name) -/* Find the symbol with the given name */ +/* Find with the given name the symbol visible in the current scope */ { - return FindSymInTree (SymTab, Name); + return FindVisibleSymInTree (SymTab, Name); } @@ -613,9 +615,9 @@ SymEntry* FindLocalSym (const char* Name) SymEntry* FindTagSym (const char* Name) -/* Find the symbol with the given name in the tag table */ +/* Find with the given name the tag symbol visible in the current scope */ { - return FindSymInTree (TagTab, Name); + return FindVisibleSymInTree (TagTab, Name); } @@ -1356,6 +1358,13 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) Name); Entry = 0; } else if ((Flags & SC_TYPEMASK) != SC_TYPEDEF) { + /* If we are adding the symbol in the file scope, it is now + ** visible there. + */ + if (SymTab == SymTab0) { + Entry->Flags &= ~SC_LOCALSCOPE; + } + /* The C standard specifies that the result is undefined if the ** same thing has both internal and external linkage. Most ** compilers choose to either give an error at compile time, or @@ -1415,6 +1424,13 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) } if (Entry == 0) { + /* Hide the symbol in the file scope if we are declaring it in a + ** local scope. + */ + if (Tab == SymTab0 && SymTab != SymTab0) { + Flags |= SC_LOCALSCOPE; + } + /* Create a new entry */ Entry = NewSymEntry (Name, Flags); diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index 53b0df4eb..236bc090a 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -142,7 +142,7 @@ void LeaveStructLevel (void); SymEntry* FindSym (const char* Name); -/* Find the symbol with the given name */ +/* Find with the given name the symbol visible in the current scope */ SymEntry* FindGlobalSym (const char* Name); /* Find the symbol with the given name in the global symbol table only */ @@ -151,7 +151,7 @@ SymEntry* FindLocalSym (const char* Name); /* Find the symbol with the given name in the current symbol table only */ SymEntry* FindTagSym (const char* Name); -/* Find the symbol with the given name in the tag table */ +/* Find with the given name the tag symbol visible in the current scope */ SymEntry FindStructField (const Type* TypeArray, const char* Name); /* Find a struct/union field in the fields list. diff --git a/test/err/bug2304-var-use.c b/test/err/bug2304-var-use.c new file mode 100644 index 000000000..8a88405e2 --- /dev/null +++ b/test/err/bug2304-var-use.c @@ -0,0 +1,15 @@ +/* Bug 2304 - Visibility of objects/functions undeclared in file scope but 'extern'-declared in unrelated block scopes */ + +void f1(void) +{ + extern int a; +} + +/* 'a' is still invisible in the file scope */ + +int main(void) +{ + return a * 0; /* Usage of 'a' should be an error */ +} + +int a = 42; diff --git a/test/misc/Makefile b/test/misc/Makefile index 811f7f462..cfcae0530 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -133,6 +133,12 @@ $(WORKDIR)/goto.$1.$2.prg: goto.c $(ISEQUAL) | $(WORKDIR) $(CC65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.$2.out $(ISEQUAL) $(WORKDIR)/goto.$1.$2.out goto.ref +# this one requires failure with --std=c89, it fails with --std=cc65 due to +# stricter checks +$(WORKDIR)/bug2304-implicit-func.$1.$2.prg: bug2304-implicit-func.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug2304-implicit-func.$1.$2.prg) + $(NOT) $(CC65) --standard c89 -t sim$2 -$1 -o $$@ $$< $(NULLERR) + # should not compile until 3-byte struct by value tests are re-enabled $(WORKDIR)/struct-by-value.$1.$2.prg: struct-by-value.c | $(WORKDIR) $(if $(QUIET),echo misc/struct-by-value.$1.$2.prg) diff --git a/test/misc/bug2304-implicit-func.c b/test/misc/bug2304-implicit-func.c new file mode 100644 index 000000000..f6b7450ff --- /dev/null +++ b/test/misc/bug2304-implicit-func.c @@ -0,0 +1,21 @@ +/* Bug 2304 - Visibility of objects/functions undeclared in file scope but 'extern'-declared in unrelated block scopes */ + +/* This one should fail even in C89 */ + +void f1(void) +{ + extern unsigned int f(); +} + +/* 'f' is still invisible in the file scope */ + +int main(void) +{ + f(); /* Should be a conflict since the implicit function type is incompatible */ + return 0; +} + +unsigned int f() +{ + return 42; +} From 7e80e55b6d12138024d44557ed878fa3c50c6fda Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 13 Jan 2024 16:40:44 +0800 Subject: [PATCH 092/707] Added a warning on implicit int in typedefs. --- src/cc65/declare.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index f93305f01..7f1d8b948 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2388,16 +2388,26 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) GetFuncDesc (D->Type)->Flags |= FD_OLDSTYLE_INTRET; } - /* For anything that is not a function or typedef, check for an implicit - ** int declaration. + /* For anything that is not a function, check for an implicit int + ** declaration. */ - if (!IsTypeFunc (D->Type) && - (D->StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { - /* If the standard was not set explicitly to C89, print a warning - ** for variables with implicit int type. - */ - if (IS_Get (&Standard) >= STD_C99) { - Warning ("Implicit 'int' is an obsolete feature"); + if (!IsTypeFunc (D->Type) && IsRankInt (D->Type)) { + if ((D->StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { + /* If the standard was not set explicitly to C89, print a warning + ** for variables with implicit int type. + */ + if (IS_Get (&Standard) >= STD_C99) { + Warning ("Implicit 'int' is an obsolete feature"); + } + } else { + /* If the standard was not set explicitly to C89, print a warning + ** for typedefs with implicit int type. + */ + if (IS_Get (&Standard) >= STD_C99) { + Warning ("Type defaults to 'int' in typedef of '%s'", + D->Ident); + Note ("Implicit 'int' is an obsolete feature"); + } } } } From 0b06c34dfc89271a135c24573352715da1aaf187 Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 14 Jan 2024 00:08:41 +0800 Subject: [PATCH 093/707] Added primitive support for the ISO C99 inline feature as well as the __inline__ extension. No inlining is actually done but that part is not required by the standard. --- src/cc65/compile.c | 6 +- src/cc65/declare.c | 84 ++++++++++++++++++++++-- src/cc65/expr.c | 2 +- src/cc65/function.c | 6 ++ src/cc65/locals.c | 2 +- src/cc65/scanner.h | 1 + src/cc65/symentry.h | 4 ++ src/cc65/symtab.c | 12 +++- test/ref/Makefile | 1 + test/ref/bug1889-missing-identifier.cref | 2 +- test/ref/inline-error.c | 36 ++++++++++ test/ref/inline-error.cref | 20 ++++++ test/val/inline-func.c | 20 ++++++ 13 files changed, 184 insertions(+), 12 deletions(-) create mode 100644 test/ref/inline-error.c create mode 100644 test/ref/inline-error.cref create mode 100644 test/val/inline-func.c diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 108c80a28..b24751b59 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -121,7 +121,7 @@ static void Parse (void) } /* Read the declaration specifier */ - ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT, SC_NONE); + ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT | TS_FUNCTION_SPEC, SC_NONE); /* Don't accept illegal storage classes */ if ((Spec.StorageClass & SC_STORAGEMASK) == SC_AUTO || @@ -560,6 +560,10 @@ void Compile (const char* FileName) if ((Entry->Flags & SC_STORAGEMASK) == SC_STATIC && SymIsRef (Entry)) { Warning ("Static function '%s' used but never defined", Entry->Name); + } else if ((Entry->Flags & SC_INLINE) != 0) { + Warning ("Inline function '%s' %s but never defined", + Entry->Name, + SymIsRef (Entry) ? "used" : "declared"); } } } diff --git a/src/cc65/declare.c b/src/cc65/declare.c index f93305f01..6173b5460 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -124,9 +124,37 @@ static unsigned ParseOneStorageClass (void) +static unsigned ParseOneFuncSpec (void) +/* Parse and return a function specifier */ +{ + unsigned FuncSpec = 0; + + /* Check the function specifier given */ + switch (CurTok.Tok) { + + case TOK_INLINE: + FuncSpec = SC_INLINE; + NextToken (); + break; + + case TOK_NORETURN: + FuncSpec = SC_NORETURN; + NextToken (); + break; + + default: + break; + } + + return FuncSpec; +} + + + static int ParseStorageClass (DeclSpec* Spec) /* Parse storage class specifiers. Return true if a specifier is read even if -** it was duplicated or disallowed. */ +** it was duplicated or disallowed. +*/ { /* Check the storage class given */ unsigned StorageClass = ParseOneStorageClass (); @@ -151,6 +179,31 @@ static int ParseStorageClass (DeclSpec* Spec) +static int ParseFuncSpecClass (DeclSpec* Spec) +/* Parse function specifiers. Return true if a specifier is read even if it +** was duplicated or disallowed. +*/ +{ + /* Check the function specifiers given */ + unsigned FuncSpec = ParseOneFuncSpec (); + + if (FuncSpec == 0) { + return 0; + } + + while (FuncSpec != 0) { + if ((Spec->StorageClass & FuncSpec) != 0) { + Warning ("Duplicate function specifier"); + } + Spec->StorageClass |= FuncSpec; + FuncSpec = ParseOneFuncSpec (); + } + + return 1; +} + + + static void DuplicateQualifier (const char* Name) /* Print an error message */ { @@ -303,7 +356,8 @@ static void OptionalSpecifiers (DeclSpec* Spec, TypeCode* Qualifiers, typespec_t */ { TypeCode Q = T_QUAL_NONE; - int Continue; + int HasStorageClass; + int HasFuncSpec; do { /* There may be type qualifiers *before* any storage class specifiers */ @@ -311,11 +365,17 @@ static void OptionalSpecifiers (DeclSpec* Spec, TypeCode* Qualifiers, typespec_t *Qualifiers |= Q; /* Parse storage class specifiers anyway then check */ - Continue = ParseStorageClass (Spec); - if (Continue && (TSFlags & (TS_STORAGE_CLASS_SPEC | TS_FUNCTION_SPEC)) == 0) { + HasStorageClass = ParseStorageClass (Spec); + if (HasStorageClass && (TSFlags & TS_STORAGE_CLASS_SPEC) == 0) { Error ("Unexpected storage class specified"); } - } while (Continue || Q != T_QUAL_NONE); + + /* Parse function specifiers anyway then check */ + HasFuncSpec = ParseFuncSpecClass (Spec); + if (HasFuncSpec && (TSFlags & TS_FUNCTION_SPEC) == 0) { + Error ("Unexpected function specifiers"); + } + } while (Q != T_QUAL_NONE || HasStorageClass || HasFuncSpec); } @@ -2375,6 +2435,14 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) /* Parse attributes for this declarator */ ParseAttribute (D); + /* 'inline' is only allowed on functions */ + if (Mode != DM_ACCEPT_PARAM_IDENT && + (D->StorageClass & SC_TYPEMASK) != SC_FUNC && + (D->StorageClass & SC_INLINE) == SC_INLINE) { + Error ("'inline' on non-function declaration"); + D->StorageClass &= ~SC_INLINE; + } + /* Check a few pre-C99 things */ if (D->Ident[0] != '\0' && (Spec->Flags & DS_TYPE_MASK) == DS_DEF_TYPE) { /* Check and warn about an implicit int return in the function */ @@ -2478,7 +2546,7 @@ void ParseDeclSpec (DeclSpec* Spec, typespec_t TSFlags, unsigned DefStorage) Spec->Flags &= ~DS_DEF_STORAGE; /* Parse the type specifiers */ - ParseTypeSpec (Spec, TSFlags | TS_STORAGE_CLASS_SPEC | TS_FUNCTION_SPEC); + ParseTypeSpec (Spec, TSFlags | TS_STORAGE_CLASS_SPEC); /* If no explicit storage class is given, use the default */ if ((Spec->StorageClass & SC_STORAGEMASK) == 0) { @@ -2495,7 +2563,9 @@ void CheckEmptyDecl (const DeclSpec* Spec) ** warning if not. */ { - if ((Spec->Flags & DS_TYPE_MASK) == DS_NONE) { + if ((Spec->StorageClass & SC_INLINE) == SC_INLINE) { + Error ("'inline' on empty declaration"); + } else if ((Spec->Flags & DS_TYPE_MASK) == DS_NONE) { /* No declaration at all */ } else if ((Spec->Flags & DS_EXTRA_TYPE) == 0) { Warning ("Declaration does not declare anything"); diff --git a/src/cc65/expr.c b/src/cc65/expr.c index e5e5cc62e..a855e5b3c 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1407,7 +1407,7 @@ static void Primary (ExprDesc* E) } else { /* Let's see if this is a C99-style declaration */ DeclSpec Spec; - ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE, SC_AUTO); + ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE | TS_FUNCTION_SPEC, SC_AUTO); if ((Spec.Flags & DS_TYPE_MASK) != DS_NONE) { Error ("Mixed declarations and code are not supported in cc65"); diff --git a/src/cc65/function.c b/src/cc65/function.c index d570c2dde..596f9b617 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -518,6 +518,12 @@ void NewFunc (SymEntry* Func, FuncDesc* D) Error ("'main' cannot be declared as __fastcall__"); } + /* main() cannot be an inline function */ + if ((Func->Flags & SC_INLINE) == SC_INLINE) { + Error ("'main' cannot be declared inline"); + Func->Flags &= ~SC_INLINE; + } + /* Check return type */ if (GetUnqualRawTypeCode (ReturnType) == T_INT) { /* Determine if this is a main function in a C99 environment that diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 28e263bb8..777f6b8b9 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -563,7 +563,7 @@ void DeclareLocals (void) } /* Read the declaration specifier */ - ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT, SC_AUTO); + ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT | TS_FUNCTION_SPEC, SC_AUTO); /* Check variable declarations. We need distinguish between a default ** int type and the end of variable declarations. So we will do the diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index ccf3a8805..6fc3e5370 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -76,6 +76,7 @@ typedef enum token_t { /* Function specifiers */ TOK_INLINE, + TOK_NORETURN, TOK_FASTCALL, TOK_CDECL, diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index 7bfc18ea4..7871b9ade 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -151,6 +151,10 @@ struct CodeEntry; #define SC_THREAD 0x08000000U /* UNSUPPORTED: Thread-local storage class */ #define SC_STORAGEMASK 0x0F000000U /* Storage type mask */ +/* Function specifiers */ +#define SC_INLINE 0x10000000U /* Inline function */ +#define SC_NORETURN 0x20000000U /* Noreturn function */ + /* Label definition or reference */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index a76e60450..f5ef2a15c 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -1439,6 +1439,16 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags) Entry->V.F.WrappedCall = WrappedCall; Entry->V.F.WrappedCallData = WrappedCallData; } + + /* A files cope function declaration with the 'extern' storage + ** class or without the 'inline' specifier ensures that the + ** function definition (if any) is a non-inline definition. + */ + if (SymTab == SymTab0 && + ((Flags & SC_STORAGEMASK) == SC_EXTERN || + (Flags & SC_INLINE) == 0)) { + Entry->Flags |= SC_NOINLINEDEF; + } } /* Add an alias of the global symbol to the local symbol table */ @@ -1575,7 +1585,7 @@ void EmitExternals (void) if (SymIsRef (Entry) && !SymIsDef (Entry)) { /* An import */ g_defimport (Entry->Name, Flags & SC_ZEROPAGE); - } else if (SymIsDef (Entry)) { + } else if (SymIsDef (Entry) && ((Flags & SC_NOINLINEDEF) || (Flags & SC_INLINE) == 0)) { /* An export */ g_defexport (Entry->Name, Flags & SC_ZEROPAGE); } diff --git a/test/ref/Makefile b/test/ref/Makefile index 9ecb33c00..5c189c6cb 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -63,6 +63,7 @@ CUSTOMSOURCES = \ # exact error output is required ERRORSOURCES = \ custom-reference-error.c \ + inline-error.c \ bug1889-missing-identifier.c \ bug2312-preprocessor-error.c diff --git a/test/ref/bug1889-missing-identifier.cref b/test/ref/bug1889-missing-identifier.cref index 6317657d1..e77c1a7a1 100644 --- a/test/ref/bug1889-missing-identifier.cref +++ b/test/ref/bug1889-missing-identifier.cref @@ -1,4 +1,4 @@ bug1889-missing-identifier.c:3: Error: Identifier or ';' expected after declaration specifiers bug1889-missing-identifier.c:3: Warning: Implicit 'int' is an obsolete feature -bug1889-missing-identifier.c:4: Error: Declaration specifier or identifier expected +bug1889-missing-identifier.c:4: Error: 'inline' on empty declaration bug1889-missing-identifier.c:6: Error: Expression expected diff --git a/test/ref/inline-error.c b/test/ref/inline-error.c new file mode 100644 index 000000000..d8191025a --- /dev/null +++ b/test/ref/inline-error.c @@ -0,0 +1,36 @@ +/* C99 inline in declarations */ + +inline typedef int; /* Error */ +static inline int; /* Error */ +inline static int a1; /* Error */ +int inline (*fp1)(void); /* Error */ +typedef inline int f1_t(void); /* Error */ +inline int f1a(void); /* OK here warning later */ +inline extern int f1b(void); /* OK here warning later */ +extern inline int f1b(void); /* Same as above */ +inline static int f1c(void); /* OK here warning later */ +static inline int f1c(void); /* Same as above */ + +void foo(inline int x); /* Error */ +int a = sizeof (inline int); /* TODO: better error message */ +int b = sizeof (inline int (int)); /* TODO: better error message */ + +inline int main(void) /* Error */ +{ + inline typedef int; /* Error */ + static inline int; /* Error */ + extern inline int a2; /* Error */ + int inline (*fp2)(void); /* Error */ + typedef inline int f2_t(void); /* Error */ + inline int f2a(void); /* OK here warning later */ + inline extern int f2b(void); /* OK here warning later */ + extern inline int f2b(void); /* Same as above */ + + f1a(); /* Still imported */ + f1b(); /* Still imported */ + f1c(); /* Not imported */ + f2a(); /* Still imported */ + f2b(); /* Still imported */ +} + +/* Warning: non-external inline functions declared but undefined in TU */ diff --git a/test/ref/inline-error.cref b/test/ref/inline-error.cref new file mode 100644 index 000000000..abfdcdddd --- /dev/null +++ b/test/ref/inline-error.cref @@ -0,0 +1,20 @@ +inline-error.c:3: Error: 'inline' on empty declaration +inline-error.c:4: Error: 'inline' on empty declaration +inline-error.c:5: Error: 'inline' on non-function declaration +inline-error.c:6: Error: 'inline' on non-function declaration +inline-error.c:7: Error: 'inline' on non-function declaration +inline-error.c:14: Error: Unexpected function specifiers +inline-error.c:15: Error: Mixed declarations and code are not supported in cc65 +inline-error.c:16: Error: Mixed declarations and code are not supported in cc65 +inline-error.c:19: Error: 'main' cannot be declared inline +inline-error.c:20: Error: 'inline' on empty declaration +inline-error.c:21: Error: 'inline' on empty declaration +inline-error.c:22: Error: 'inline' on non-function declaration +inline-error.c:23: Error: 'inline' on non-function declaration +inline-error.c:24: Error: 'inline' on non-function declaration +inline-error.c:34: Warning: Variable 'fp2' is defined but never used +inline-error.c:37: Warning: Inline function 'f1a' used but never defined +inline-error.c:37: Warning: Inline function 'f1b' used but never defined +inline-error.c:37: Warning: Static function 'f1c' used but never defined +inline-error.c:37: Warning: Inline function 'f2a' used but never defined +inline-error.c:37: Warning: Inline function 'f2b' used but never defined diff --git a/test/val/inline-func.c b/test/val/inline-func.c new file mode 100644 index 000000000..b9e127aae --- /dev/null +++ b/test/val/inline-func.c @@ -0,0 +1,20 @@ +/* C99 inline */ + +#include + +inline static int f(int x, ...) +{ + return x * 2; +} + +extern inline int g(int x); + +int main(void) +{ + return f(g(7)) == 42 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +int g(int x) +{ + return x * 3; +} From de3087a7e9b7590ab8122d547e8ae9ac0d191b21 Mon Sep 17 00:00:00 2001 From: acqn Date: Sun, 14 Jan 2024 00:19:11 +0800 Subject: [PATCH 094/707] Removed the extra "unused parameter" warning when the parameter had an duplicated identifier error. --- src/cc65/symtab.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index a76e60450..d3544bfc4 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -170,7 +170,8 @@ static void CheckSymTable (SymTable* Tab) if (SymIsDef (Entry) && !SymIsRef (Entry) && !SymHasAttr (Entry, atUnused)) { if (Flags & SC_PARAM) { - if (IS_Get (&WarnUnusedParam)) { + if (IS_Get (&WarnUnusedParam) && + !IsAnonName (Entry->Name)) { Warning ("Parameter '%s' is never used", Entry->Name); } } else if ((Flags & SC_TYPEMASK) == SC_FUNC) { From afdf398a0b628704b23166cde21d986b23d168b6 Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 15 Jan 2024 23:56:11 +0800 Subject: [PATCH 095/707] Fixed repeated diagnosis when reading EOF in certain cases. --- src/cc65/declare.c | 6 +++--- src/cc65/locals.c | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 7f1d8b948..c3c1160a6 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -997,7 +997,7 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) /* Parse union fields */ UnionSize = 0; - while (CurTok.Tok != TOK_RCURLY) { + while (CurTok.Tok != TOK_RCURLY && CurTok.Tok != TOK_CEOF) { /* Get the type of the entry */ DeclSpec Spec; @@ -1217,7 +1217,7 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) FlexibleMember = 0; StructSize = 0; BitOffs = 0; - while (CurTok.Tok != TOK_RCURLY) { + while (CurTok.Tok != TOK_RCURLY && CurTok.Tok != TOK_CEOF) { /* Get the type of the entry */ DeclSpec Spec; @@ -1814,7 +1814,7 @@ static void ParseOldStyleParamDeclList (FuncDesc* F attribute ((unused))) } /* An optional list of type specifications follows */ - while (CurTok.Tok != TOK_LCURLY) { + while (CurTok.Tok != TOK_LCURLY && CurTok.Tok != TOK_CEOF) { DeclSpec Spec; int NeedClean; diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 28e263bb8..8bf7aa1d2 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -551,7 +551,9 @@ void DeclareLocals (void) /* A place to store info about potential initializations of auto variables */ CollAppend (&CurrentFunc->LocalsBlockStack, 0); - /* Loop until we don't find any more variables */ + /* Loop until we don't find any more variables. EOF is handled in the loop + ** as well. + */ while (1) { DeclSpec Spec; int NeedClean; From 07e349c517a4702c8c2af26064691dcf05c5e580 Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 15 Jan 2024 23:56:39 +0800 Subject: [PATCH 096/707] Skipped anonymous tag names in diagnosis on empty structs/unions. --- src/cc65/symtab.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index d3544bfc4..8ae49cdf3 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -955,7 +955,13 @@ SymEntry* AddStructSym (const char* Name, unsigned Flags, unsigned Size, SymTabl TagEntry = 0; } else if (Size == 0) { /* Empty struct is not supported now */ - Error ("Empty %s type '%s' is not supported", SCType == SC_STRUCT ? "struct" : "union", Name); + if (!IsAnonName (Name)) { + Error ("Empty %s type '%s' is not supported", + SCType == SC_STRUCT ? "struct" : "union", Name); + } else { + Error ("Empty %s type is not supported", + SCType == SC_STRUCT ? "struct" : "union"); + } TagEntry = 0; } } From e9bd9330c0b09f646a52e36c6cbf198015887d2f Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 15 Jan 2024 23:56:42 +0800 Subject: [PATCH 097/707] Added warning on some code patterns of faulty attempt to declare anonymous structs/unions. Removed unnecessary warning on tagless enum/struct/unions that would be invisible out of a function declaration. --- src/cc65/datatype.c | 18 ++++++++++++ src/cc65/datatype.h | 6 ++++ src/cc65/declare.c | 68 ++++++++++++++++++++------------------------- 3 files changed, 54 insertions(+), 38 deletions(-) diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 9c82e6773..4d6cb25a5 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -989,6 +989,24 @@ int IsIncompleteESUType (const Type* T) +int IsAnonESUType (const Type* T) +/* Return true if this is an anonymous ESU type */ +{ + SymEntry* TagSym = GetESUTagSym (T); + + return TagSym != 0 && SymHasAnonName (TagSym); +} + + + +int IsAnonStructClass (const Type* T) +/* Return true if this is an anonymous struct or union type */ +{ + return IsClassStruct (T) && IsAnonESUType (T); +} + + + int IsPassByRefType (const Type* T) /* Return true if this is a large struct/union type that doesn't fit in the ** primary. This returns false for the void value extension type since it is diff --git a/src/cc65/datatype.h b/src/cc65/datatype.h index dbe0eedaa..8446fb914 100644 --- a/src/cc65/datatype.h +++ b/src/cc65/datatype.h @@ -792,6 +792,12 @@ int IsESUType (const Type* T); int IsIncompleteESUType (const Type* T); /* Return true if this is an incomplete ESU type */ +int IsAnonESUType (const Type* T); +/* Return true if this is an anonymous ESU type */ + +int IsAnonStructClass (const Type* T); +/* Return true if this is an anonymous struct or union type */ + int IsPassByRefType (const Type* T); /* Return true if this is a large struct/union type that doesn't fit in the ** primary. This returns false for the void value extension type since it is diff --git a/src/cc65/declare.c b/src/cc65/declare.c index c3c1160a6..20e2e6879 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1020,7 +1020,8 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) ParseTypeSpec (&Spec, TS_DEFAULT_TYPE_NONE); /* Check if this is only a type declaration */ - if (CurTok.Tok == TOK_SEMI && (Spec.Flags & DS_EXTRA_TYPE) == 0) { + if (CurTok.Tok == TOK_SEMI && + !(IS_Get (&Standard) >= STD_CC65 && IsAnonStructClass (Spec.Type))) { CheckEmptyDecl (&Spec); NextToken (); continue; @@ -1061,22 +1062,12 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags) /* In cc65 mode, we allow anonymous structs/unions within ** a union. */ - SymEntry* TagEntry; - if (IS_Get (&Standard) >= STD_CC65 && - IsClassStruct (Decl.Type) && - (TagEntry = GetESUTagSym (Decl.Type)) && - SymHasAnonName (TagEntry)) { - /* This is an anonymous struct or union */ - AnonFieldName (Decl.Ident, GetBasicTypeName (Decl.Type), UnionTagEntry->V.S.ACount); + AnonFieldName (Decl.Ident, GetBasicTypeName (Decl.Type), UnionTagEntry->V.S.ACount); - /* Ignore CVR qualifiers */ - if (IsQualConst (Decl.Type) || IsQualVolatile (Decl.Type) || IsQualRestrict (Decl.Type)) { - Warning ("Anonymous %s qualifiers are ignored", GetBasicTypeName (Decl.Type)); - Decl.Type[0].C &= ~T_QUAL_CVR; - } - } else { - /* Invalid member */ - goto NextMember; + /* Ignore CVR qualifiers */ + if (IsQualConst (Decl.Type) || IsQualVolatile (Decl.Type) || IsQualRestrict (Decl.Type)) { + Warning ("Anonymous %s qualifiers are ignored", GetBasicTypeName (Decl.Type)); + Decl.Type[0].C &= ~T_QUAL_CVR; } } else if (FieldWidth > 0) { /* A bit-field without a name will get an anonymous one */ @@ -1240,7 +1231,8 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) ParseTypeSpec (&Spec, TS_DEFAULT_TYPE_NONE); /* Check if this is only a type declaration */ - if (CurTok.Tok == TOK_SEMI && (Spec.Flags & DS_EXTRA_TYPE) == 0) { + if (CurTok.Tok == TOK_SEMI && + !(IS_Get (&Standard) >= STD_CC65 && IsAnonStructClass (Spec.Type))) { CheckEmptyDecl (&Spec); NextToken (); continue; @@ -1308,22 +1300,12 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags) /* In cc65 mode, we allow anonymous structs/unions within ** a struct. */ - SymEntry* TagEntry; - if (IS_Get (&Standard) >= STD_CC65 && - IsClassStruct (Decl.Type) && - (TagEntry = GetESUTagSym (Decl.Type)) && - SymHasAnonName (TagEntry)) { - /* This is an anonymous struct or union */ - AnonFieldName (Decl.Ident, GetBasicTypeName (Decl.Type), StructTagEntry->V.S.ACount); + AnonFieldName (Decl.Ident, GetBasicTypeName (Decl.Type), StructTagEntry->V.S.ACount); - /* Ignore CVR qualifiers */ - if (IsQualConst (Decl.Type) || IsQualVolatile (Decl.Type) || IsQualRestrict (Decl.Type)) { - Warning ("Anonymous %s qualifiers are ignored", GetBasicTypeName (Decl.Type)); - Decl.Type[0].C &= ~T_QUAL_CVR; - } - } else { - /* Invalid member */ - goto NextMember; + /* Ignore CVR qualifiers */ + if (IsQualConst (Decl.Type) || IsQualVolatile (Decl.Type) || IsQualRestrict (Decl.Type)) { + Warning ("Anonymous %s qualifiers are ignored", GetBasicTypeName (Decl.Type)); + Decl.Type[0].C &= ~T_QUAL_CVR; } } else if (FieldWidth > 0) { /* A bit-field without a name will get an anonymous one */ @@ -1854,7 +1836,7 @@ static void ParseOldStyleParamDeclList (FuncDesc* F attribute ((unused))) } /* Warn about new local type declaration */ - if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0) { + if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0 && !IsAnonESUType (Spec.Type)) { Warning ("'%s' will be invisible out of this function", GetFullTypeName (Spec.Type)); } @@ -1957,7 +1939,7 @@ static void ParseAnsiParamList (FuncDesc* F) } /* Warn about new local type declaration */ - if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0) { + if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0 && !IsAnonESUType (Spec.Type)) { Warning ("'%s' will be invisible out of this function", GetFullTypeName (Spec.Type)); } @@ -2508,10 +2490,20 @@ void CheckEmptyDecl (const DeclSpec* Spec) if ((Spec->Flags & DS_TYPE_MASK) == DS_NONE) { /* No declaration at all */ } else if ((Spec->Flags & DS_EXTRA_TYPE) == 0) { - Warning ("Declaration does not declare anything"); - } else if (IsClassStruct (Spec->Type) && - !IsIncompleteESUType (Spec->Type) && - SymHasAnonName (GetESUTagSym (Spec->Type))) { + /* Empty declaration of basic types */ + Warning ("Useless declaration"); + } else if (IsAnonStructClass (Spec->Type)) { + /* This could be that the user made a wrong attempt to declare an + ** anonymous struct/union field outside a struct/union. + */ Warning ("Unnamed %s that defines no instances", GetBasicTypeName (Spec->Type)); + } else if (GetLexicalLevel () == LEX_LEVEL_STRUCT) { + /* This could be that the user made a wrong attempt to declare an + ** anonymous struct/union field inside a struct/union. Perhaps just + ** paranoid since it is not so uncommon to do forward declarations. + */ + if (!IsTypeEnum (Spec->Type) || ((Spec->Flags & DS_NEW_TYPE_DEF) == 0)) { + Warning ("Declaration defines no instances"); + } } } From b388ca0236940bd45402a63af901f325309f5f8d Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Mon, 15 Jan 2024 21:51:17 +0100 Subject: [PATCH 098/707] Fix #2357 - Copy est.size and flags of op when moving it --- src/cc65/coptlong.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/cc65/coptlong.c b/src/cc65/coptlong.c index 16f089e49..b378021b5 100644 --- a/src/cc65/coptlong.c +++ b/src/cc65/coptlong.c @@ -106,9 +106,13 @@ unsigned OptLongAssign (CodeSeg* S) !RegXUsed (S, I+11)) { L[1]->AM = L[11]->AM; + L[1]->Size = L[11]->Size; + L[1]->Flags = L[11]->Flags; CE_SetArg(L[1], L[11]->Arg); L[3]->AM = L[9]->AM; + L[3]->Size = L[9]->Size; + L[3]->Flags = L[9]->Flags; CE_SetArg(L[3], L[9]->Arg); CS_DelEntries (S, I+8, 4); @@ -188,9 +192,13 @@ unsigned OptLongCopy (CodeSeg* S) !RegXUsed (S, I+11)) { L[1]->AM = L[11]->AM; + L[1]->Size = L[11]->Size; + L[1]->Flags = L[11]->Flags; CE_SetArg(L[1], L[11]->Arg); L[3]->AM = L[9]->AM; + L[3]->Size = L[9]->Size; + L[3]->Flags = L[9]->Flags; CE_SetArg(L[3], L[9]->Arg); CS_DelEntries (S, I+8, 4); From 2c4ebe812c9ba5ddf0ae08d3294d78e14507d0b2 Mon Sep 17 00:00:00 2001 From: Bob Andrews Date: Mon, 15 Jan 2024 23:03:13 +0100 Subject: [PATCH 099/707] Revert "Fix #2357 - Copy est.size and flags of op when moving it" --- src/cc65/coptlong.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/cc65/coptlong.c b/src/cc65/coptlong.c index 7e30ef42e..29cf4d353 100644 --- a/src/cc65/coptlong.c +++ b/src/cc65/coptlong.c @@ -120,13 +120,9 @@ unsigned OptLongAssign (CodeSeg* S) !CS_RangeHasLabel(S, I, 12)) { L[1]->AM = L[11]->AM; - L[1]->Size = L[11]->Size; - L[1]->Flags = L[11]->Flags; CE_SetArg(L[1], L[11]->Arg); L[3]->AM = L[9]->AM; - L[3]->Size = L[9]->Size; - L[3]->Flags = L[9]->Flags; CE_SetArg(L[3], L[9]->Arg); CS_DelEntries (S, I+8, 4); @@ -215,13 +211,9 @@ unsigned OptLongCopy (CodeSeg* S) !CS_RangeHasLabel(S, I, 12)) { L[1]->AM = L[11]->AM; - L[1]->Size = L[11]->Size; - L[1]->Flags = L[11]->Flags; CE_SetArg(L[1], L[11]->Arg); L[3]->AM = L[9]->AM; - L[3]->Size = L[9]->Size; - L[3]->Flags = L[9]->Flags; CE_SetArg(L[3], L[9]->Arg); CS_DelEntries (S, I+8, 4); From dec65176f03f77592018f0ddb44411c0a5ddf0a7 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Mon, 15 Jan 2024 21:51:17 +0100 Subject: [PATCH 100/707] Fix #2357 - Copy est.size and flags of op when moving it --- src/cc65/coptlong.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/cc65/coptlong.c b/src/cc65/coptlong.c index 29cf4d353..7e30ef42e 100644 --- a/src/cc65/coptlong.c +++ b/src/cc65/coptlong.c @@ -120,9 +120,13 @@ unsigned OptLongAssign (CodeSeg* S) !CS_RangeHasLabel(S, I, 12)) { L[1]->AM = L[11]->AM; + L[1]->Size = L[11]->Size; + L[1]->Flags = L[11]->Flags; CE_SetArg(L[1], L[11]->Arg); L[3]->AM = L[9]->AM; + L[3]->Size = L[9]->Size; + L[3]->Flags = L[9]->Flags; CE_SetArg(L[3], L[9]->Arg); CS_DelEntries (S, I+8, 4); @@ -211,9 +215,13 @@ unsigned OptLongCopy (CodeSeg* S) !CS_RangeHasLabel(S, I, 12)) { L[1]->AM = L[11]->AM; + L[1]->Size = L[11]->Size; + L[1]->Flags = L[11]->Flags; CE_SetArg(L[1], L[11]->Arg); L[3]->AM = L[9]->AM; + L[3]->Size = L[9]->Size; + L[3]->Flags = L[9]->Flags; CE_SetArg(L[3], L[9]->Arg); CS_DelEntries (S, I+8, 4); From db8ac355cb7d4f32d820041bccf3a6905565bdad Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Tue, 16 Jan 2024 09:33:33 +0100 Subject: [PATCH 101/707] Cleaner updating of instructions --- src/cc65/coptlong.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/cc65/coptlong.c b/src/cc65/coptlong.c index 7e30ef42e..23c30875a 100644 --- a/src/cc65/coptlong.c +++ b/src/cc65/coptlong.c @@ -87,6 +87,7 @@ unsigned OptLongAssign (CodeSeg* S) L[0] = CS_GetEntry (S, I); if (CS_GetEntries (S, L+1, I+1, 12)) { + CodeEntry* N; if (/* Check the opcode sequence */ L[0]->OPC == OP65_LDA && L[1]->OPC == OP65_STA && @@ -119,15 +120,13 @@ unsigned OptLongAssign (CodeSeg* S) !RegXUsed (S, I+12) && !CS_RangeHasLabel(S, I, 12)) { - L[1]->AM = L[11]->AM; - L[1]->Size = L[11]->Size; - L[1]->Flags = L[11]->Flags; - CE_SetArg(L[1], L[11]->Arg); + N = NewCodeEntry (OP65_STA, L[11]->AM, L[11]->Arg, 0, L[11]->LI); + CS_DelEntry (S, I+1); + CS_InsertEntry (S, N, I+1); - L[3]->AM = L[9]->AM; - L[3]->Size = L[9]->Size; - L[3]->Flags = L[9]->Flags; - CE_SetArg(L[3], L[9]->Arg); + N = NewCodeEntry (OP65_STA, L[9]->AM, L[9]->Arg, 0, L[9]->LI); + CS_DelEntry (S, I+3); + CS_InsertEntry (S, N, I+3); CS_DelEntries (S, I+8, 4); @@ -183,6 +182,7 @@ unsigned OptLongCopy (CodeSeg* S) L[0] = CS_GetEntry (S, I); if (CS_GetEntries (S, L+1, I+1, 12)) { + CodeEntry *N; if (L[0]->OPC == OP65_LDA && !strncmp(L[0]->Arg, L[5]->Arg, strlen(L[5]->Arg)) && !strcmp(L[0]->Arg + strlen(L[5]->Arg), "+3") && @@ -214,15 +214,13 @@ unsigned OptLongCopy (CodeSeg* S) !RegXUsed (S, I+11) && !CS_RangeHasLabel(S, I, 12)) { - L[1]->AM = L[11]->AM; - L[1]->Size = L[11]->Size; - L[1]->Flags = L[11]->Flags; - CE_SetArg(L[1], L[11]->Arg); + N = NewCodeEntry (OP65_STA, L[11]->AM, L[11]->Arg, 0, L[11]->LI); + CS_DelEntry (S, I+1); + CS_InsertEntry (S, N, I+1); - L[3]->AM = L[9]->AM; - L[3]->Size = L[9]->Size; - L[3]->Flags = L[9]->Flags; - CE_SetArg(L[3], L[9]->Arg); + N = NewCodeEntry (OP65_STA, L[9]->AM, L[9]->Arg, 0, L[9]->LI); + CS_DelEntry (S, I+3); + CS_InsertEntry (S, N, I+3); CS_DelEntries (S, I+8, 4); From 0c53e7e0da864e65c62559b0037794bd024e0900 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Tue, 16 Jan 2024 20:50:50 +0100 Subject: [PATCH 102/707] Add test case for bug #2357 --- test/val/bug2357.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 test/val/bug2357.c diff --git a/test/val/bug2357.c b/test/val/bug2357.c new file mode 100644 index 000000000..a0cff0d19 --- /dev/null +++ b/test/val/bug2357.c @@ -0,0 +1,38 @@ +/* bug #2357 - Compiler produces invalid code after d8a3938 +*/ + +unsigned long test; + +unsigned long longarray[7]; + +void jsr_threebytes(void) { + +} + +/* having replaced two sty $zp with two sta $abs, but forgetting + * to update the instruction size, coptlong.c could cause a build + * error "Error: Range error (131 not in [-128..127])" if the + * computed codesize was under 126, but the real codesize was above + * 127. + * This tests verifies that the bug is fixed. + */ +unsigned char __fastcall__ foo (unsigned char res) +{ + if (res == 0) { + longarray[1]=test; /* 24 bytes - but the compiler thought 22 */ + longarray[2]=test; /* 48 bytes - but 44 */ + longarray[3]=test; /* 72 bytes - 66 */ + longarray[4]=test; /* 96 bytes - 88 */ + longarray[6]=test; /* 120 bytes - 110 */ + jsr_threebytes(); /* 123 - 113 */ + jsr_threebytes(); /* 126 - 116 */ + jsr_threebytes(); /* 129 - 119 */ + } + return 0; +} + +int main (void) +{ + foo(42); + return 0; +} From 348a9048b7bed27335301f5b8d3398baceb5f84e Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Tue, 9 Jan 2024 21:28:37 +0100 Subject: [PATCH 103/707] Convert _time_t_to_tm to asm 46 bytes size gain, -8% cycles on the unit tests --- libsrc/common/_time_t_to_tm.c | 64 ----------------- libsrc/common/_time_t_to_tm.s | 129 ++++++++++++++++++++++++++++++++++ libsrc/common/mktime.c | 9 ++- 3 files changed, 135 insertions(+), 67 deletions(-) delete mode 100644 libsrc/common/_time_t_to_tm.c create mode 100644 libsrc/common/_time_t_to_tm.s diff --git a/libsrc/common/_time_t_to_tm.c b/libsrc/common/_time_t_to_tm.c deleted file mode 100644 index 684cff752..000000000 --- a/libsrc/common/_time_t_to_tm.c +++ /dev/null @@ -1,64 +0,0 @@ -/*****************************************************************************/ -/* */ -/* gmtime.c */ -/* */ -/* Convert calendar time into broken down time in UTC */ -/* */ -/* */ -/* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - -struct tm* __fastcall__ _time_t_to_tm (const time_t t) -{ - static struct tm timebuf; - /* Since our ints are just 16 bits, split the given time into seconds, - ** hours and days. Each of the values will fit in a 16 bit variable. - ** The mktime routine will then do the rest. - */ - timebuf.tm_sec = t % 3600; - timebuf.tm_min = 0; - timebuf.tm_hour = (t / 3600) % 24; - timebuf.tm_mday = (t / (3600UL * 24UL)) + 1; - timebuf.tm_mon = 0; - timebuf.tm_year = 70; /* Base value is 1/1/1970 */ - - /* Call mktime to do the final conversion */ - mktime (&timebuf); - - /* Return the result */ - return &timebuf; -} diff --git a/libsrc/common/_time_t_to_tm.s b/libsrc/common/_time_t_to_tm.s new file mode 100644 index 000000000..ffabf15fc --- /dev/null +++ b/libsrc/common/_time_t_to_tm.s @@ -0,0 +1,129 @@ +; +; Colin Leroy-Mira, 2024 +; +; struct tm* __fastcall__ _time_t_to_tm (const time_t t) +; +; Helper to gmtime and localtime. Breaks down a number of +; seconds since Jan 1, 1970 into days, hours and seconds, +; so that each of them fits in 16 bits; passes the +; result to _mktime which fixes all values in the struct, +; and returns a pointer to the struct to callers. +; + + .export __time_t_to_tm + .import udiv32, _mktime + .importzp sreg, tmp3, ptr1, ptr2, ptr3, ptr4 + + .include "time.inc" + + .macpack cpu + +__time_t_to_tm: + ; Divide number of seconds since epoch, in ptr1:sreg, + ; by 86400 to get the number of days since epoch, and + ; the number of seconds today in the remainder. + + ; Load t as dividend (sreg is already set by the caller) + sta ptr1 + stx ptr1+1 + + ; Load 86400 as divisor + lda #$80 + sta ptr3 + lda #$51 + sta ptr3+1 + lda #$01 + sta ptr4 + lda #$00 + sta ptr4+1 + + ; Clear TM buf while we have zero in A + ldx #.sizeof(tm)-1 +: sta TM,x + dex + bne :- + + ; Divide t/86400 + jsr udiv32 + + ; Store the quotient (the number of full days), and increment + ; by one as epoch starts at day 1. + clc + lda ptr1 + adc #1 + sta TM + tm::tm_mday + lda ptr1+1 + adc #0 + sta TM + tm::tm_mday+1 + + ; Now divide the number of remaining seconds by 3600, + ; to get the number of hours, and the seconds in the + ; current hour, in neat 16-bit integers. + + ; Load the previous division's remainder (in ptr2:tmp3:tmp4) + ; as dividend + lda ptr2 + sta ptr1 + lda ptr2+1 + sta ptr1+1 + lda tmp3 + sta sreg + ; We ignore the high byte stored in tmp4 because it will be + ; zero. We'll zero sreg+1 right below, when we'll have + ; a convenient zero already in A. + + ; Load divisor + lda #<3600 + sta ptr3 + lda #>3600 + sta ptr3+1 + + ; Zero the two high bytes of the divisor and the high byte + ; of the dividend. + .if .cpu .bitand CPU_ISET_65SC02 + stz ptr4 + stz ptr4+1 + stz sreg+1 + .else + lda #$00 + sta ptr4 + sta ptr4+1 + sta sreg+1 + .endif + + ; Do the division + jsr udiv32 + + ; Store year + lda #70 + sta TM + tm::tm_year + + ; Store hours (the quotient of the last division) + lda ptr1 + sta TM + tm::tm_hour + lda ptr1+1 + sta TM + tm::tm_hour+1 + + ; Store seconds (the remainder of the last division) + lda ptr2 + sta TM + tm::tm_sec + lda ptr2+1 + sta TM + tm::tm_sec+1 + + ; The rest of the struct tm fields are zero. mktime + ; will take care of shifting extra seconds to minutes, + ; and extra days to months and years. + + ; Call mktime + lda #TM + jsr _mktime + + ; And return our pointer + lda #TM + rts + + .bss + +TM: .tag tm diff --git a/libsrc/common/mktime.c b/libsrc/common/mktime.c index c9ac1652c..7ea3e2bff 100644 --- a/libsrc/common/mktime.c +++ b/libsrc/common/mktime.c @@ -65,7 +65,8 @@ static const unsigned MonthDays [] = { /* Code */ /*****************************************************************************/ - +/* use statics for size optimisation (~34 bytes) */ +#pragma static-locals(push, on) time_t __fastcall__ mktime (register struct tm* TM) /* Make a time in seconds since 1/1/1970 from the broken down time in TM. @@ -74,8 +75,8 @@ time_t __fastcall__ mktime (register struct tm* TM) */ { register div_t D; - static int Max; - static unsigned DayCount; + int Max; + unsigned DayCount; /* Check if TM is valid */ if (TM == 0) { @@ -182,3 +183,5 @@ time_t __fastcall__ mktime (register struct tm* TM) ((unsigned) TM->tm_sec) - _tz.timezone; } + +#pragma static-locals(pop) From 03d5e5fba0ab9394d1f4ccd75068fb6d31cabe72 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Wed, 10 Jan 2024 22:20:43 +0100 Subject: [PATCH 104/707] Rewrite mktime in assembly -415 bytes, -39% cycles, Unit test expanded to cover more cases (there was a bug in 2100 before!) --- libsrc/common/_is_leap_year.h | 22 -- libsrc/common/_is_leap_year.s | 23 -- libsrc/common/_time_t_to_tm.s | 2 +- libsrc/common/divt.s | 2 +- libsrc/common/mktime.c | 187 ---------- libsrc/common/mktime.s | 476 +++++++++++++++++++++++++ test/val/lib_common_gmtime_localtime.c | 27 +- test/val/lib_common_mktime.c | 119 ++++--- 8 files changed, 575 insertions(+), 283 deletions(-) delete mode 100644 libsrc/common/_is_leap_year.h delete mode 100644 libsrc/common/_is_leap_year.s delete mode 100644 libsrc/common/mktime.c create mode 100644 libsrc/common/mktime.s diff --git a/libsrc/common/_is_leap_year.h b/libsrc/common/_is_leap_year.h deleted file mode 100644 index 378c462ff..000000000 --- a/libsrc/common/_is_leap_year.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -** _is_leap_year.h -** -** (C) Copyright 2024, Colin Leroy-Mira -** -*/ - - - -#ifndef __IS_LEAP_YEAR_H -#define __IS_LEAP_YEAR_H - - - -unsigned char __fastcall__ IsLeapYear (unsigned char Year); -/* Returns 1 if the given year is a leap year. Expects a year from 0 to 206, - * without 1900 added */ - - - -/* End of _is_leap_year.h */ -#endif diff --git a/libsrc/common/_is_leap_year.s b/libsrc/common/_is_leap_year.s deleted file mode 100644 index d3136c1c8..000000000 --- a/libsrc/common/_is_leap_year.s +++ /dev/null @@ -1,23 +0,0 @@ -; -; Colin Leroy-Mira, 2024 -; -; unsigned char __fastcall__ IsLeapYear (unsigned char Year) -; Returns 1 in A if the given year is a leap year. Expects a year from 0 to 206, -; without 1900 added. -; - - .export _IsLeapYear - -_IsLeapYear: - ldx #$00 ; Prepare X for rts - cmp #$00 ; Y 0 (1900) is not a leap year - beq NotLeap - cmp #$C8 ; Y 200 (2100) is not a leap year - beq NotLeap - and #$03 ; Year % 4 == 0 means leap year - bne NotLeap - lda #$01 ; Return 1 - rts -NotLeap: - lda #$00 ; Return 0 - rts diff --git a/libsrc/common/_time_t_to_tm.s b/libsrc/common/_time_t_to_tm.s index ffabf15fc..9bcf84184 100644 --- a/libsrc/common/_time_t_to_tm.s +++ b/libsrc/common/_time_t_to_tm.s @@ -41,7 +41,7 @@ __time_t_to_tm: ldx #.sizeof(tm)-1 : sta TM,x dex - bne :- + bpl :- ; Divide t/86400 jsr udiv32 diff --git a/libsrc/common/divt.s b/libsrc/common/divt.s index 7f2b4e1bb..52b6efd04 100644 --- a/libsrc/common/divt.s +++ b/libsrc/common/divt.s @@ -3,7 +3,7 @@ ; 2002-10-22, Greg King ; ; This signed-division function returns both the quotient and the remainder, -; in this structure: +; in this structure: (quotient in sreg, remainder in AX) ; ; typedef struct { ; int rem, quot; diff --git a/libsrc/common/mktime.c b/libsrc/common/mktime.c deleted file mode 100644 index 7ea3e2bff..000000000 --- a/libsrc/common/mktime.c +++ /dev/null @@ -1,187 +0,0 @@ -/*****************************************************************************/ -/* */ -/* mktime.c */ -/* */ -/* Make calendar time from broken down time and cleanup */ -/* */ -/* */ -/* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include -#include -#include "_is_leap_year.h" - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -#define JANUARY 0 -#define FEBRUARY 1 -#define DECEMBER 11 -#define JAN_1_1970 4 /* 1/1/1970 is a thursday */ - - - -static const unsigned char MonthLength [] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; -static const unsigned MonthDays [] = { - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 -}; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - -/* use statics for size optimisation (~34 bytes) */ -#pragma static-locals(push, on) - -time_t __fastcall__ mktime (register struct tm* TM) -/* Make a time in seconds since 1/1/1970 from the broken down time in TM. -** A call to mktime does also correct the time in TM to contain correct -** values. -*/ -{ - register div_t D; - int Max; - unsigned DayCount; - - /* Check if TM is valid */ - if (TM == 0) { - /* Invalid data */ - return (time_t) -1L; - } - - /* Adjust seconds. */ - D = div (TM->tm_sec, 60); - TM->tm_sec = D.rem; - - /* Adjust minutes */ - TM->tm_min += D.quot; - D = div (TM->tm_min, 60); - TM->tm_min = D.rem; - - /* Adjust hours */ - TM->tm_hour += D.quot; - D = div (TM->tm_hour, 24); - TM->tm_hour = D.rem; - - /* Adjust days */ - TM->tm_mday += D.quot; - - /* Adjust year */ - while (1) { - Max = 365UL + IsLeapYear (TM->tm_year); - if ((unsigned int)TM->tm_mday > Max) { - ++TM->tm_year; - TM->tm_mday -= Max; - } else { - break; - } - } - - /* Adjust month and year. This is an iterative process, since changing - ** the month will change the allowed days for this month. - */ - while (1) { - - /* Make sure, month is in the range 0..11 */ - D = div (TM->tm_mon, 12); - TM->tm_mon = D.rem; - TM->tm_year += D.quot; - - /* Now check if mday is in the correct range, if not, correct month - ** and eventually year and repeat the process. - */ - if (TM->tm_mon == FEBRUARY && IsLeapYear (TM->tm_year)) { - Max = 29; - } else { - Max = MonthLength[TM->tm_mon]; - } - if ((unsigned int)TM->tm_mday > Max) { - /* Must correct month and eventually, year */ - if (TM->tm_mon == DECEMBER) { - TM->tm_mon = JANUARY; - ++TM->tm_year; - } else { - ++TM->tm_mon; - } - TM->tm_mday -= Max; - } else { - /* Done */ - break; - } - } - - /* Ok, all time/date fields are now correct. Calculate the days in this - ** year. - */ - TM->tm_yday = MonthDays[TM->tm_mon] + TM->tm_mday - 1; - if (TM->tm_mon > FEBRUARY && IsLeapYear (TM->tm_year)) { - ++TM->tm_yday; - } - - /* Calculate days since 1/1/1970. In the complete epoch (1/1/1970 to - ** somewhere in 2106) all years dividable by 4 are leap years(1), - ** so dividing by 4 gives the days that must be added because of leap years. - ** (and the last leap year before 1970 was 1968) - ** (1): Exception on 2100, which is not leap, and handled just after. - */ - DayCount = ((unsigned) (TM->tm_year-70)) * 365U + - (((unsigned) (TM->tm_year-(68+1))) / 4) + - TM->tm_yday; - - /* Handle the 2100 exception */ - if (TM->tm_year == 200 && TM->tm_mon > FEBRUARY) { - DayCount--; - } else if (TM->tm_year > 200) { - DayCount--; - } - - /* Calculate the weekday */ - TM->tm_wday = (JAN_1_1970 + DayCount) % 7; - - /* No (US) daylight saving (for now) */ - TM->tm_isdst = 0; - - /* Return seconds since 1970 */ - return DayCount * 86400UL + - ((unsigned) TM->tm_hour) * 3600UL + - ((unsigned) TM->tm_min) * 60U + - ((unsigned) TM->tm_sec) - - _tz.timezone; -} - -#pragma static-locals(pop) diff --git a/libsrc/common/mktime.s b/libsrc/common/mktime.s new file mode 100644 index 000000000..ac5755a45 --- /dev/null +++ b/libsrc/common/mktime.s @@ -0,0 +1,476 @@ +; +; Colin Leroy-Mira, 2024 +; +; time_t __fastcall__ mktime (register struct tm* TM) +; +; Converts a struct tm to a time_t timestamp, making sure +; day, month, year, hour, minute and seconds are in the +; correct range. +; + + .export _mktime + .import __tz + .import pushax, pusha0, pusheax + .import shrax2, _div, tosumulax, tosumodax, tossubeax, tosaddeax, tosumuleax + .importzp ptr2, tmp3, sreg + + .include "time.inc" + +; ------------------------------------------------------------------------ +; Special values + +FEBRUARY = 1 +MARCH = 2 +JAN_1_1970 = 4 +N_SEC = 60 +N_MIN = 60 +N_HOUR = 24 +N_MON = 12 +N_DAY_YEAR = 365 +; ------------------------------------------------------------------------ +; Helpers + + ; Helper to shift overflows from one field to the next + ; Current field in Y, divisor in A + ; Keeps remainder in current field, and adds the quotient + ; to the next one +adjust_field: + pha ; Push divisor + iny ; Point to high byte of current field + lda (ptr2),y + tax + dey + sty tmp3 ; Store current field (_div will mess with + lda (ptr2),y ; tmp1 and tmp2) + jsr pushax + pla ; Load divisor + ldx #$00 + + jsr _div + + ldy tmp3 ; Store remainder in current field + sta (ptr2),y + iny + txa + sta (ptr2),y + + lda sreg ; Add quotient to next field + iny + clc + adc (ptr2),y + sta (ptr2),y + iny + lda sreg+1 + adc (ptr2),y + sta (ptr2),y + rts + + ; Returns 1 in A if the given year is a leap year. Expects a year + ; from 0 to 206, without 1900 added. +is_leap_year: + cmp #$00 ; Y 0 (1900) is not a leap year + beq not_leap + cmp #$C8 ; Y 200 (2100) is not a leap year + beq not_leap + and #$03 ; Year % 4 == 0 means leap year + bne not_leap + lda #$01 ; Return 1 + rts +not_leap: + lda #$00 ; Return 0 + rts + + ; Returns the number of days in the current month/year in A +get_days_in_month: + ldy #tm::tm_mon + lda (ptr2),y + tax + lda months_len,x + cpx #FEBRUARY + beq :+ + rts +: tax + ldy #tm::tm_year ; Adjust for leap years + lda (ptr2),y + jsr is_leap_year + beq :+ + inx +: txa + rts + + ; Add AX to counter +addaxcounter: + clc + adc Counter + sta Counter ; Store in Counter + txa + adc Counter+1 + sta Counter+1 + rts + + ; Helpers for long chain of arithmetic on day counter. + ; Reload Counter and push it on the stack +load_and_push_counter: + lda Counter+3 + sta sreg+1 + lda Counter+2 + sta sreg + lda Counter + ldx Counter+1 + jsr pusheax + rts + + ; Store result in AX:sreg to Counter +store_counter: + sta Counter + stx Counter+1 + lda sreg + sta Counter+2 + lda sreg+1 + sta Counter+3 + rts + +; ------------------------------------------------------------------------ +; Code + +_mktime: + sta ptr2 ; Store struct to ptr2, which arithmetic + stx ptr2+1 ; functions won't touch + + ; Check pointer validity + ora ptr2+1 + bne :+ + lda #$FF + tax + sta sreg + sta sreg+1 + rts + + ; Adjust seconds +: ldy #tm::tm_sec + lda #N_SEC + jsr adjust_field + + ; Adjust minutes + ldy #tm::tm_min + lda #N_MIN + jsr adjust_field + + ; Adjust hours + ldy #tm::tm_hour + lda #N_HOUR + jsr adjust_field + + ;Shift one year as long as tm_mday is more than a year + ldy #tm::tm_year + lda (ptr2),y + +dec_by_year: + jsr is_leap_year ; Compute max numbers of days in year + clc + adc #N_DAY_YEAR + beq :+ ; High byte equal, check low byte + bcs do_year_dec ; High byte greater, decrement + bcc dec_by_month ; Low byte lower, we're done +: dey + lda (ptr2),y + cmp Max + bcc dec_by_month + beq dec_by_month + +do_year_dec: + ; Decrement days + ldy #tm::tm_mday + lda (ptr2),y + sbc Max ; Carry already set + sta (ptr2),y + iny + lda (ptr2),y + sbc #>N_DAY_YEAR + sta (ptr2),y + + ; Increment year + ldy #tm::tm_year + lda (ptr2),y + clc + adc #1 + sta (ptr2),y ; No carry possible here either + bcc dec_by_year ; bra, go check next year + +dec_by_month: + ; We're done decrementing days by full years, now do it + ; month per month. + ldy #tm::tm_mon + lda #N_MON + jsr adjust_field + + ; Get max day for this month + jsr get_days_in_month + sta Max + + ; So, do we have more days than this month? + ldy #tm::tm_mday+1 + lda (ptr2),y + bne do_month_dec ; High byte not zero, sure we do + dey + lda (ptr2),y + cmp Max + bcc calc_tm_yday ; No + beq calc_tm_yday + +do_month_dec: + ; Decrement days + ldy #tm::tm_mday + lda (ptr2),y + sec + sbc Max + sta (ptr2),y + iny + lda (ptr2),y + sbc #$00 + sta (ptr2),y + + ; Increment month + ldy #tm::tm_mon + lda (ptr2),y + clc + adc #1 + sta (ptr2),y + + bne dec_by_month ; Check next month + +calc_tm_yday: + ; We finished decrementing tm_mday and have put it in the correct + ; year/month range. Now compute the day of the year. + ldy #tm::tm_mday ; Get current day of month + lda (ptr2),y + sta Counter ; Store it in Counter + + lda #$00 ; Init counter high bytes + sta Counter+1 + sta Counter+2 + sta Counter+3 + + ldy #tm::tm_mon ; Get current month + lda (ptr2),y + asl + tax + clc + lda yday_by_month,x ; Get yday for this month's start + adc Counter ; Add it to counter + sta Counter + inx + lda yday_by_month,x + adc Counter+1 + sta Counter+1 + + ldy #tm::tm_year ; Adjust for leap years (if after feb) + lda (ptr2),y + jsr is_leap_year + beq dec_counter + ldy #tm::tm_mon ; Leap year, get current month + lda (ptr2),y + cmp #MARCH + bcs store_yday + +dec_counter: + lda Counter ; Decrease counter by one (yday starts at 0), + bne :+ ; unless we're after february in a leap year + dec Counter+1 +: dec Counter + +store_yday: + ldy #tm::tm_yday ; Store tm_yday + lda Counter + sta (ptr2),y + iny + lda Counter+1 + sta (ptr2),y + + ; Now calculate total day count since epoch with the formula: + ; ((unsigned) (TM->tm_year-70)) * 365U + (number of days per year since 1970) + ; (((unsigned) (TM->tm_year-(68+1))) / 4) + (one extra day per leap year since 1970) + ; TM->tm_yday (number of days in this year) + + ldy #tm::tm_year ; Get full years + lda (ptr2),y + sec + sbc #70 + ldx #0 + jsr pushax + lda #N_DAY_YEAR + + jsr tosumulax + jsr addaxcounter + + ; Add one day per leap year + ldy #tm::tm_year ; Get full years + lda (ptr2),y + sec + sbc #69 + ldx #0 + jsr shrax2 ; Divide by 4 + + jsr addaxcounter + + ; Handle the 2100 exception (which was considered leap by "Add one day + ; per leap year" just before) + ldy #tm::tm_year ; Get full years + lda (ptr2),y + cmp #201 + bcc finish_calc ; <= 200, nothing to do + + lda Counter + bne :+ + dec Counter+1 +: dec Counter + +finish_calc: + ; Now we can compute the weekday. + lda Counter + clc + adc #JAN_1_1970 + pha + lda Counter+1 + adc #0 + tax + pla + jsr pushax + + lda #7 ; Modulo 7 + ldx #0 + jsr tosumodax + + ldy #tm::tm_wday ; Store tm_wday + sta (ptr2),y + iny + txa + sta (ptr2),y + + ; DST + lda #$00 ; Store tm_isdst + ldy #tm::tm_isdst + sta (ptr2),y + iny + sta (ptr2),y + + ; Our struct tm is all fixed and every field calculated. + ; We can finally count seconds according to this formula: + ; seconds = (full days since epoch) * 86400UL + + ; ((unsigned) TM->tm_hour) * 3600UL + + ; ((unsigned) TM->tm_min) * 60U + + ; ((unsigned) TM->tm_sec) - + ; _tz.timezone; + + ; We already have the number of days since epoch in our counter, + ; from just before when we computed tm_wday. Reuse it. + jsr load_and_push_counter + lda #$00 ; Multiply by 86400 + sta sreg+1 + lda #$01 + sta sreg + lda #$80 + ldx #$51 + jsr tosumuleax + jsr store_counter ; Store into counter + + ; Push counter to add 3600 * hours to it + jsr load_and_push_counter + + ldx #$00 ; Load hours + stx sreg + stx sreg+1 + ldy #tm::tm_hour + lda (ptr2),y + jsr pusheax ; Push + ldx #$00 ; Load 3600 + stx sreg + stx sreg+1 + lda #<3600 + ldx #>3600 + jsr tosumuleax ; Multiply (pops the pushed hours) + jsr tosaddeax ; Add to counter (pops the pushed counter) + jsr store_counter ; Store counter + + ; Push counter to add 60 * min to it + jsr load_and_push_counter + + ldy #tm::tm_min ; Load minutes + lda (ptr2),y + jsr pusha0 ; Push + lda #N_MIN + ldx #0 + stx sreg + stx sreg+1 + jsr tosumulax ; Multiply + jsr tosaddeax ; Add to pushed counter + jsr store_counter ; Store + + ; Add seconds + jsr load_and_push_counter + + ldy #tm::tm_sec ; Load seconds + lda (ptr2),y + ldx #0 + stx sreg + stx sreg+1 + jsr tosaddeax ; Simple addition there + + ; No need to store/load/push the counter here, simply to push it + ; for the last substraction + jsr pusheax + + ; Substract timezone + lda __tz+1+3 + sta sreg+1 + lda __tz+1+2 + sta sreg + ldx __tz+1+1 + lda __tz+1 + jsr tossubeax + + ; And we're done! + rts + + .data + +months_len: + .byte 31 + .byte 28 + .byte 31 + .byte 30 + .byte 31 + .byte 30 + .byte 31 + .byte 31 + .byte 30 + .byte 31 + .byte 30 + .byte 31 + +yday_by_month: + .word 0 + .word 31 + .word 59 + .word 90 + .word 120 + .word 151 + .word 181 + .word 212 + .word 243 + .word 273 + .word 304 + .word 334 + + + .bss + +Max: .res 1 ; We won't need a high byte +Counter: + .res 4 diff --git a/test/val/lib_common_gmtime_localtime.c b/test/val/lib_common_gmtime_localtime.c index 143d15831..9ba4d6a0d 100644 --- a/test/val/lib_common_gmtime_localtime.c +++ b/test/val/lib_common_gmtime_localtime.c @@ -6,6 +6,9 @@ int fails = 0; time_t timestamps[] = { 0, + 0x41eb00, + 0x1e7cb00, + 0x21c8700, 0x2FFFFFFF, 0x6FFFFFFF, 0xF48656FF, @@ -19,6 +22,9 @@ time_t timestamps[] = { /* Values checked against glibc 2.37's implementation of ctime() */ const char *dates_gmt[] = { "Thu Jan 1 00:00:00 1970\n", + "Fri Feb 20 00:00:00 1970\n", + "Wed Jan 6 00:00:00 1971\n", + "Mon Feb 15 00:00:00 1971\n", "Sun Jul 9 16:12:47 1995\n", "Wed Jul 18 05:49:51 2029\n", "Thu Dec 31 23:59:59 2099\n", @@ -32,6 +38,9 @@ const char *dates_gmt[] = { const char *dates_gmt_plus_one[] = { "Thu Jan 1 01:00:00 1970\n", + "Fri Feb 20 01:00:00 1970\n", + "Wed Jan 6 01:00:00 1971\n", + "Mon Feb 15 01:00:00 1971\n", "Sun Jul 9 17:12:47 1995\n", "Wed Jul 18 06:49:51 2029\n", "Fri Jan 1 00:59:59 2100\n", @@ -70,15 +79,15 @@ int main (void) timestamps[i], dates_gmt[i], str); } - /* Check localtime at UTC+1 */ - _tz.timezone = 3600; - tm = localtime(×tamps[i]); - str = asctime(tm); - if (strcmp(str, dates_gmt_plus_one[i])) { - fails++; - printf("localtime: Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n", - timestamps[i], dates_gmt_plus_one[i], str); - } + // /* Check localtime at UTC+1 */ + // _tz.timezone = 3600; + // tm = localtime(×tamps[i]); + // str = asctime(tm); + // if (strcmp(str, dates_gmt_plus_one[i])) { + // fails++; + // printf("localtime: Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n", + // timestamps[i], dates_gmt_plus_one[i], str); + // } } return fails; } diff --git a/test/val/lib_common_mktime.c b/test/val/lib_common_mktime.c index 832ce3834..5d42db874 100644 --- a/test/val/lib_common_mktime.c +++ b/test/val/lib_common_mktime.c @@ -4,58 +4,97 @@ int fails = 0; -time_t timestamps[] = { - 0, - 0x2FFFFFFF, - 0x6FFFFFFF, - 0xF48656FF, - 0xF4865700, - 0xFC5A3EFF, - 0x6D6739FF, - 0x6D673A00, - 0xFFFFFFFF, +typedef struct _test_data { + time_t t; + struct tm tm; + char *str; +} test_data; + +/* Test data generated using glibc 2.37 */ +test_data data[] = { + /* First year */ + {0x00000000, {0, 0, 0, 1, 0, 70, 0, 4}, "Thu Jan 1 00:00:00 1970\n"}, + {0x004e7970, {56, 34, 12, 1, 2, 70, 59, 0}, "Sun Mar 1 12:34:56 1970\n"}, + {0x01e1337f, {59, 59, 23, 31, 11, 70, 364, 4}, "Thu Dec 31 23:59:59 1970\n"}, + + /* First leap year */ + {0x03c26700, {0, 0, 0, 1, 0, 72, 0, 6}, "Sat Jan 1 00:00:00 1972\n"}, + {0x03c8fe7f, {59, 59, 23, 5, 0, 72, 4, 3}, "Wed Jan 5 23:59:59 1972\n"}, + {0x041180ff, {59, 59, 23, 29, 1, 72, 59, 2}, "Tue Feb 29 23:59:59 1972\n"}, + {0x04118100, {0, 0, 0, 1, 2, 72, 60, 3}, "Wed Mar 1 00:00:00 1972\n"}, + {0x05a4ebff, {59, 59, 23, 31, 11, 72, 365, 0}, "Sun Dec 31 23:59:59 1972\n"}, + + /* A non-leap year */ + {0x63b0cd00, {0, 0, 0, 1, 0, 123, 0, 0}, "Sun Jan 1 00:00:00 2023\n"}, + {0x63fe957f, {59, 59, 23, 28, 1, 123, 58, 2}, "Tue Feb 28 23:59:59 2023\n"}, + {0x63fe9580, {0, 0, 0, 1, 2, 123, 59, 3}, "Wed Mar 1 00:00:00 2023\n"}, + {0x656d4ec0, {0, 0, 4, 4, 11, 123, 337, 1}, "Mon Dec 4 04:00:00 2023\n"}, + {0x6592007f, {59, 59, 23, 31, 11, 123, 364, 0}, "Sun Dec 31 23:59:59 2023\n"}, + + /* Another leap year */ + {0x65920080, {0, 0, 0, 1, 0, 124, 0, 1}, "Mon Jan 1 00:00:00 2024\n"}, + {0x65e11a7f, {59, 59, 23, 29, 1, 124, 59, 4}, "Thu Feb 29 23:59:59 2024\n"}, + {0x65e11a80, {0, 0, 0, 1, 2, 124, 60, 5}, "Fri Mar 1 00:00:00 2024\n"}, + {0x6774857f, {59, 59, 23, 31, 11, 124, 365, 2}, "Tue Dec 31 23:59:59 2024\n"}, + + /* End of century */ + {0xf48656ff, {59, 59, 23, 31, 11, 199, 364, 4}, "Thu Dec 31 23:59:59 2099\n"}, + + /* A non-leap year for exceptional reasons */ + {0xf4865700, {0, 0, 0, 1, 0, 200, 0, 5}, "Fri Jan 1 00:00:00 2100\n"}, + {0xf4d41f7f, {59, 59, 23, 28, 1, 200, 58, 0}, "Sun Feb 28 23:59:59 2100\n"}, + {0xf4d41f80, {0, 0, 0, 1, 2, 200, 59, 1}, "Mon Mar 1 00:00:00 2100\n"}, + {0xf4fceff0, {0, 0, 23, 31, 2, 200, 89, 3}, "Wed Mar 31 23:00:00 2100\n"}, + {0xf6678a7f, {59, 59, 23, 31, 11, 200, 364, 5}, "Fri Dec 31 23:59:59 2100\n"}, + + /* First post-2100 leap year */ + {0xfc0b2500, {0, 0, 0, 1, 0, 204, 0, 2}, "Tue Jan 1 00:00:00 2104\n"}, + {0xfc5a3eff, {59, 59, 23, 29, 1, 204, 59, 5}, "Fri Feb 29 23:59:59 2104\n"}, + {0xfc5a3f00, {0, 0, 0, 1, 2, 204, 60, 6}, "Sat Mar 1 00:00:00 2104\n"}, + {0xfcaa9c70, {0, 0, 23, 30, 3, 204, 120, 3}, "Wed Apr 30 23:00:00 2104\n"}, + + /* End of epoch */ + {0xfdedaa00, {0, 0, 0, 1, 0, 205, 0, 4}, "Thu Jan 1 00:00:00 2105\n"}, + {0xffffffff, {15, 28, 6, 7, 1, 206, 37, 0}, "Sun Feb 7 06:28:15 2106\n"} }; -/* Values checked against glibc 2.37's implementation of ctime() */ -const char *dates[] = { - "Thu Jan 1 00:00:00 1970\n", - "Sun Jul 9 16:12:47 1995\n", - "Wed Jul 18 05:49:51 2029\n", - "Thu Dec 31 23:59:59 2099\n", - "Fri Jan 1 00:00:00 2100\n", - "Fri Feb 29 23:59:59 2104\n", - "Tue Feb 29 23:59:59 2028\n", - "Wed Mar 1 00:00:00 2028\n", - "Sun Feb 7 06:28:15 2106\n", - NULL -}; +static int compare_tm(time_t t, struct tm *tm, struct tm *ref) { + if (memcmp(tm, ref, sizeof(tm))) { + printf("0x%lx: unexpected tm from gmtime: " + "expected {%u, %u, %u, %u, %u, %u, %u, %u}, " + "got {%u, %u, %u, %u, %u, %u, %u, %u}\n", + t, + ref->tm_sec, ref->tm_min, ref->tm_hour, ref->tm_mday, ref->tm_mon, ref->tm_year, ref->tm_yday, ref->tm_wday, + tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_yday, tm->tm_wday); + return 1; + } + return 0; +} int main (void) { - struct tm tm; - time_t t; int i; /* Verify conversion both ways */ - for (t = 0x0FFFFFFF; ; t += 0x10000000) { + for (i = 0; ; i++) { + time_t t = data[i].t; + time_t r; struct tm *tm = gmtime(&t); - time_t r = mktime(tm); - if (t != r) { - fails++; - printf("Unexpected result for t %lx: %lx\n", t, r); - } - if (t == 0xFFFFFFFF) { - break; - } - } + r = mktime(tm); - for (i = 0; dates[i] != NULL; i++) { - char *str = ctime(×tamps[i]); - if (strcmp(str, dates[i])) { + if (t != r) { + printf("unexpected timestamp from mktime: expected 0x%lx, got 0x%lx\n", t, r); fails++; - printf("Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n", - timestamps[i], dates[i], str); } + if (compare_tm(t, tm, &data[i].tm)) { + fails++; + } + if (strcmp(data[i].str, ctime(&t))) { + printf("0x%lx: unexpected ctime result: expected %s, got %s", t, data[i].str, ctime(&t)); + } + + if (t == 0xFFFFFFFF) + break; } return fails; } From 10282a9b7402f5390fb93b6938ed902e495f7a7c Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Wed, 10 Jan 2024 22:26:55 +0100 Subject: [PATCH 105/707] Rewrite asctime() in assembler (-7 bytes) --- libsrc/common/asctime.c | 59 ------------------------------ libsrc/common/asctime.s | 81 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 59 deletions(-) delete mode 100644 libsrc/common/asctime.c create mode 100644 libsrc/common/asctime.s diff --git a/libsrc/common/asctime.c b/libsrc/common/asctime.c deleted file mode 100644 index b46f29128..000000000 --- a/libsrc/common/asctime.c +++ /dev/null @@ -1,59 +0,0 @@ -/*****************************************************************************/ -/* */ -/* asctime.c */ -/* */ -/* Convert a broken down time into a string */ -/* */ -/* */ -/* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - -/* - CAUTION: we need to reserve enough space to be able to hold the maximum - length string: - - 1234567890123456789012345678901234567 - "Wednesday September ..1 00:00:00 1970" -*/ - -char* __fastcall__ asctime (const struct tm* timep) -{ - static char buf[38]; - - /* Format into given buffer and return the result */ - return strftime (buf, sizeof (buf), "%c\n", timep)? buf : 0; -} diff --git a/libsrc/common/asctime.s b/libsrc/common/asctime.s new file mode 100644 index 000000000..efcf34b41 --- /dev/null +++ b/libsrc/common/asctime.s @@ -0,0 +1,81 @@ +; +; Colin Leroy-Mira, 2024 +; +; char* __fastcall__ asctime (const struct tm* timep) +; + + .export _asctime + .import _strftime, pushax + .importzp ptr1 + .include "time.inc" + + .macpack cpu + +; ------------------------------------------------------------------------ +; Special values + +; We need to be able to store up to 38 bytes: +; 1234567890123456789012345678901234567 +; "Wednesday September ..1 00:00:00 1970" +MAX_BUF_LEN = 38 + +; ------------------------------------------------------------------------ +; Code + +_asctime: + ; Backup timep + .if (.cpu .bitand ::CPU_ISET_65SC02) + pha + phx + .else + sta ptr1 + stx ptr1+1 + .endif + + ; Push buf + lda #buf + jsr pushax + + ; Push sizeof(buf) + lda #MAX_BUF_LEN + jsr pushax + + ; Push format string + lda #fmt + jsr pushax + + ; Restore timep + .if (.cpu .bitand ::CPU_ISET_65SC02) + plx + pla + .else + lda ptr1 + ldx ptr1+1 + .endif + + ; Call formatter + jsr _strftime + + ; Check return status + bne :+ + cpx #$00 + bne :+ + rts + +: lda #buf + rts + + .data + +fmt: .byte '%' + .byte 'c' + .byte $0A + .byte $00 + + .bss + +buf: .res MAX_BUF_LEN From 9471e128b5091838695ab9695b3145d33ac6b22f Mon Sep 17 00:00:00 2001 From: acqn Date: Thu, 18 Jan 2024 20:59:46 +0800 Subject: [PATCH 106/707] Fixed segname pragmas right after a function definition. --- src/cc65/function.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cc65/function.c b/src/cc65/function.c index 4b4060f2a..d570c2dde 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -685,9 +685,6 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* Leave the lexical level */ LeaveFunctionLevel (); - /* Eat the closing brace */ - ConsumeRCurly (); - /* Restore the old literal pool, remembering the one for the function */ Func->V.F.LitPool = PopLiteralPool (); @@ -699,6 +696,12 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* Switch back to the old segments */ PopSegContext (); + /* Eat the closing brace after we've done everything with the function + ** definition. This way we won't have troubles with pragmas right after + ** the closing brace. + */ + ConsumeRCurly(); + /* Reset the current function pointer */ FreeFunction (CurrentFunc); CurrentFunc = 0; From 166a4b25f7fa6eb9b0ccb3a785a6fabf36492af1 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sun, 14 Jan 2024 18:27:41 +0100 Subject: [PATCH 107/707] Apple2: implement sleep using MONWAIT Also publish detect_iigs(), set_iigs_speed() and get_iigs_speed(). Refactor to only store one ostype variable. --- doc/apple2.sgml | 16 ++++++++ doc/apple2enh.sgml | 16 ++++++++ doc/funcref.sgml | 70 ++++++++++++++++++++++++++++++++++ include/accelerator.h | 32 +++++++++++++++- libsrc/apple2/detect_iigs.s | 17 +++++++++ libsrc/apple2/get_iigs_speed.s | 22 +++++++++++ libsrc/apple2/get_ostype.s | 2 +- libsrc/apple2/set_iigs_speed.s | 29 ++++++++++++++ libsrc/apple2/sleep.s | 54 ++++++++++++++++++++++++++ libsrc/apple2/wait.s | 20 ++++++++++ libsrc/apple2/waitvsync.s | 16 +------- 11 files changed, 277 insertions(+), 17 deletions(-) create mode 100644 libsrc/apple2/detect_iigs.s create mode 100644 libsrc/apple2/get_iigs_speed.s create mode 100644 libsrc/apple2/set_iigs_speed.s create mode 100644 libsrc/apple2/sleep.s create mode 100644 libsrc/apple2/wait.s diff --git a/doc/apple2.sgml b/doc/apple2.sgml index f1603c428..fb49ea941 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -331,12 +331,28 @@ usage. _filetype _datetime get_ostype +gmtime_dt +mktime_dt rebootafterexit ser_apple2_slot tgi_apple2_mix +Apple IIgs specific functions in accelerator.h

+ +In addition to those, the for declaration and +usage. + + +detect_iigs +get_iigs_speed +set_iigs_speed + + + Hardware access

There's currently no support for direct hardware access. This does not mean diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index e27501577..593b226ba 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -332,6 +332,8 @@ usage. _filetype _datetime get_ostype +gmtime_dt +mktime_dt rebootafterexit ser_apple2_slot tgi_apple2_mix @@ -340,6 +342,20 @@ usage. +Apple IIgs specific functions in accelerator.h

+ +In addition to those, the for declaration and +usage. + + +detect_iigs +get_iigs_speed +set_iigs_speed + + + Hardware access

There's currently no support for direct hardware access. This does not mean diff --git a/doc/funcref.sgml b/doc/funcref.sgml index c8a818295..740a6d62e 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -71,18 +71,21 @@ function. + + + @@ -104,6 +107,8 @@ function. _dos_type + + rebootafterexit @@ -3453,6 +3458,26 @@ used in presence of a prototype. +detect_iigs

+ + + +/ + +The function is specific to the Apple2 and Apple2enh platforms. + +, +, + + + + detect_scpu

@@ -4167,6 +4192,27 @@ header files define constants that can be used to check the return code. +get_iigs_speed

+ + + +/ + +The function is specific to the Apple2 and Apple2enh platforms. +See the accelerator.h header for the speed definitions. + +, +, + + + + get_scpu_speed

@@ -6985,6 +7031,30 @@ clean-up when exiting the program. +set_iigs_speed

+ + + +/ + +The function is specific to the Apple2 and Apple2enh platforms. +See the accelerator.h header for the speed definitions. +Accepted parameters are SPEED_SLOW and SPEED_FAST (all other values are +considered SPEED_FAST). + +, +, + + + + set_scpu_speed

diff --git a/include/accelerator.h b/include/accelerator.h index b5d8d0194..0137a7fed 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -304,6 +304,36 @@ unsigned char detect_turbomaster (void); * 0x01 : C64 Turbo Master cartridge present */ +unsigned char __fastcall__ set_iigs_speed (unsigned char speed); + +/* Set the speed of the Apple IIgs CPU. + * + * Possible values: + * SPEED_SLOW : 1 Mhz mode + * SPEED_FAST : Fast mode (2.8MHz or more, depending on the presence of + * an accelerator) + * + * Any other value will be interpreted as SPEED_FAST. + */ + +unsigned char get_iigs_speed (void); + +/* Get the speed of the Apple IIgs CPU. + * + * Possible return values: + * SPEED_SLOW : 1 Mhz mode + * SPEED_FAST : Fast mode (2.8MHz or more, depending on the presence of + * an accelerator) + */ + +unsigned char detect_iigs (void); + +/* Check whether we are running on an Apple IIgs. + * + * Possible return values: + * 0x00 : No + * 0x01 : Yes + */ + /* End of accelerator.h */ #endif - diff --git a/libsrc/apple2/detect_iigs.s b/libsrc/apple2/detect_iigs.s new file mode 100644 index 000000000..f82a464ac --- /dev/null +++ b/libsrc/apple2/detect_iigs.s @@ -0,0 +1,17 @@ +; +; Colin Leroy-Mira , 2024 +; +; void __fastcall__ detect_iigs(void) +; + + .export _detect_iigs + .import ostype, return0, return1 + + .include "apple2.inc" + + ; Returns 1 if running on IIgs, 0 otherwise +_detect_iigs: + lda ostype + bpl :+ + jmp return1 +: jmp return0 diff --git a/libsrc/apple2/get_iigs_speed.s b/libsrc/apple2/get_iigs_speed.s new file mode 100644 index 000000000..1915d7773 --- /dev/null +++ b/libsrc/apple2/get_iigs_speed.s @@ -0,0 +1,22 @@ +; +; Colin Leroy-Mira , 2024 +; +; unsigned char __fastcall__ get_iigs_speed(void) +; + + .export _get_iigs_speed + .import ostype, return0 + + .include "apple2.inc" + .include "accelerator.inc" + +_get_iigs_speed: + lda ostype ; Return SLOW if not IIgs + bpl :+ + lda CYAREG ; Check current setting + bpl :+ + lda #SPEED_FAST + ldx #$00 + rts + .assert SPEED_SLOW = 0, error +: jmp return0 ; SPEED_SLOW diff --git a/libsrc/apple2/get_ostype.s b/libsrc/apple2/get_ostype.s index a1b1eb5be..ea9ff25cc 100644 --- a/libsrc/apple2/get_ostype.s +++ b/libsrc/apple2/get_ostype.s @@ -5,7 +5,7 @@ ; .constructor initostype, 9 - .export _get_ostype + .export _get_ostype, ostype ; Identify machine according to: ; Apple II Miscellaneous TechNote #7, Apple II Family Identification diff --git a/libsrc/apple2/set_iigs_speed.s b/libsrc/apple2/set_iigs_speed.s new file mode 100644 index 000000000..5e2f2f722 --- /dev/null +++ b/libsrc/apple2/set_iigs_speed.s @@ -0,0 +1,29 @@ +; +; Colin Leroy-Mira , 2024 +; +; unsigned char __fastcall__ detect_iigs(unsigned char speed) +; + + .export _set_iigs_speed + .import ostype, return0 + + .include "apple2.inc" + .include "accelerator.inc" + +_set_iigs_speed: + tax ; Keep parameter + lda ostype ; Return if not IIgs + bmi :+ + jmp return0 + +: lda CYAREG + cpx #SPEED_SLOW + beq :+ + ora #%10000000 + bne set_speed +: and #%01111111 +set_speed: + sta CYAREG + txa + ldx #$00 + rts diff --git a/libsrc/apple2/sleep.s b/libsrc/apple2/sleep.s new file mode 100644 index 000000000..43873d9f4 --- /dev/null +++ b/libsrc/apple2/sleep.s @@ -0,0 +1,54 @@ +; +; Colin Leroy-Mira , 2024 +; +; void __fastcall__ sleep(unsigned s) +; +; + + .export _sleep + .import _get_iigs_speed + .import _set_iigs_speed + .import WAIT + .importzp tmp1 + + .include "accelerator.inc" + + ; This functions uses the Apple2 WAIT ROM routine to waste a certain + ; amount of cycles and returns approximately after the numbers of + ; seconds passed in AX. + ; + ; It takes 1023730 cycles when called with AX=1 (1,0007s), + ; 10236364 cycles when called with AX=10 (10,006 seconds), + ; 306064298 cycles with AX=300 (299.2 seconds). + ; + ; Caveat: IRQs firing during calls to sleep will make the sleep longer + ; by the amount of cycles it takes to handle the IRQ. + ; +_sleep: + stx tmp1 ; High byte of s in X + tay ; Low byte in A + ora tmp1 + bne :+ + rts +: jsr _get_iigs_speed ; Save current CPU speed + pha + lda #SPEED_SLOW ; Down to 1MHz for consistency around WAIT + jsr _set_iigs_speed +sleep_1s: + ldx #$0A ; Loop 10 times +sleep_100ms: + lda #$C7 ; Sleep about 99ms + jsr WAIT + lda #$0D ; About 1ms + jsr WAIT + dex + bne sleep_100ms + dey + bne sleep_1s + dec tmp1 + bmi done + dey ; Down to #$FF + bne sleep_1s +done: + pla ; Restore CPU speed + jmp _set_iigs_speed diff --git a/libsrc/apple2/wait.s b/libsrc/apple2/wait.s new file mode 100644 index 000000000..3b569215b --- /dev/null +++ b/libsrc/apple2/wait.s @@ -0,0 +1,20 @@ +; +; Colin Leroy-Mira, 2024 +; +; WAIT routine +; + + .export WAIT + + .include "apple2.inc" + + .segment "LOWCODE" + +WAIT: + ; Switch in ROM and call WAIT + bit $C082 + jsr $FCA8 ; Vector to WAIT routine + + ; Switch in LC bank 2 for R/O and return + bit $C080 + rts diff --git a/libsrc/apple2/waitvsync.s b/libsrc/apple2/waitvsync.s index a4ab5ebb3..1697622de 100644 --- a/libsrc/apple2/waitvsync.s +++ b/libsrc/apple2/waitvsync.s @@ -5,21 +5,11 @@ ; .ifdef __APPLE2ENH__ - .constructor initvsync .export _waitvsync - .import _get_ostype + .import ostype .include "apple2.inc" - .segment "ONCE" - -initvsync: - jsr _get_ostype - sta ostype - rts - - .code - _waitvsync: bit ostype bmi iigs ; $8x @@ -53,8 +43,4 @@ iic: sei cli rts - .segment "INIT" - -ostype: .res 1 - .endif ; __APPLE2ENH__ From d906748691d31dc8ec1dfd95d1314bec11a149a1 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Thu, 18 Jan 2024 17:37:09 +0100 Subject: [PATCH 108/707] Fix uploader implementation to reset IRQ bit for timer 4 (serial) interrupt --- libsrc/lynx/uploader.s | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libsrc/lynx/uploader.s b/libsrc/lynx/uploader.s index f16a1721a..df3e5df40 100644 --- a/libsrc/lynx/uploader.s +++ b/libsrc/lynx/uploader.s @@ -33,7 +33,7 @@ loop1: cont1: jsr read_byte sta (load_ptr2),y - sta PALETTE ; feedback ;-) + sta PALETTE + 1 ; feedback ;-) iny bne loop1 inc load_ptr2+1 @@ -69,6 +69,8 @@ again: ; last action : clear interrupt ; exit: + lda #$10 + sta INTRST clc rts From 93f9cb6e489e248a2f92c0b103d330b9e78ee220 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Thu, 18 Jan 2024 18:06:10 +0100 Subject: [PATCH 109/707] Adjusted uploader configuration. Split into two MEMORY areas, so it can be just below video memory. --- cfg/lynx-uploader.cfg | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/cfg/lynx-uploader.cfg b/cfg/lynx-uploader.cfg index 476b3c5de..ea217626c 100644 --- a/cfg/lynx-uploader.cfg +++ b/cfg/lynx-uploader.cfg @@ -5,16 +5,17 @@ SYMBOLS { __BANK1BLOCKSIZE__: type = weak, value = $0000; # bank 1 block size __EXEHDR__: type = import; __BOOTLDR__: type = import; - __DEFDIR__: type = import; __UPLOADER__: type = import; + __UPLOADERSIZE__: type = export, value = $61; + __HEADERSIZE__: type = export, value = 64; } MEMORY { ZP: file = "", define = yes, start = $0000, size = $0100; - HEADER: file = %O, start = $0000, size = $0040; + HEADER: file = %O, start = $0000, size = __HEADERSIZE__; BOOT: file = %O, start = $0200, size = __STARTOFDIRECTORY__; - DIR: file = %O, start = $0000, size = 8; - MAIN: file = %O, define = yes, start = $0200, size = $BD38 - __STACKSIZE__; - UPLDR: file = %O, define = yes, start = $BFDC, size = $005C; + DIR: file = %O, start = $0000, size = 16; + MAIN: file = %O, define = yes, start = $0200, size = $C038 - __UPLOADERSIZE__ - $200 - __STACKSIZE__; + UPLOAD: file = %O, define = yes, start = $C038 - __UPLOADERSIZE__, size = $0061; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -30,8 +31,8 @@ SEGMENTS { RODATA: load = MAIN, type = ro, define = yes; DATA: load = MAIN, type = rw, define = yes; BSS: load = MAIN, type = bss, define = yes; - UPCODE: load = UPLDR, type = ro, define = yes; - UPDATA: load = UPLDR, type = rw, define = yes; + UPCODE: load = UPLOAD, type = ro, define = yes; + UPDATA: load = UPLOAD, type = rw, define = yes; } FEATURES { CONDES: type = constructor, From acce24fedcfa4d37dc5a28bf18129b68cb2194f9 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Thu, 18 Jan 2024 18:13:02 +0100 Subject: [PATCH 110/707] Switched to __BANK0BLOCKSIZE__ instead of __BLOCKSIZE__ to make current lynx config files work --- libsrc/lynx/lynx-cart.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/lynx/lynx-cart.s b/libsrc/lynx/lynx-cart.s index 94edff677..f9417aed3 100644 --- a/libsrc/lynx/lynx-cart.s +++ b/libsrc/lynx/lynx-cart.s @@ -88,7 +88,7 @@ lynxblock: lda __iodat sta IODAT stz _FileBlockByte - lda #<($100-(>__BLOCKSIZE__)) + lda #<($100-(>__BANK0BLOCKSIZE__)) sta _FileBlockByte+1 ply plx From 2e56dcc52196a8fdd65416adcc46c7e834db4615 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Thu, 18 Jan 2024 18:13:39 +0100 Subject: [PATCH 111/707] Fix for mising import --- libsrc/lynx/lynx-cart.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/lynx/lynx-cart.s b/libsrc/lynx/lynx-cart.s index f9417aed3..d1f3e33eb 100644 --- a/libsrc/lynx/lynx-cart.s +++ b/libsrc/lynx/lynx-cart.s @@ -17,7 +17,7 @@ .include "extzp.inc" .export lynxskip0, lynxread0 .export lynxblock - .import __BLOCKSIZE__ + .import __BANK0BLOCKSIZE__ .code From ad90a3a421776d9c13756de5e5cdb53fa7b5a469 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Thu, 18 Jan 2024 18:57:57 +0000 Subject: [PATCH 112/707] Replaced references to __BLOCKSIZE__ with __BANK0BLOCKSIZE__ --- libsrc/lynx/lseek.s | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libsrc/lynx/lseek.s b/libsrc/lynx/lseek.s index 4b4f94d7c..04d816945 100644 --- a/libsrc/lynx/lseek.s +++ b/libsrc/lynx/lseek.s @@ -18,7 +18,7 @@ .import ldeaxysp, decsp2, pushax, incsp8 .import tosandeax,decax1,tosdiveax,axlong,ldaxysp .import lynxskip0, lynxblock,tosasreax - .import __BLOCKSIZE__ + .import __BANK0BLOCKSIZE__ .importzp _FileCurrBlock .segment "CODE" @@ -32,15 +32,15 @@ jsr ldeaxysp jsr pusheax ldx #$00 - lda #<(__BLOCKSIZE__/1024 + 9) + lda #<(__BANK0BLOCKSIZE__/1024 + 9) jsr tosasreax sta _FileCurrBlock jsr lynxblock ldy #$05 jsr ldeaxysp jsr pusheax - lda #<(__BLOCKSIZE__-1) - ldx #>(__BLOCKSIZE__-1) + lda #<(__BANK0BLOCKSIZE__-1) + ldx #>(__BANK0BLOCKSIZE__-1) jsr axlong jsr tosandeax eor #$FF From 83691f30c1442aacb769d9eb3841802d2817beb8 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Fri, 19 Jan 2024 10:52:42 +0000 Subject: [PATCH 113/707] Missed a tab in config --- cfg/lynx-uploader.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/lynx-uploader.cfg b/cfg/lynx-uploader.cfg index ea217626c..62269de90 100644 --- a/cfg/lynx-uploader.cfg +++ b/cfg/lynx-uploader.cfg @@ -15,7 +15,7 @@ MEMORY { BOOT: file = %O, start = $0200, size = __STARTOFDIRECTORY__; DIR: file = %O, start = $0000, size = 16; MAIN: file = %O, define = yes, start = $0200, size = $C038 - __UPLOADERSIZE__ - $200 - __STACKSIZE__; - UPLOAD: file = %O, define = yes, start = $C038 - __UPLOADERSIZE__, size = $0061; + UPLOAD: file = %O, define = yes, start = $C038 - __UPLOADERSIZE__, size = $0061; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; From b23a7ec40746d68c90582dc4ec78ea822dd5d1b6 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Fri, 19 Jan 2024 21:14:47 +0100 Subject: [PATCH 114/707] Save two bytes in pushax and popptr1 It's not because Y must equal zero on rts that we should'nt spare one byte and one cycle. --- libsrc/runtime/popptr1.s | 8 +++++++- libsrc/runtime/pushax.s | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index 1d04330ab..b54bb9eb3 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -8,12 +8,18 @@ .import incsp2 .importzp sp, ptr1 + .macpack cpu + .proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) ldy #1 lda (sp),y ; get hi byte sta ptr1+1 ; into ptr hi - dey ; no optimization for 65C02 here to have Y=0 at exit! + dey ; dey even for for 65C02 here to have Y=0 at exit! +.if (.cpu .bitand ::CPU_ISET_65SC02) + lda (sp) ; get lo byte +.else lda (sp),y ; get lo byte +.endif sta ptr1 ; to ptr lo jmp incsp2 .endproc diff --git a/libsrc/runtime/pushax.s b/libsrc/runtime/pushax.s index ac181b994..27ddf641d 100644 --- a/libsrc/runtime/pushax.s +++ b/libsrc/runtime/pushax.s @@ -7,6 +7,8 @@ .export push0, pusha0, pushax .importzp sp + .macpack cpu + push0: lda #0 pusha0: ldx #0 @@ -29,7 +31,11 @@ pusha0: ldx #0 sta (sp),y ; (27) pla ; (31) dey ; (33) +.if (.cpu .bitand ::CPU_ISET_65SC02) + sta (sp) ; (37) +.else sta (sp),y ; (38) - rts ; (44) +.endif + rts ; (44/43) .endproc From 01ee903cdfadf418e84c9e2243b652d64b9ca06f Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Wed, 10 Jan 2024 22:43:49 +0100 Subject: [PATCH 115/707] Fixup gmtime/localtime/mktime tests with all cases --- test/val/lib_common_gmtime_localtime.c | 151 ++++++++++++++----------- test/val/lib_common_mktime.c | 6 + 2 files changed, 90 insertions(+), 67 deletions(-) diff --git a/test/val/lib_common_gmtime_localtime.c b/test/val/lib_common_gmtime_localtime.c index 9ba4d6a0d..f0d9a8332 100644 --- a/test/val/lib_common_gmtime_localtime.c +++ b/test/val/lib_common_gmtime_localtime.c @@ -4,90 +4,107 @@ int fails = 0; -time_t timestamps[] = { - 0, - 0x41eb00, - 0x1e7cb00, - 0x21c8700, - 0x2FFFFFFF, - 0x6FFFFFFF, - 0xF48656FF, - 0xF4865700, - 0xFC5A3EFF, - 0x6D6739FF, - 0x6D673A00, - 0xFFFFFFFF, -}; +typedef struct _test_data { + time_t t; + char *gmt; + char *local; +} test_data; -/* Values checked against glibc 2.37's implementation of ctime() */ -const char *dates_gmt[] = { - "Thu Jan 1 00:00:00 1970\n", - "Fri Feb 20 00:00:00 1970\n", - "Wed Jan 6 00:00:00 1971\n", - "Mon Feb 15 00:00:00 1971\n", - "Sun Jul 9 16:12:47 1995\n", - "Wed Jul 18 05:49:51 2029\n", - "Thu Dec 31 23:59:59 2099\n", - "Fri Jan 1 00:00:00 2100\n", - "Fri Feb 29 23:59:59 2104\n", - "Tue Feb 29 23:59:59 2028\n", - "Wed Mar 1 00:00:00 2028\n", - "Sun Feb 7 06:28:15 2106\n", - NULL -}; +/* Test data generated using glibc 2.37 */ +test_data data[] = { + /* First year */ + {0x00000000, "Thu Jan 1 00:00:00 1970\n", "Thu Jan 1 01:00:00 1970\n"}, + {0x004e7970, "Sun Mar 1 12:34:56 1970\n", "Sun Mar 1 13:34:56 1970\n"}, + {0x01e1337f, "Thu Dec 31 23:59:59 1970\n", "Fri Jan 1 00:59:59 1971\n"}, -const char *dates_gmt_plus_one[] = { - "Thu Jan 1 01:00:00 1970\n", - "Fri Feb 20 01:00:00 1970\n", - "Wed Jan 6 01:00:00 1971\n", - "Mon Feb 15 01:00:00 1971\n", - "Sun Jul 9 17:12:47 1995\n", - "Wed Jul 18 06:49:51 2029\n", - "Fri Jan 1 00:59:59 2100\n", - "Fri Jan 1 01:00:00 2100\n", - "Sat Mar 1 00:59:59 2104\n", - "Wed Mar 1 00:59:59 2028\n", - "Wed Mar 1 01:00:00 2028\n", - "Thu Jan 1 00:59:59 1970\n", - NULL + /* First leap year */ + {0x03c26700, "Sat Jan 1 00:00:00 1972\n", "Sat Jan 1 01:00:00 1972\n"}, + {0x03c8fe7f, "Wed Jan 5 23:59:59 1972\n", "Thu Jan 6 00:59:59 1972\n"}, + {0x041180ff, "Tue Feb 29 23:59:59 1972\n", "Wed Mar 1 00:59:59 1972\n"}, + {0x04118100, "Wed Mar 1 00:00:00 1972\n", "Wed Mar 1 01:00:00 1972\n"}, + {0x05a4ebff, "Sun Dec 31 23:59:59 1972\n", "Mon Jan 1 00:59:59 1973\n"}, + + /* A non-leap year */ + {0x63b0cd00, "Sun Jan 1 00:00:00 2023\n", "Sun Jan 1 01:00:00 2023\n"}, + {0x63fe957f, "Tue Feb 28 23:59:59 2023\n", "Wed Mar 1 00:59:59 2023\n"}, + {0x63fe9580, "Wed Mar 1 00:00:00 2023\n", "Wed Mar 1 01:00:00 2023\n"}, + {0x656d4ec0, "Mon Dec 4 04:00:00 2023\n", "Mon Dec 4 05:00:00 2023\n"}, + {0x6592007f, "Sun Dec 31 23:59:59 2023\n", "Mon Jan 1 00:59:59 2024\n"}, + + /* Another leap year */ + {0x65920080, "Mon Jan 1 00:00:00 2024\n", "Mon Jan 1 01:00:00 2024\n"}, + {0x65e11a7f, "Thu Feb 29 23:59:59 2024\n", "Fri Mar 1 00:59:59 2024\n"}, + {0x65e11a80, "Fri Mar 1 00:00:00 2024\n", "Fri Mar 1 01:00:00 2024\n"}, + {0x6774857f, "Tue Dec 31 23:59:59 2024\n", "Wed Jan 1 00:59:59 2025\n"}, + + /* End of century */ + {0xf48656ff, "Thu Dec 31 23:59:59 2099\n", "Fri Jan 1 00:59:59 2100\n"}, + + /* A non-leap year for exceptional reasons */ + {0xf4865700, "Fri Jan 1 00:00:00 2100\n", "Fri Jan 1 01:00:00 2100\n"}, + {0xf4d41f7f, "Sun Feb 28 23:59:59 2100\n", "Mon Mar 1 00:59:59 2100\n"}, + {0xf4d41f80, "Mon Mar 1 00:00:00 2100\n", "Mon Mar 1 01:00:00 2100\n"}, + {0xf4fceff0, "Wed Mar 31 23:00:00 2100\n", "Thu Apr 1 00:00:00 2100\n"}, + {0xf6678a7f, "Fri Dec 31 23:59:59 2100\n", "Sat Jan 1 00:59:59 2101\n"}, + + /* First post-2100 leap year */ + {0xfc0b2500, "Tue Jan 1 00:00:00 2104\n", "Tue Jan 1 01:00:00 2104\n"}, + {0xfc5a3eff, "Fri Feb 29 23:59:59 2104\n", "Sat Mar 1 00:59:59 2104\n"}, + {0xfc5a3f00, "Sat Mar 1 00:00:00 2104\n", "Sat Mar 1 01:00:00 2104\n"}, + {0xfcaa9c70, "Wed Apr 30 23:00:00 2104\n", "Thu May 1 00:00:00 2104\n"}, + + /* End of epoch */ + {0xfdedaa00, "Thu Jan 1 00:00:00 2105\n", "Thu Jan 1 01:00:00 2105\n"}, + {0xffffffff, "Sun Feb 7 06:28:15 2106\n", "Thu Jan 1 00:59:59 1970\n"} }; int main (void) { int i; + struct tm *tm; + char *str; - for (i = 0; dates_gmt[i] != NULL; i++) { - struct tm *tm; - char *str; + tm = gmtime(NULL); + if (tm != NULL) { + printf("gmtime should return NULL with a NULL parameter\n"); + fails++; + } - /* Check gmtime */ - tm = gmtime(×tamps[i]); + tm = localtime(NULL); + if (tm != NULL) { + printf("localtime should return NULL with a NULL parameter\n"); + fails++; + } + + /* Verify conversion both ways */ + for (i = 0; ; i++) { + time_t t = data[i].t; + + tm = gmtime(&t); str = asctime(tm); - if (strcmp(str, dates_gmt[i])) { + if (strcmp(data[i].gmt, str)) { + printf("0x%lx: gmtime: unexpected result: expected %s, got %s\n", t, data[i].gmt, str); fails++; - printf("gmtime: Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n", - timestamps[i], dates_gmt[i], str); } - - /* Check localtime with UTC timezone */ + _tz.timezone = 0; - tm = localtime(×tamps[i]); + tm = localtime(&t); str = asctime(tm); - if (strcmp(str, dates_gmt[i])) { + if (strcmp(data[i].gmt, str)) { + printf("0x%lx: localtime (UTC+0): unexpected result: expected %s, got %s\n", t, data[i].gmt, str); fails++; - printf("localtime: Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n", - timestamps[i], dates_gmt[i], str); } - // /* Check localtime at UTC+1 */ - // _tz.timezone = 3600; - // tm = localtime(×tamps[i]); - // str = asctime(tm); - // if (strcmp(str, dates_gmt_plus_one[i])) { - // fails++; - // printf("localtime: Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n", - // timestamps[i], dates_gmt_plus_one[i], str); - // } + _tz.timezone = 3600; + tm = localtime(&t); + str = asctime(tm); + if (strcmp(data[i].local, str)) { + printf("0x%lx: localtime (UTC+1): unexpected result: expected %s, got %s\n", t, data[i].local, str); + fails++; + } + + if (t == 0xFFFFFFFF) + break; } return fails; } diff --git a/test/val/lib_common_mktime.c b/test/val/lib_common_mktime.c index 5d42db874..6cabef2be 100644 --- a/test/val/lib_common_mktime.c +++ b/test/val/lib_common_mktime.c @@ -75,6 +75,11 @@ int main (void) { int i; + if (mktime(NULL) != (time_t)-1) { + printf("mktime should return -1 with a NULL parameter\n"); + fails++; + } + /* Verify conversion both ways */ for (i = 0; ; i++) { time_t t = data[i].t; @@ -91,6 +96,7 @@ int main (void) } if (strcmp(data[i].str, ctime(&t))) { printf("0x%lx: unexpected ctime result: expected %s, got %s", t, data[i].str, ctime(&t)); + fails++; } if (t == 0xFFFFFFFF) From ba75a2ac267fee6adc7a581612ca878efec44e38 Mon Sep 17 00:00:00 2001 From: acqn Date: Tue, 23 Jan 2024 14:33:05 +0800 Subject: [PATCH 116/707] Added missing checks for forward declarations of the main() function. More accurate diagnosis on implicit 'int' type specifiers. --- src/cc65/declare.c | 74 +++++++++++++----------- src/cc65/function.c | 31 +--------- test/ref/bug1889-missing-identifier.cref | 2 +- test/ref/inline-error.c | 2 + test/ref/inline-error.cref | 11 ++-- 5 files changed, 50 insertions(+), 70 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 29827d3aa..e1e66ab85 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2417,48 +2417,54 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode) /* Parse attributes for this declarator */ ParseAttribute (D); - /* 'inline' is only allowed on functions */ - if (Mode != DM_ACCEPT_PARAM_IDENT && - (D->StorageClass & SC_TYPEMASK) != SC_FUNC && - (D->StorageClass & SC_INLINE) == SC_INLINE) { - Error ("'inline' on non-function declaration"); - D->StorageClass &= ~SC_INLINE; - } - - /* Check a few pre-C99 things */ - if (D->Ident[0] != '\0' && (Spec->Flags & DS_TYPE_MASK) == DS_DEF_TYPE) { - /* Check and warn about an implicit int return in the function */ - if (IsTypeFunc (D->Type) && IsRankInt (GetFuncReturnType (D->Type))) { - /* Function has an implicit int return. Output a warning if we don't - ** have the C89 standard enabled explicitly. + /* Check a few things for the instance (rather than the type) */ + if (D->Ident[0] != '\0') { + /* Check a few pre-C99 things */ + if ((Spec->Flags & DS_TYPE_MASK) == DS_DEF_TYPE && IsRankInt (Spec->Type)) { + /* If the standard was not set explicitly to C89, print a warning + ** for typedefs with implicit int type specifier. */ if (IS_Get (&Standard) >= STD_C99) { - Warning ("Implicit 'int' return type is an obsolete feature"); + if ((D->StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { + Warning ("Implicit 'int' type specifier is an obsolete feature"); + } else { + Warning ("Type specifier defaults to 'int' in typedef of '%s'", + D->Ident); + Note ("Implicit 'int' type specifier is an obsolete feature"); + } } - GetFuncDesc (D->Type)->Flags |= FD_OLDSTYLE_INTRET; } - /* For anything that is not a function, check for an implicit int - ** declaration. - */ - if (!IsTypeFunc (D->Type) && IsRankInt (D->Type)) { - if ((D->StorageClass & SC_TYPEMASK) != SC_TYPEDEF) { - /* If the standard was not set explicitly to C89, print a warning - ** for variables with implicit int type. - */ - if (IS_Get (&Standard) >= STD_C99) { - Warning ("Implicit 'int' is an obsolete feature"); + /* Check other things depending on the "kind" of the instance */ + if ((D->StorageClass & SC_TYPEMASK) == SC_FUNC) { + /* Special handling for main() */ + if (strcmp (D->Ident, "main") == 0) { + /* main() cannot be a fastcall function */ + if (IsQualFastcall (D->Type)) { + Error ("'main' cannot be declared __fastcall__"); } - } else { - /* If the standard was not set explicitly to C89, print a warning - ** for typedefs with implicit int type. - */ - if (IS_Get (&Standard) >= STD_C99) { - Warning ("Type defaults to 'int' in typedef of '%s'", - D->Ident); - Note ("Implicit 'int' is an obsolete feature"); + + /* main() cannot be an inline function */ + if ((D->StorageClass & SC_INLINE) == SC_INLINE) { + Error ("'main' cannot be declared inline"); + D->StorageClass &= ~SC_INLINE; + } + + /* Check return type */ + if (GetUnqualRawTypeCode (GetFuncReturnType (D->Type)) != T_INT) { + /* If cc65 extensions aren't enabled, don't allow a main function + ** that doesn't return an int. + */ + if (IS_Get (&Standard) != STD_CC65) { + Error ("'main' must always return an int"); + } } } + } else if (Mode != DM_ACCEPT_PARAM_IDENT && + (D->StorageClass & SC_INLINE) == SC_INLINE) { + /* 'inline' is only allowed on functions */ + Error ("'inline' on non-function declaration"); + D->StorageClass &= ~SC_INLINE; } } diff --git a/src/cc65/function.c b/src/cc65/function.c index 596f9b617..a4b860251 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -450,7 +450,6 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* Parse argument declarations and function body. */ { int ParamComplete; /* If all paramemters have complete types */ - int C99MainFunc = 0;/* Flag for C99 main function returning int */ SymEntry* Param; const Type* RType; /* Real type used for struct parameters */ const Type* ReturnType; /* Return type */ @@ -513,34 +512,6 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* Mark this as the main function */ CurrentFunc->Flags |= FF_IS_MAIN; - /* Main cannot be a fastcall function */ - if (IsQualFastcall (Func->Type)) { - Error ("'main' cannot be declared as __fastcall__"); - } - - /* main() cannot be an inline function */ - if ((Func->Flags & SC_INLINE) == SC_INLINE) { - Error ("'main' cannot be declared inline"); - Func->Flags &= ~SC_INLINE; - } - - /* Check return type */ - if (GetUnqualRawTypeCode (ReturnType) == T_INT) { - /* Determine if this is a main function in a C99 environment that - ** returns an int. - */ - if (IS_Get (&Standard) >= STD_C99) { - C99MainFunc = 1; - } - } else { - /* If cc65 extensions aren't enabled, don't allow a main function - ** that doesn't return an int. - */ - if (IS_Get (&Standard) != STD_CC65) { - Error ("'main' must always return an int"); - } - } - /* Add a forced import of a symbol that is contained in the startup ** code. This will force the startup code to be linked in. */ @@ -665,7 +636,7 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* If this is the main function in a C99 environment returning an int, ** let it always return zero. Otherwise output a warning. */ - if (C99MainFunc) { + if (IS_Get (&Standard) >= STD_C99 && GetUnqualRawTypeCode (ReturnType) == T_INT) { g_getimmed (CF_INT | CF_CONST, 0, 0); } else if (IS_Get (&WarnReturnType)) { Warning ("Control reaches end of non-void function [-Wreturn-type]"); diff --git a/test/ref/bug1889-missing-identifier.cref b/test/ref/bug1889-missing-identifier.cref index e77c1a7a1..70c485fab 100644 --- a/test/ref/bug1889-missing-identifier.cref +++ b/test/ref/bug1889-missing-identifier.cref @@ -1,4 +1,4 @@ bug1889-missing-identifier.c:3: Error: Identifier or ';' expected after declaration specifiers -bug1889-missing-identifier.c:3: Warning: Implicit 'int' is an obsolete feature +bug1889-missing-identifier.c:3: Warning: Implicit 'int' type specifier is an obsolete feature bug1889-missing-identifier.c:4: Error: 'inline' on empty declaration bug1889-missing-identifier.c:6: Error: Expression expected diff --git a/test/ref/inline-error.c b/test/ref/inline-error.c index d8191025a..2dad41b6d 100644 --- a/test/ref/inline-error.c +++ b/test/ref/inline-error.c @@ -33,4 +33,6 @@ inline int main(void) /* Error */ f2b(); /* Still imported */ } +inline int main(void); /* Error */ + /* Warning: non-external inline functions declared but undefined in TU */ diff --git a/test/ref/inline-error.cref b/test/ref/inline-error.cref index abfdcdddd..4ce1d7073 100644 --- a/test/ref/inline-error.cref +++ b/test/ref/inline-error.cref @@ -13,8 +13,9 @@ inline-error.c:22: Error: 'inline' on non-function declaration inline-error.c:23: Error: 'inline' on non-function declaration inline-error.c:24: Error: 'inline' on non-function declaration inline-error.c:34: Warning: Variable 'fp2' is defined but never used -inline-error.c:37: Warning: Inline function 'f1a' used but never defined -inline-error.c:37: Warning: Inline function 'f1b' used but never defined -inline-error.c:37: Warning: Static function 'f1c' used but never defined -inline-error.c:37: Warning: Inline function 'f2a' used but never defined -inline-error.c:37: Warning: Inline function 'f2b' used but never defined +inline-error.c:36: Error: 'main' cannot be declared inline +inline-error.c:39: Warning: Inline function 'f1a' used but never defined +inline-error.c:39: Warning: Inline function 'f1b' used but never defined +inline-error.c:39: Warning: Static function 'f1c' used but never defined +inline-error.c:39: Warning: Inline function 'f2a' used but never defined +inline-error.c:39: Warning: Inline function 'f2b' used but never defined From 2ba176372e5b2643703e3c68e2f8e1cee54a4ec7 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Thu, 18 Jan 2024 13:55:18 +0100 Subject: [PATCH 117/707] Add beep for apple2 --- doc/apple2.sgml | 1 + doc/apple2enh.sgml | 1 + doc/funcref.sgml | 5 ++++- include/apple2.h | 3 +++ libsrc/apple2/beep.s | 20 ++++++++++++++++++++ libsrc/apple2/bell.s | 20 ++++++++++++++++++++ 6 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 libsrc/apple2/beep.s create mode 100644 libsrc/apple2/bell.s diff --git a/doc/apple2.sgml b/doc/apple2.sgml index fb49ea941..3a3ec3666 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -330,6 +330,7 @@ usage. _dos_type _filetype _datetime +beep get_ostype gmtime_dt mktime_dt diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 593b226ba..738e5b8af 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -331,6 +331,7 @@ usage. _dos_type _filetype _datetime +beep get_ostype gmtime_dt mktime_dt diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 740a6d62e..81c63a38b 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -95,6 +95,7 @@ function. _dos_type + @@ -106,6 +107,7 @@ function. _dos_type + @@ -1771,10 +1773,11 @@ used in presence of a prototype. / +/ -The function is specific to the Sym-1. +The function is specific to the Sym-1 and Apple2 platforms. Date: Tue, 23 Jan 2024 23:26:26 +0100 Subject: [PATCH 118/707] Add note about contacting the devs when starting to work on huge patches --- Contributing.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Contributing.md b/Contributing.md index 25c6217aa..1fde873f2 100644 --- a/Contributing.md +++ b/Contributing.md @@ -1,4 +1,6 @@ -This document contains all kinds of information that you should know if you want to contribute to the cc65 project. Before you start, please read all of it. If something is not clear to you, please ask - this document is an ongoing effort and may well be incomplete. +This document contains all kinds of information that you should know if you want to contribute to the cc65 project. Before you start, please read all of it. If something is not clear to you, please ask - this document is an ongoing effort and may well be incomplete. + +Also, before you put a lot of work into implementing something you want to contribute, please get in touch with one of the developers and ask if what you are going to do is actually wanted and has a chance of being merged. Perhaps someone else is already working on it, or perhaps what you have in mind is not how we'd expect it to be - talking to us before you start might save you a lot of work in those cases. (''Note:'' The word "must" indicates a requirement. The word "should" indicates a recomendation.) From 3e01ac9b04f2bf7da1b1be46cc502b8f0423b08d Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Mon, 15 Jan 2024 20:30:20 +0100 Subject: [PATCH 119/707] Fix malloc and realloc overflow If user requests a size >= 65532, adding the heap admin size overflows size. Fixes #2358. --- libsrc/common/malloc.s | 2 +- libsrc/common/realloc.c | 8 ++-- test/val/lib_common_malloc.c | 34 +++++++++++++++ test/val/lib_common_realloc.c | 81 +++++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 test/val/lib_common_malloc.c create mode 100644 test/val/lib_common_realloc.c diff --git a/libsrc/common/malloc.s b/libsrc/common/malloc.s index 6872f1f2e..72c4aedaa 100644 --- a/libsrc/common/malloc.s +++ b/libsrc/common/malloc.s @@ -131,6 +131,7 @@ _malloc: sta ptr1 bcc @L1 inc ptr1+1 + beq OutOfHeapSpace ; if high byte's 0, we overflowed! @L1: ldx ptr1+1 bne @L2 cmp #HEAP_MIN_BLOCKSIZE+1 @@ -336,4 +337,3 @@ RetUserPtr: bcc @L9 inx @L9: rts - diff --git a/libsrc/common/realloc.c b/libsrc/common/realloc.c index eeb1eeea5..b5429b3c2 100644 --- a/libsrc/common/realloc.c +++ b/libsrc/common/realloc.c @@ -59,6 +59,11 @@ void* __fastcall__ realloc (void* block, register size_t size) return 0; } + /* Don't overflow! */ + if (size > 0xFFFF - HEAP_ADMIN_SPACE) { + return 0; + } + /* Make the internal used size from the given size */ size += HEAP_ADMIN_SPACE; if (size < sizeof (struct freeblock)) { @@ -107,6 +112,3 @@ void* __fastcall__ realloc (void* block, register size_t size) } return newblock; } - - - diff --git a/test/val/lib_common_malloc.c b/test/val/lib_common_malloc.c new file mode 100644 index 000000000..5c68dc39a --- /dev/null +++ b/test/val/lib_common_malloc.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include "unittest.h" + +TEST +{ + char *buf, *buf2; + unsigned int i; + + buf = malloc(0); + ASSERT_IsTrue (buf == NULL, "malloc (0) returned something"); + + for (i = 1; i < 10; i++) { + buf = malloc(i); + ASSERT_IsTrue (buf != NULL, "small returned nothing"); + } + + buf = malloc(4096); + ASSERT_IsTrue (buf != NULL, "malloc (4096) returned nothing"); + + buf = malloc(61000UL); + ASSERT_IsTrue (buf == NULL, "malloc (61000) returned something"); + + for (i = 65535UL; i > _heapmaxavail(); i--) { + buf = malloc(i); + ASSERT_IsTrue (buf == NULL, "malloc returned something but shouldn't have"); + } + + buf = malloc(i); + ASSERT_IsTrue (buf != NULL, "malloc returned nothing but should have"); + ASSERT_IsTrue(_heapmaxavail() == 0, "heapmaxavail should be 0"); +} +ENDTEST diff --git a/test/val/lib_common_realloc.c b/test/val/lib_common_realloc.c new file mode 100644 index 000000000..d1e4fa3eb --- /dev/null +++ b/test/val/lib_common_realloc.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include "unittest.h" + +TEST +{ + char *buf, *buf2; + unsigned int i; + + buf = realloc(NULL, 0); + ASSERT_IsTrue (buf == NULL, "realloc (NULL, 0) returned something"); + + for (i = 1; i < 10; i++) { + buf2 = realloc(buf, i); + ASSERT_IsTrue (buf2 != NULL, "small realloc returned nothing"); + if (i > 1) { + ASSERT_IsTrue (buf2 == buf, "buf shouldn't have moved"); + } + buf = buf2; + } + + buf = realloc(NULL, 15); + ASSERT_IsTrue (buf != NULL, "realloc (NULL, 15) returned nothing"); + + buf = realloc(buf, 0); + ASSERT_IsTrue (buf == NULL, "realloc (buf, 0) returned something"); + + buf = realloc(buf, 32); + memset(buf, 'a', 32); + for (i = 0; i < 32; i++) { + ASSERT_IsTrue(buf[i] == 'a', "wrong contents in buf"); + } + + /* Now realloc larger, while there's nothing else in the heap */ + buf = realloc(buf, 64); + memset(buf+32, 'b', 32); + for (i = 0; i < 32; i++) { + ASSERT_IsTrue(buf[i] == 'a', "wrong contents in start of buf"); + } + for (i = 32; i < 64; i++) { + ASSERT_IsTrue(buf[i] == 'b', "wrong contents in end of buf"); + } + + /* Now realloc smaller, while there's nothing else in the heap */ + buf = realloc(buf, 40); + for (i = 0; i < 32; i++) { + ASSERT_IsTrue(buf[i] == 'a', "wrong contents in start of buf"); + } + for (i = 32; i < 40; i++) { + ASSERT_IsTrue(buf[i] == 'b', "wrong contents in end of buf"); + } + + /* Allocate something else, so next realloc has to change block */ + malloc(50); + + /* Now realloc larger, with something else in the heap */ + buf = realloc(buf, 128); + for (i = 0; i < 32; i++) { + ASSERT_IsTrue(buf[i] == 'a', "wrong contents in start of buf"); + } + for (i = 32; i < 40; i++) { + ASSERT_IsTrue(buf[i] == 'b', "wrong contents in end of buf"); + } + + for (i = 129; i < 8192; i++) { + buf = realloc(buf, i); + ASSERT_IsTrue(buf != NULL, "realloc failed"); + } + + malloc(4096); + + buf2 = realloc(buf, 58000UL); + ASSERT_IsTrue (buf2 == NULL, "realloc (buf, 58000) returned something"); + + for (i = 65535UL; i > 65527UL; i--) { + buf2 = realloc(buf, i); + ASSERT_IsTrue (buf2 == NULL, "realloc returned something but shouldn't have"); + } +} +ENDTEST From 5d49fde788ba7adcee87d5eb050fe8269fa6103a Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Thu, 11 Jan 2024 18:19:13 +0100 Subject: [PATCH 120/707] add a return -1 helper --- libsrc/atari/open.s | 6 ++---- libsrc/cbm/cbm_read.s | 7 ++----- libsrc/cbm/cbm_write.s | 7 ++----- libsrc/common/fclose.s | 8 ++------ libsrc/common/fmisc.s | 9 ++------- libsrc/common/putenv.s | 9 ++------- libsrc/common/ungetc.s | 6 +----- libsrc/runtime/returnFFFF.s | 15 +++++++++++++++ 8 files changed, 28 insertions(+), 39 deletions(-) create mode 100644 libsrc/runtime/returnFFFF.s diff --git a/libsrc/atari/open.s b/libsrc/atari/open.s index ed3e40b2f..e7e55c54c 100644 --- a/libsrc/atari/open.s +++ b/libsrc/atari/open.s @@ -19,7 +19,7 @@ .import findfreeiocb .import incsp4 .import ldaxysp,addysp - .import ___oserror + .import ___oserror, returnFFFF .ifdef UCASE_FILENAME .import ucase_fn .endif @@ -39,9 +39,7 @@ parmok: jsr findfreeiocb lda # Date: Thu, 11 Jan 2024 19:31:04 +0100 Subject: [PATCH 121/707] Rewrite fgets in asm -104 bytes, -1% cycles --- libsrc/apple2/statvfs.s | 6 +- libsrc/common/fgets.c | 68 ---------------------- libsrc/common/fgets.s | 119 ++++++++++++++++++++++++++++++++++++++ libsrc/runtime/pushptr1.s | 14 +++++ 4 files changed, 135 insertions(+), 72 deletions(-) delete mode 100644 libsrc/common/fgets.c create mode 100644 libsrc/common/fgets.s create mode 100644 libsrc/runtime/pushptr1.s diff --git a/libsrc/apple2/statvfs.s b/libsrc/apple2/statvfs.s index 6274bb52b..8fcf46af8 100644 --- a/libsrc/apple2/statvfs.s +++ b/libsrc/apple2/statvfs.s @@ -6,7 +6,7 @@ .export _statvfs .import _dio_query_sectsize - .import mli_file_info, pushax, popax, popptr1 + .import mli_file_info, pushax, popax, popptr1, pushptr1 .include "zeropage.inc" .include "apple2.inc" .include "errno.inc" @@ -45,9 +45,7 @@ _statvfs: sty vol_sep ; Register '/' index lda #$00 sta (ptr1),y ; Cut pathname at first slash -: lda ptr1 - ldx ptr1+1 - jsr pushax +: jsr pushptr1 jsr mli_file_info diff --git a/libsrc/common/fgets.c b/libsrc/common/fgets.c deleted file mode 100644 index 21a991fd6..000000000 --- a/libsrc/common/fgets.c +++ /dev/null @@ -1,68 +0,0 @@ -/* -** Ullrich von Bassewitz, 11.08.1998 -** -** char* fgets (char* s, int size, FILE* f); -*/ - - - -#include -#include -#include "_file.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -char* __fastcall__ fgets (char* s, unsigned size, register FILE* f) -{ - register char* p = s; - unsigned i; - int c; - - if (size == 0) { - /* Invalid size */ - return (char*) _seterrno (EINVAL); - } - - /* Read input */ - i = 0; - while (--size) { - - /* Get next character */ - if ((c = fgetc (f)) == EOF) { - /* Error or EOF */ - if ((f->f_flags & _FERROR) != 0 || i == 0) { - /* ERROR or EOF on first char */ - *p = '\0'; - return 0; - } else { - /* EOF with data already read */ - break; - } - } - - /* One char more */ - *p = c; - ++p; - ++i; - - /* Stop at end of line */ - if ((char)c == '\n') { - break; - } - } - - /* Terminate the string */ - *p = '\0'; - - /* Done */ - return s; -} - - - diff --git a/libsrc/common/fgets.s b/libsrc/common/fgets.s new file mode 100644 index 000000000..465658191 --- /dev/null +++ b/libsrc/common/fgets.s @@ -0,0 +1,119 @@ +; +; Colin Leroy-Mira, 2024 +; +; char* __fastcall__ fgets (char* s, unsigned size, register FILE* f) +; + + .export _fgets + .import _fgetc, popptr1, pushptr1, popax, pushax, return0, ___errno + .importzp ptr1, ptr4 + + .include "errno.inc" + .include "stdio.inc" + .include "_file.inc" + + .macpack cpu + +terminate_ptr: + lda #$00 + tax + .if (.cpu .bitand ::CPU_ISET_65SC02) + sta (ptr4) + .else + tay + sta (ptr4),y + .endif + rts + +_fgets: + sta ptr1 + stx ptr1+1 + + jsr popax + sta size + stx size+1 + + jsr popax + sta ptr4 + stx ptr4+1 + sta buf + stx buf+1 + + .if (.cpu .bitand ::CPU_ISET_65SC02) + stz didread + .else + lda #$00 ; We have read nothing yet + sta didread + .endif + + ; Check size + lda size + ora size+1 + bne read_loop + lda #EINVAL + sta ___errno + jmp return0 + +read_loop: + lda size ; Dec size + bne :+ + dec size+1 +: dec size + + bne :+ ; Check bound + ldx size+1 + beq done + +: jsr pushptr1 ; Push ptr1 for backup and load it to AX for fgetc + jsr _fgetc ; Read a char + + pha + jsr popptr1 ; Get ptr1 back + pla + + cpx #buf + lda # Date: Fri, 12 Jan 2024 23:04:14 +0100 Subject: [PATCH 122/707] Optimize -36 bytes out of posix_memalign And add a unit test --- libsrc/common/pmemalign.c | 22 ++++++++++++++-------- test/val/lib_common_pmemalign.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 test/val/lib_common_pmemalign.c diff --git a/libsrc/common/pmemalign.c b/libsrc/common/pmemalign.c index 52adb240d..4499084d1 100644 --- a/libsrc/common/pmemalign.c +++ b/libsrc/common/pmemalign.c @@ -50,7 +50,6 @@ */ - int __fastcall__ posix_memalign (void** memptr, size_t alignment, size_t size) /* Allocate a block of memory with the given "size", which is aligned to a ** memory address that is a multiple of "alignment". "alignment" MUST NOT be @@ -64,20 +63,27 @@ int __fastcall__ posix_memalign (void** memptr, size_t alignment, size_t size) size_t rawsize; size_t uppersize; size_t lowersize; + char err; register struct usedblock* b; /* points to raw Block */ register struct usedblock* u; /* points to User block */ register struct usedblock* p; /* Points to upper block */ /* Handle requests for zero-sized blocks */ if (size == 0) { +err_einval: + err = EINVAL; +err_out: *memptr = NULL; - return EINVAL; + return err; } - /* Test alignment: is it a power of two? There must be only one bit set. */ - if (alignment == 0 || (alignment & (alignment - 1)) != 0) { - *memptr = NULL; - return EINVAL; + /* Test alignment: is it a power of two? There must be one and only one bit set. */ + if (alignment == 0) { + goto err_einval; + } + + if (alignment & (alignment - 1)) { + goto err_einval; } /* Augment the block size up to the alignment, and allocate memory. @@ -90,8 +96,8 @@ int __fastcall__ posix_memalign (void** memptr, size_t alignment, size_t size) /* Handle out-of-memory */ if (b == NULL) { - *memptr = NULL; - return ENOMEM; + err = ENOMEM; + goto err_out; } /* Create (and return) a new pointer that points to the user-visible diff --git a/test/val/lib_common_pmemalign.c b/test/val/lib_common_pmemalign.c new file mode 100644 index 000000000..0e9e5f52f --- /dev/null +++ b/test/val/lib_common_pmemalign.c @@ -0,0 +1,31 @@ +#include +#include +#include "unittest.h" + +TEST +{ + void *buf; + int r; + + r = posix_memalign(&buf, 123, 1024); + ASSERT_IsTrue(r == EINVAL, "posix_memalign did not return EINVAL with wrong alignment"); + ASSERT_IsTrue(buf == NULL, "posix_memalign did not set buf to NULL with wrong alignment"); + + r = posix_memalign(&buf, 0, 1024); + ASSERT_IsTrue(r == EINVAL, "posix_memalign did not return EINVAL with 0 alignment"); + ASSERT_IsTrue(buf == NULL, "posix_memalign did not set buf to NULL with 0 alignment"); + + r = posix_memalign(&buf, 256, 0); + ASSERT_IsTrue(r == EINVAL, "posix_memalign did not return EINVAL with 0 size"); + ASSERT_IsTrue(buf == NULL, "posix_memalign did not set buf to NULL with 0 size"); + + r = posix_memalign(&buf, 256, 32768U); + ASSERT_IsTrue(r == 0, "posix_memalign did not return 0 on correct call"); + ASSERT_IsTrue(buf != NULL, "posix_memalign left buf set to NULL on correct call"); + ASSERT_IsTrue(((unsigned int)buf & 0x00FF) == 0x00, "posix_memalign did not align memory"); + + r = posix_memalign(&buf, 256, 32768U); + ASSERT_IsTrue(r == ENOMEM, "posix_memalign did not return ENOMEM when no memory is available"); + ASSERT_IsTrue(buf == NULL, "posix_memalign did not set buf to NULL when no memory is available"); +} +ENDTEST From f0b5b0296678dde02aa2c46096a7dee59cc4b9f4 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sun, 21 Jan 2024 16:50:59 +0100 Subject: [PATCH 123/707] Swap in LC before destructors, ROM after --- doc/apple2.sgml | 2 +- doc/apple2enh.sgml | 2 +- libsrc/apple2/crt0.s | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 3a3ec3666..e6ec870ee 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -62,7 +62,7 @@ Special locations:

While running

While running exit jsr reset ; Setup RESET vector - ; Switch in ROM, in case it wasn't already switched in by a RESET. - bit $C082 + ; Switch in LC bank 2 for R/O in case it was switched out by a RESET. + bit $C080 ; Call the module destructors. jsr donelib + ; Switch in ROM. + bit $C082 + ; Restore the original RESET vector. exit: ldx #$02 : lda rvsave,x From 34f37c873ebe25e5973f0043b0a99a9867589cd9 Mon Sep 17 00:00:00 2001 From: Stefan Date: Wed, 24 Jan 2024 16:32:45 +0100 Subject: [PATCH 124/707] Fixed comment --- libsrc/geos-common/graph/bitotherclip.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/geos-common/graph/bitotherclip.s b/libsrc/geos-common/graph/bitotherclip.s index 020139da8..fba00d966 100644 --- a/libsrc/geos-common/graph/bitotherclip.s +++ b/libsrc/geos-common/graph/bitotherclip.s @@ -6,7 +6,7 @@ ; void BitOtherClip (void *proc1, void* proc2, char skipl, char skipr, int skipy, ; struct iconpic *myGfx); -; both proc1, proc2 should be: char __fastcall something (void); +; both proc1, proc2 should be: char foo (void); ; proc1 is called before reading a byte (.A returns next data) ; proc2 is called before reading each byte which is not pattern (code >219) From f7388cfb79def6c7fc9c737120553fea7b76b9e0 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Thu, 11 Jan 2024 18:30:13 +0100 Subject: [PATCH 125/707] add fgets/fgetc test --- include/stdio.h | 4 +++ test/ref/test_fgets.c | 60 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 test/ref/test_fgets.c diff --git a/include/stdio.h b/include/stdio.h index 012b8e2ba..35ebd7784 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -86,6 +86,10 @@ extern FILE* stderr; # define FILENAME_MAX (80+1) #elif defined(__TELESTRAT__) # define FILENAME_MAX (50+1) +#elif defined(__SIM6502__) +# define FILENAME_MAX (1024+1) +#elif defined(__SIM65C02__) +# define FILENAME_MAX (1024+1) #else # define FILENAME_MAX (16+1) #endif diff --git a/test/ref/test_fgets.c b/test/ref/test_fgets.c new file mode 100644 index 000000000..70d30a066 --- /dev/null +++ b/test/ref/test_fgets.c @@ -0,0 +1,60 @@ +/* + !!DESCRIPTION!! fgets test + !!LICENCE!! Public domain +*/ + +#include "common.h" + +#include +#include +#include +#include +#include + +FILE *in, *out; +char buf[32]; + +#define INFILE "cf.in" + +int main(int argc,char **argv) +{ + static char outfile_path[FILENAME_MAX+1]; + + sprintf(outfile_path, "%s.test.out", argv[0]); + + out = fopen(outfile_path, "wb"); + if (out == NULL) { + return EXIT_FAILURE; + } + if (fgets(buf, sizeof(buf), out) != NULL) { + printf("Error, could fgets with write-only file\n"); + return 1; + } + if (!ferror(out)) { + printf("Error: file pointer should be in error state\n"); + } + fclose(out); + + in = fopen(INFILE, "rb"); + if (in == NULL) { + return EXIT_FAILURE; + } + + if (fgets(NULL, 0, in) != NULL) { + printf("Error, could fgets with zero size\n"); + return 1; + } + + while (fgets(buf, sizeof(buf), in) != NULL) + { + printf("%s",buf); + } + + if (!feof(in)) + { + printf("We should have EOF!\n"); + } + + fclose(in); + return 0; +} From 476591e8b7f28bd5145c4e81750a969ce83b97ff Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Thu, 11 Jan 2024 18:54:42 +0100 Subject: [PATCH 126/707] Rewrite fgetc in asm -82 bytes, -20% cycles --- libsrc/common/fgetc.c | 58 --------------------------- libsrc/common/fgetc.s | 92 +++++++++++++++++++++++++++++++++++++++++++ test/ref/test_fgets.c | 5 +++ 3 files changed, 97 insertions(+), 58 deletions(-) delete mode 100644 libsrc/common/fgetc.c create mode 100644 libsrc/common/fgetc.s diff --git a/libsrc/common/fgetc.c b/libsrc/common/fgetc.c deleted file mode 100644 index b4ba18d73..000000000 --- a/libsrc/common/fgetc.c +++ /dev/null @@ -1,58 +0,0 @@ -/* -** fgetc.c -** -** (C) Copyright 1998, 2002 Ullrich von Bassewitz (uz@cc65.org) -** -*/ - - - -#include -#include -#include "_file.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -int __fastcall__ fgetc (register FILE* f) -{ - unsigned char c; - - /* Check if the file is open or if there is an error condition */ - if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) { - return EOF; - } - - /* If we have a pushed back character, return it */ - if (f->f_flags & _FPUSHBACK) { - f->f_flags &= ~_FPUSHBACK; - return f->f_pushback; - } - - /* Read one byte */ - switch (read (f->f_fd, &c, 1)) { - - case -1: - /* Error */ - f->f_flags |= _FERROR; - return EOF; - - case 0: - /* EOF */ - f->f_flags |= _FEOF; - return EOF; - - default: - /* Char read */ - return c; - - } -} - - - diff --git a/libsrc/common/fgetc.s b/libsrc/common/fgetc.s new file mode 100644 index 000000000..777696b7a --- /dev/null +++ b/libsrc/common/fgetc.s @@ -0,0 +1,92 @@ +; +; Colin Leroy-Mira, 2024 +; +; int __fastcall__ fgetc (register FILE* f) +; + + .export _fgetc + .import _read, pusha0, pushax, popptr1, incsp2, returnFFFF + .importzp ptr1 + + .include "stdio.inc" + .include "_file.inc" + +_fgetc: + sta ptr1 + stx ptr1+1 + jsr pushax ; Backup our ptr + + ldy #_FILE::f_flags + lda (ptr1),y + tax + and #_FOPEN ; Check for file open + beq ret_eof + txa + and #(_FERROR|_FEOF); Check for error/eof + bne ret_eof + + txa + and #_FPUSHBACK ; Check for pushed back char + beq do_read + + txa + and #<(~_FPUSHBACK) ; Reset flag + sta (ptr1),y + + .assert _FILE::f_pushback = _FILE::f_flags+1, error + iny + jsr incsp2 ; Drop our ptr copy + lda (ptr1),y ; Return pushed back char + ldx #$00 + rts + +do_read: + ; Push _read parameters + ldy #_FILE::f_fd + lda (ptr1),y + jsr pusha0 + + lda #c + jsr pushax + + lda #$01 + ldx #$00 + + ; Read + jsr _read + + ; Check for errors + cmp #$00 + beq set_feof + + cmp #<(-1) + beq set_ferror + + jsr incsp2 + ; Return char + ldx #$00 + lda c + rts + +ret_eof: + jsr incsp2 + jmp returnFFFF + +set_ferror: + lda #_FERROR + bne set_err +set_feof: + lda #_FEOF +set_err: + pha + jsr popptr1 + pla + ldy #_FILE::f_flags + ora (ptr1),y + sta (ptr1),y + jmp returnFFFF + + .bss + +c: .res 1 diff --git a/test/ref/test_fgets.c b/test/ref/test_fgets.c index 70d30a066..72ea308dd 100644 --- a/test/ref/test_fgets.c +++ b/test/ref/test_fgets.c @@ -45,6 +45,11 @@ int main(int argc,char **argv) return 1; } + /* Test ungetc while we're at it */ + buf[0] = fgetc(in); + ungetc(buf[0], in); + + while (fgets(buf, sizeof(buf), in) != NULL) { printf("%s",buf); From f1d95f1f07accf0e7912fd862738e4cd66794913 Mon Sep 17 00:00:00 2001 From: Stefan Date: Thu, 25 Jan 2024 11:27:54 +0100 Subject: [PATCH 127/707] Added link for your interest --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 11c3bb0ff..dce9a07bc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ For details look at the [Website](https://cc65.github.io). Project founders: -* John R. Dunning: original implementation of the C compiler and runtime library, Atari hosted +* John R. Dunning: [original implementation](https://public.websites.umich.edu/~archive/atari/8bit/Languages/Cc65/) of the C compiler and runtime library, Atari hosted * Ullrich von Bassewitz: * move the code to modern systems * rewrite most parts of the compiler From a8b870555e4dd371a718f0de506510b0ee202eff Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Mon, 22 Jan 2024 12:57:59 +0100 Subject: [PATCH 128/707] Rewrite realloc in asm -80 bytes, -39% cycles --- libsrc/common/realloc.c | 114 --------------------- libsrc/common/realloc.s | 213 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 114 deletions(-) delete mode 100644 libsrc/common/realloc.c create mode 100644 libsrc/common/realloc.s diff --git a/libsrc/common/realloc.c b/libsrc/common/realloc.c deleted file mode 100644 index b5429b3c2..000000000 --- a/libsrc/common/realloc.c +++ /dev/null @@ -1,114 +0,0 @@ -/*****************************************************************************/ -/* */ -/* realloc.c */ -/* */ -/* Change the size of an allocated memory block */ -/* */ -/* */ -/* */ -/* (C) 1998-2004 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include -#include <_heap.h> - - - -void* __fastcall__ realloc (void* block, register size_t size) -{ - register struct usedblock* b; - struct usedblock* newblock; - unsigned oldsize; - unsigned newhptr; - - /* Check the block parameter */ - if (!block) { - /* Block is NULL, same as malloc */ - return malloc (size); - } - - /* Check the size parameter */ - if (size == 0) { - /* Block is not NULL, but size is: free the block */ - free (block); - return 0; - } - - /* Don't overflow! */ - if (size > 0xFFFF - HEAP_ADMIN_SPACE) { - return 0; - } - - /* Make the internal used size from the given size */ - size += HEAP_ADMIN_SPACE; - if (size < sizeof (struct freeblock)) { - size = sizeof (struct freeblock); - } - - /* The word below the user block contains a pointer to the start of the - ** raw memory block. The first word of this raw memory block is the full - ** size of the block. Get a pointer to the real block, get the old block - ** size. - */ - b = (((struct usedblock*) block) - 1)->start; - oldsize = b->size; - - /* Is the block at the current heap top? */ - if (((unsigned) b) + oldsize == ((unsigned) __heapptr)) { - /* Check if we've enough memory at the heap top */ - newhptr = ((unsigned) __heapptr) - oldsize + size; - if (newhptr <= ((unsigned) __heapend)) { - /* Ok, there's space enough */ - __heapptr = (unsigned*) newhptr; - b->size = size; - b->start = b; - return block; - } - } - - /* The given block was not located on top of the heap, or there's no - ** room left. Try to allocate a new block and copy the data. - */ - if (newblock = malloc (size)) { - - /* Adjust the old size to the user visible portion */ - oldsize -= HEAP_ADMIN_SPACE; - - /* If the new block is larger than the old one, copy the old - ** data only - */ - if (size > oldsize) { - size = oldsize; - } - - /* Copy the block data */ - memcpy (newblock, block, size); - free (block); - } - return newblock; -} diff --git a/libsrc/common/realloc.s b/libsrc/common/realloc.s new file mode 100644 index 000000000..925ac3d19 --- /dev/null +++ b/libsrc/common/realloc.s @@ -0,0 +1,213 @@ +; +; Colin Leroy-Mira, 2024 +; +; void* __fastcall__ realloc (void* block, register size_t size) +; + + .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4, sp + .import _malloc, _memcpy, _free + .import pushax, popptr1, return0 + .import incsp2, decsp2 + .export _realloc + + .include "_heap.inc" + + .macpack generic + +;---------------------------------------------------------------------------- +; Aliases for clarity + +block = ptr1 +size = ptr2 +ublock = ptr3 +oldsize = ptr4 +newblock = tmp1 ; (and tmp2) +orgblock = tmp3 ; (and tmp4) + +;---------------------------------------------------------------------------- +; Code + +_realloc: + sta size ; Store size + stx size+1 + + jsr popptr1 ; Pop block + + lda block+1 ; Is block null? + tax + ora block + bne :+ + + lda size ; Block is null, just malloc + ldx size+1 + jmp _malloc + +: lda size ; Is size 0? + ora size+1 + bne :+ + + lda block ; It is: free block (high byte already in X) + jsr _free + jmp return0 + +: clc ; Add internal used size + lda size + adc #HEAP_ADMIN_SPACE + sta size + bcc :+ + inc size+1 + bne :+ + + lda #$00 ; Size high byte now 0: We overflowed! + tax + rts + +: ldx size+1 ; Should we round size up? + bne :+ + cmp #.sizeof (freeblock) + bcs :+ + + lda #.sizeof (freeblock) + sta size ; (we presuppose that sizeof (freeblock) is < 256) + +: lda block ; Get pointer to raw memory block + sta orgblock ; Store original pointer + sec + sbc #.sizeof(usedblock) + sta ublock + lda block+1 + sta orgblock+1 ; Finish storing original pointer + sbc #0 + sta ublock+1 ; We have our usedblock struct + + ; Get block start + ldy #usedblock::start+1 + lda (ublock),y + tax ; Backup ublock high + dey + lda (ublock),y + + sta ublock ; Store ublock + stx ublock+1 + + ; Remember oldsize + ldy #usedblock::size+1 + lda (ublock),y + sta oldsize+1 + dey + lda (ublock),y + sta oldsize + + clc ; Is the block at heap top? + adc ublock + tay + lda ublock+1 + adc oldsize+1 + cmp ___heapptr+1 + bne must_malloc_new + cpy ___heapptr + bne must_malloc_new + + tya ; Put ___heapptr back in A + sec ; Check if we have enough memory at heap top + sbc oldsize ; Substract oldsize + sta newblock + lda ___heapptr+1 + sbc oldsize+1 + sta newblock+1 + clc + lda newblock ; And add size + adc size + sta newblock + lda newblock+1 + adc size+1 + sta newblock+1 + bcs must_malloc_new ; If we have a carry there we overflowed + + cmp ___heapend+1 + bne :+ + lda newblock + cmp ___heapend +: bcc :+ + bne must_malloc_new + +: lda newblock ; There is enough space + sta ___heapptr ; Update heapptr + lda newblock+1 + sta ___heapptr+1 + + ldy #usedblock::start+1 + lda ublock+1 + sta (ublock),y ; Update block start + dey + lda ublock + sta (ublock),y + dey + + .assert usedblock::size = usedblock::start-2, error + lda size+1 + sta (ublock),y ; Update block size + dey + lda size + sta (ublock),y + + lda orgblock ; Return original block + ldx orgblock+1 + rts + +must_malloc_new: ; The block is not at heap top, or too big + lda size+1 + pha ; Backup new size (at this point the only ptr + tax ; we'll need after malloc). tmp* are safe + lda size ; from malloc, memcpy and free. + pha + jsr _malloc + + cmp #$00 ; Did malloc succeed? + bne :+ + cpx #$00 + bne :+ + pla ; Pop size backup and return NULL + pla + txa ; X already 0 + rts ; No + +: sta newblock ; Yes, store newblock + stx newblock+1 + jsr pushax ; Push newblock for memcpy + + lda orgblock ; Push orgblock for memcpy + ldx orgblock+1 + jsr pushax + + sec ; Remove admin space from oldsize + lda oldsize + sbc #HEAP_ADMIN_SPACE + sta oldsize+1 + + pla ; Restore new size to AX + tay + pla + tax + tya + + cmp oldsize ; Find the smallest size + bcc :+ + cpx oldsize+1 + bcc :+ + + lda oldsize + ldx oldsize+1 + +: jsr _memcpy ; And copy data + + lda orgblock ; Free old block + ldx orgblock+1 + jsr _free + + lda newblock ; Return new block + ldx newblock+1 + rts From aa6f850b8d2308b99bc13776e6e7937aacb5d711 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Thu, 11 Jan 2024 19:51:17 +0100 Subject: [PATCH 129/707] Rewrite gets in assembler +19 bytes if used alone, because it pulls in fgets, but as code is factorized, -128 bytes in programs using both fgets and gets. --- libsrc/common/gets.c | 63 -------------------------------------------- libsrc/common/gets.s | 47 +++++++++++++++++++++++++++++++++ test/ref/test_gets.c | 46 ++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 63 deletions(-) delete mode 100644 libsrc/common/gets.c create mode 100644 libsrc/common/gets.s create mode 100644 test/ref/test_gets.c diff --git a/libsrc/common/gets.c b/libsrc/common/gets.c deleted file mode 100644 index 2936c70de..000000000 --- a/libsrc/common/gets.c +++ /dev/null @@ -1,63 +0,0 @@ -/* -** gets.c -** -** Ullrich von Bassewitz, 11.08.1998 -*/ - - - -#include -#include "_file.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -char* __fastcall__ gets (char* s) -{ - register char* p = s; - int c; - unsigned i = 0; - - while (1) { - - /* Get next character */ - if ((c = fgetc (stdin)) == EOF) { - /* Error or EOF */ - *p = '\0'; - if (stdin->f_flags & _FERROR) { - /* ERROR */ - return 0; - } else { - /* EOF */ - if (i) { - return s; - } else { - return 0; - } - } - } - - /* One char more. Newline ends the input */ - if ((char) c == '\n') { - *p = '\0'; - break; - } else { - *p = c; - ++p; - ++i; - } - - } - - /* Done */ - return s; -} - - - - diff --git a/libsrc/common/gets.s b/libsrc/common/gets.s new file mode 100644 index 000000000..dfaf2def3 --- /dev/null +++ b/libsrc/common/gets.s @@ -0,0 +1,47 @@ +; +; Colin Leroy-Mira, 2024 +; +; char* __fastcall__ gets (char* s) +; + + .export _gets + .import _fgets, _stdin, popax, pushax + .importzp ptr4 + +_gets: + ; Push buffer + sta ptr4 + stx ptr4+1 + jsr pushax + + ; Push size (there's no limit!) + lda #$FF + tax + jsr pushax + + lda _stdin + ldx _stdin+1 + + jsr _fgets + + ; Check return value + bne :+ + cpx #$00 + bne :+ + rts + +: ; At least one byte written. + jsr pushax ; Store returned pointer + + ; Remove \n if there is one. + lda ptr4 ; _fgets returns with ptr4 at + bne :+ ; end of buffer + dec ptr4+1 +: dec ptr4 + lda (ptr4),y ; _fgets returns with Y=0 + cmp #$0A + bne :+ + tya + sta (ptr4),y ; Set terminator over \n + +: jmp popax diff --git a/test/ref/test_gets.c b/test/ref/test_gets.c new file mode 100644 index 000000000..ee5b6fd58 --- /dev/null +++ b/test/ref/test_gets.c @@ -0,0 +1,46 @@ +/* + !!DESCRIPTION!! gets test + !!LICENCE!! Public domain +*/ + +#include "common.h" + +#include +#include +#include +#include +#include + +char buf[512]; + +#define INFILE "cf.in" + +#ifndef __CC65__ +/* Force declaration on host compiler, as gets() is deprecated for + * being dangerous as hell */ +char *gets (char *__s); +#endif + +#ifdef NO_OLD_FUNC_DECL +int main(int argc,char **argv) +#else +main(argc, argv) +int argc; +char *argv[]; +#endif +{ + /* Fake stdin with the reference file */ + fclose(stdin); + stdin = fopen(INFILE, "r"); + if (stdin == NULL) { + return EXIT_FAILURE; + } + + while (gets(buf) != NULL) + { + printf("%s",buf); + } + + fclose(stdin); + return 0; +} From 0dd7b0c3a5204ac96ae6067f3d48cbfc4f62ec05 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Thu, 25 Jan 2024 09:12:46 +0100 Subject: [PATCH 130/707] Implement __sysremove for sim65 This will allow using unlink()/remove() in sim65 programs Use it to unlink fgets' test output file --- libsrc/sim6502/paravirt.s | 5 ++++ src/sim65/paravirt.c | 43 ++++++++++++++++++++++++++++-- src/sim65/paravirt.h | 6 ++--- test/ref/test_fgets.c | 2 ++ test/val/remove.c | 55 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 test/val/remove.c diff --git a/libsrc/sim6502/paravirt.s b/libsrc/sim6502/paravirt.s index 0d8e528b1..3bd40fbe4 100644 --- a/libsrc/sim6502/paravirt.s +++ b/libsrc/sim6502/paravirt.s @@ -8,10 +8,15 @@ ; .export exit, args, _open, _close, _read, _write + .export __sysremove, ___osmaperrno +__sysremove := $FFF2 +___osmaperrno := $FFF3 _open := $FFF4 _close := $FFF5 _read := $FFF6 _write := $FFF7 args := $FFF8 exit := $FFF9 + + ; $FFFA-FFFF are hardware vectors, extend before not after! diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 2e52d6e7e..141bcd2bd 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -163,7 +163,7 @@ static void PVArgs (CPURegs* Regs) static void PVOpen (CPURegs* Regs) { - char Path[PVOPEN_PATH_SIZE]; + char Path[PV_PATH_SIZE]; int OFlag = O_INITIAL; int OMode = 0; unsigned RetVal, I = 0; @@ -184,7 +184,7 @@ static void PVOpen (CPURegs* Regs) break; } ++I; - if (I >= PVOPEN_PATH_SIZE) { + if (I >= PV_PATH_SIZE) { Error("PVOpen path too long at address $%04X",Name); } } @@ -253,6 +253,35 @@ static void PVClose (CPURegs* Regs) +static void PVSysRemove (CPURegs* Regs) +{ + char Path[PV_PATH_SIZE]; + unsigned RetVal, I = 0; + + unsigned Name = GetAX (Regs); + + Print (stderr, 2, "PVSysRemove ($%04X)\n", Name); + + do { + if (!(Path[I] = MemReadByte ((Name + I) & 0xFFFF))) { + break; + } + ++I; + if (I >= PV_PATH_SIZE) { + Error("PVSysRemove path too long at address $%04X", Name); + } + } + while (1); + + Print (stderr, 2, "PVSysRemove (\"%s\")\n", Path); + + RetVal = remove (Path); + + SetAX (Regs, RetVal); +} + + + static void PVRead (CPURegs* Regs) { unsigned char* Data; @@ -305,7 +334,17 @@ static void PVWrite (CPURegs* Regs) +static void PVOSMapErrno (CPURegs* Regs) +{ + unsigned err = GetAX(Regs); + SetAX (Regs, err != 0 ? -1 : 0); +} + + + static const PVFunc Hooks[] = { + PVSysRemove, + PVOSMapErrno, PVOpen, PVClose, PVRead, diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 3badb50ea..f3281705e 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -44,11 +44,11 @@ -#define PARAVIRT_BASE 0xFFF4 +#define PARAVIRT_BASE 0xFFF2 /* Lowest address used by a paravirtualization hook */ -#define PVOPEN_PATH_SIZE 1024 -/* Maximum path size supported by PVOpen */ +#define PV_PATH_SIZE 1024 +/* Maximum path size supported by PVOpen/PVSysRemove */ diff --git a/test/ref/test_fgets.c b/test/ref/test_fgets.c index 72ea308dd..0529b1651 100644 --- a/test/ref/test_fgets.c +++ b/test/ref/test_fgets.c @@ -10,6 +10,7 @@ #include #include #include +#include FILE *in, *out; char buf[32]; @@ -34,6 +35,7 @@ int main(int argc,char **argv) printf("Error: file pointer should be in error state\n"); } fclose(out); + unlink(outfile_path); in = fopen(INFILE, "rb"); if (in == NULL) { diff --git a/test/val/remove.c b/test/val/remove.c new file mode 100644 index 000000000..eecf8be8f --- /dev/null +++ b/test/val/remove.c @@ -0,0 +1,55 @@ +#include +#include +#include + +int fails = 0; + + +static void create_out_file(const char *outfile_path) { + FILE *out; + + + out = fopen(outfile_path, "wb"); + if (out == NULL) { + printf("Could not create %s\n", outfile_path); + fails++; + return; + } + fclose(out); +} + +int main (int argc, char **argv) +{ + int r; + static char outfile_path[FILENAME_MAX+1]; + + sprintf(outfile_path, "%s.test.out", argv[0]); + + create_out_file(outfile_path); + r = remove(outfile_path); + if (r != 0) { + printf("could not remove() %s\n", outfile_path); + fails++; + } + + create_out_file(outfile_path); + r = unlink(outfile_path); + if (r != 0) { + printf("could not unlink() %s\n", outfile_path); + fails++; + } + + r = remove("klsdfjqlsjdflkqjdsoizu"); + if (r == 0) { + printf("remove()ing non-existent file succeeded\n"); + fails++; + } + + r = unlink("klsdfjqlsjdflkqjdsoizu"); + if (r == 0) { + printf("unlink()ing non-existent file succeeded\n"); + fails++; + } + + return fails; +} From 7d7cf2d1e0f13dc095c4b085633772b2fab08eb1 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sun, 28 Jan 2024 21:33:12 +0100 Subject: [PATCH 131/707] Implement aslax7/shlax7/asrax7/shrax7 --- libsrc/runtime/aslax7.s | 21 +++++++++++++++++ libsrc/runtime/asrax7.s | 18 ++++++++++++++ libsrc/runtime/shrax7.s | 18 ++++++++++++++ src/cc65/codegen.c | 16 +++++++++++++ src/cc65/codeinfo.c | 4 ++++ test/val/lib_runtime_aslax7.c | 44 +++++++++++++++++++++++++++++++++++ test/val/lib_runtime_asrax7.c | 44 +++++++++++++++++++++++++++++++++++ test/val/lib_runtime_shlax7.c | 44 +++++++++++++++++++++++++++++++++++ test/val/lib_runtime_shrax7.c | 44 +++++++++++++++++++++++++++++++++++ 9 files changed, 253 insertions(+) create mode 100644 libsrc/runtime/aslax7.s create mode 100644 libsrc/runtime/asrax7.s create mode 100644 libsrc/runtime/shrax7.s create mode 100644 test/val/lib_runtime_aslax7.c create mode 100644 test/val/lib_runtime_asrax7.c create mode 100644 test/val/lib_runtime_shlax7.c create mode 100644 test/val/lib_runtime_shrax7.c diff --git a/libsrc/runtime/aslax7.s b/libsrc/runtime/aslax7.s new file mode 100644 index 000000000..533ee55e6 --- /dev/null +++ b/libsrc/runtime/aslax7.s @@ -0,0 +1,21 @@ +; +; Miloslaw Smyk, 2024 +; +; CC65 runtime: Scale the primary register by 128, unsigned +; + + .export shlax7, aslax7 + +aslax7: +shlax7: ; XXXXXXXL AAAAAAAl + tay + txa + lsr ; XXXXXXXL -> 0XXXXXXX, L->C + tya + ror ; AAAAAAAl -> LAAAAAAA, l->C + tax + lda #$00 ; LAAAAAAA 00000000 + ror ; LAAAAAAA l0000000 + rts + + ; 10 bytes, 16 cycles + rts diff --git a/libsrc/runtime/asrax7.s b/libsrc/runtime/asrax7.s new file mode 100644 index 000000000..3c9cce681 --- /dev/null +++ b/libsrc/runtime/asrax7.s @@ -0,0 +1,18 @@ +; +; Miloslaw Smyk, 2024 +; +; CC65 runtime: Scale the primary register by 128, signed +; + + .export asrax7 + +asrax7: ; HXXXXXXL hAAAAAAl + asl ; AAAAAAA0, h->C + txa + rol ; XXXXXXLh, H->C + ldx #$00 ; 00000000 XXXXXXLh + bcc :+ + dex ; 11111111 XXXXXXLh if C +: rts + + ; 12 cycles max, 9 bytes diff --git a/libsrc/runtime/shrax7.s b/libsrc/runtime/shrax7.s new file mode 100644 index 000000000..31712ca72 --- /dev/null +++ b/libsrc/runtime/shrax7.s @@ -0,0 +1,18 @@ +; +; Miloslaw Smyk, 2024 +; +; CC65 runtime: Scale the primary register by 128, unsigned +; + + .export shrax7 + +shrax7: ; HXXXXXXL hAAAAAAl + asl ; AAAAAAA0, h->C + txa + rol ; XXXXXXLh, H->C + ldx #$00 ; 00000000 XXXXXXLh + bcc :+ + inx ; 0000000H XXXXXXLh if C +: rts + + ; 12 cycles max, 9 bytes diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index c2bdfcd63..69dcc1c6c 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -3260,6 +3260,14 @@ void g_asr (unsigned flags, unsigned long val) } val -= 8; } + if (val == 7) { + if (flags & CF_UNSIGNED) { + AddCodeLine ("jsr shrax7"); + } else { + AddCodeLine ("jsr asrax7"); + } + val = 0; + } if (val >= 4) { if (flags & CF_UNSIGNED) { AddCodeLine ("jsr shrax4"); @@ -3402,6 +3410,14 @@ void g_asl (unsigned flags, unsigned long val) AddCodeLine ("lda #$00"); val -= 8; } + if (val == 7) { + if (flags & CF_UNSIGNED) { + AddCodeLine ("jsr shlax7"); + } else { + AddCodeLine ("jsr aslax7"); + } + val = 0; + } if (val >= 4) { if (flags & CF_UNSIGNED) { AddCodeLine ("jsr shlax4"); diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 88f8a5138..427bfc52b 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -99,6 +99,7 @@ static const FuncInfo FuncInfoTable[] = { { "aslax2", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, { "aslax3", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, { "aslax4", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "aslax7", REG_AX, PSTATE_ALL | REG_AXY }, { "aslaxy", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 }, { "asleax1", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, { "asleax2", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, @@ -108,6 +109,7 @@ static const FuncInfo FuncInfoTable[] = { { "asrax2", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, { "asrax3", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, { "asrax4", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "asrax7", REG_AX, PSTATE_ALL | REG_AX }, { "asraxy", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 }, { "asreax1", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, { "asreax2", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, @@ -245,6 +247,7 @@ static const FuncInfo FuncInfoTable[] = { { "shlax2", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, { "shlax3", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, { "shlax4", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "shlax7", REG_AX, PSTATE_ALL | REG_AXY }, { "shlaxy", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 }, { "shleax1", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, { "shleax2", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, @@ -254,6 +257,7 @@ static const FuncInfo FuncInfoTable[] = { { "shrax2", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, { "shrax3", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, { "shrax4", REG_AX, PSTATE_ALL | REG_AX | REG_TMP1 }, + { "shrax7", REG_AX, PSTATE_ALL | REG_AX }, { "shraxy", REG_AXY, PSTATE_ALL | REG_AXY | REG_TMP1 }, { "shreax1", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, { "shreax2", REG_EAX, PSTATE_ALL | REG_EAX | REG_TMP1 }, diff --git a/test/val/lib_runtime_aslax7.c b/test/val/lib_runtime_aslax7.c new file mode 100644 index 000000000..ea8f0b375 --- /dev/null +++ b/test/val/lib_runtime_aslax7.c @@ -0,0 +1,44 @@ +/* + !!DESCRIPTION!! A small test for aslax7. + !!ORIGIN!! + !!LICENCE!! + !!AUTHOR!! +*/ + +#include +#include +#include +#include +#include + +int main (void) +{ + signed int ai = -32768, ti, refi; + signed char ac = -128, tc, refc; + + do { + refi = ai << 4; + refi = refi << 3; + + ti = ai << 7; + + if (ti != refi) { + printf("wrong result on int %d << 7: %04X, expected %04X\n", ai, ti, refi); + return 1; + } + } while (ai != -32768); + + do { + refc = ac << 4; + refc = refc << 3; + + tc = ac << 7; + + if (tc != refc) { + printf("wrong result on char %d << 7: %04X, expected %04X\n", ac, tc, refc); + return 1; + } + } while (ac != -128); + + return 0; +} diff --git a/test/val/lib_runtime_asrax7.c b/test/val/lib_runtime_asrax7.c new file mode 100644 index 000000000..942efea1d --- /dev/null +++ b/test/val/lib_runtime_asrax7.c @@ -0,0 +1,44 @@ +/* + !!DESCRIPTION!! A small test for asrax7. + !!ORIGIN!! + !!LICENCE!! + !!AUTHOR!! +*/ + +#include +#include +#include +#include +#include + +int main (void) +{ + signed int ai = -32768, ti, refi; + signed char ac = -128, tc, refc; + + do { + refi = ai >> 4; + refi = refi >> 3; + + ti = ai >> 7; + + if (ti != refi) { + printf("wrong result on int %d >> 7: %04X, expected %04X\n", ai, ti, refi); + return 1; + } + } while (ai != -32768); + + do { + refc = ac >> 4; + refc = refc >> 3; + + tc = ac >> 7; + + if (tc != refc) { + printf("wrong result on char %d >> 7: %04X, expected %04X\n", ac, tc, refc); + return 1; + } + } while (ac != -128); + + return 0; +} diff --git a/test/val/lib_runtime_shlax7.c b/test/val/lib_runtime_shlax7.c new file mode 100644 index 000000000..9a4869438 --- /dev/null +++ b/test/val/lib_runtime_shlax7.c @@ -0,0 +1,44 @@ +/* + !!DESCRIPTION!! A small test for shlax7. + !!ORIGIN!! + !!LICENCE!! + !!AUTHOR!! +*/ + +#include +#include +#include +#include +#include + +int main (void) +{ + unsigned int ai = 0, ti, refi; + unsigned char ac = 0, tc, refc; + + do { + refi = ai << 4; + refi = refi << 3; + + ti = ai << 7; + + if (ti != refi) { + printf("wrong result on int %u << 7: %04X, expected %04X\n", ai, ti, refi); + return 1; + } + } while (ai != 0); + + do { + refc = ac << 4; + refc = refc << 3; + + tc = ac << 7; + + if (tc != refc) { + printf("wrong result on char %u << 7: %04X, expected %04X\n", ac, tc, refc); + return 1; + } + } while (ac != 0); + + return 0; +} diff --git a/test/val/lib_runtime_shrax7.c b/test/val/lib_runtime_shrax7.c new file mode 100644 index 000000000..db7356d0e --- /dev/null +++ b/test/val/lib_runtime_shrax7.c @@ -0,0 +1,44 @@ +/* + !!DESCRIPTION!! A small test for shrax7. + !!ORIGIN!! + !!LICENCE!! + !!AUTHOR!! +*/ + +#include +#include +#include +#include +#include + +int main (void) +{ + unsigned int ai = 0, ti, refi; + unsigned char ac = 0, tc, refc; + + do { + refi = ai >> 4; + refi = refi >> 3; + + ti = ai >> 7; + + if (ti != refi) { + printf("wrong result on int %d >> 7: %04X, expected %04X\n", ai, ti, refi); + return 1; + } + } while (ai != 0); + + do { + refc = ac >> 4; + refc = refc >> 3; + + tc = ac >> 7; + + if (tc != refc) { + printf("wrong result on char %d >> 7: %04X, expected %04X\n", ac, tc, refc); + return 1; + } + } while (ac != 0); + + return 0; +} From 9ffa2d05e65fd0aa3455235ffc5cc74cd9159c58 Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Tue, 30 Jan 2024 00:17:28 -0800 Subject: [PATCH 132/707] rp6502 validate write_xstack count --- include/rp6502.h | 3 +-- libsrc/rp6502/write_xstack.c | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/rp6502.h b/include/rp6502.h index 61664c78f..53028c35a 100644 --- a/include/rp6502.h +++ b/include/rp6502.h @@ -47,8 +47,7 @@ struct __RP6502 unsigned char step1; unsigned int addr1; unsigned char xstack; - unsigned char errno_lo; - unsigned char errno_hi; + unsigned int errno; unsigned char op; unsigned char irq; const unsigned char spin; diff --git a/libsrc/rp6502/write_xstack.c b/libsrc/rp6502/write_xstack.c index b53aa95e7..ff979899d 100644 --- a/libsrc/rp6502/write_xstack.c +++ b/libsrc/rp6502/write_xstack.c @@ -1,8 +1,12 @@ #include +#include int __fastcall__ write_xstack (const void* buf, unsigned count, int fildes) { unsigned i; + if (count > 256) { + return _mappederrno (EINVAL); + } for (i = count; i;) { ria_push_char (((char*)buf)[--i]); } From 7594af553ae3a189e7a7f9cf2f59c47af51441eb Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Sun, 28 Jan 2024 17:00:02 +0100 Subject: [PATCH 133/707] Fix #2388 Reopen stdin in binary mode instead of closing/opening --- test/ref/test_gets.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/ref/test_gets.c b/test/ref/test_gets.c index ee5b6fd58..003da5569 100644 --- a/test/ref/test_gets.c +++ b/test/ref/test_gets.c @@ -30,9 +30,7 @@ char *argv[]; #endif { /* Fake stdin with the reference file */ - fclose(stdin); - stdin = fopen(INFILE, "r"); - if (stdin == NULL) { + if (freopen(INFILE, "rb", stdin) == NULL) { return EXIT_FAILURE; } From ba3607102263c73af18105902a8e50063618bd96 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Tue, 30 Jan 2024 17:51:00 +0100 Subject: [PATCH 134/707] Rewrite fputs in assembly -28 bytes, -1% cycles --- libsrc/common/fputs.c | 28 ---------------------------- libsrc/common/fputs.s | 42 ++++++++++++++++++++++++++++++++++++++++++ test/ref/test_fputs.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 28 deletions(-) delete mode 100644 libsrc/common/fputs.c create mode 100644 libsrc/common/fputs.s create mode 100644 test/ref/test_fputs.c diff --git a/libsrc/common/fputs.c b/libsrc/common/fputs.c deleted file mode 100644 index be476a3f0..000000000 --- a/libsrc/common/fputs.c +++ /dev/null @@ -1,28 +0,0 @@ -/* -** int fputs (const char* s, FILE* f); -** -** Ullrich von Bassewitz, 11.08.1998 -*/ - - - -#include -#include -#include -#include "_file.h" - - - -int __fastcall__ fputs (const char* s, register FILE* f) -{ - /* Check if the file is open or if there is an error condition */ - if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) { - return EOF; - } - - /* Write the string */ - return write (f->f_fd, s, strlen (s)); -} - - - diff --git a/libsrc/common/fputs.s b/libsrc/common/fputs.s new file mode 100644 index 000000000..e70374058 --- /dev/null +++ b/libsrc/common/fputs.s @@ -0,0 +1,42 @@ +; +; Colin Leroy-Mira, 2024 +; +; int __fastcall__ fputs (const char* s, register FILE* f) +; + + .export _fputs + .importzp ptr1, ptr2 + .import _write, _strlen + .import swapstk, pushax, returnFFFF + + .include "stdio.inc" + .include "_file.inc" + +_fputs: + sta ptr1 + stx ptr1+1 + + ldy #_FILE::f_flags + lda (ptr1),y + tax + and #_FOPEN ; Check for file open + beq ret_eof + txa + and #(_FERROR|_FEOF); Check for error/eof + bne ret_eof + + ; Push _write parameters + ldy #_FILE::f_fd + lda (ptr1),y + ldx #$00 + jsr swapstk ; Push fd, get s + + jsr pushax ; Push s + + jsr _strlen ; Get length + + ; Write + jmp _write + +ret_eof: + jmp returnFFFF diff --git a/test/ref/test_fputs.c b/test/ref/test_fputs.c new file mode 100644 index 000000000..ad0552317 --- /dev/null +++ b/test/ref/test_fputs.c @@ -0,0 +1,40 @@ +/* + !!DESCRIPTION!! fgets test + !!LICENCE!! Public domain +*/ + +#include "common.h" + +#include +#include +#include +#include +#include +#include + +FILE *in, *out; +char buf[512], err; + +#define INFILE "cf.in" + +int main(int argc,char **argv) +{ + in = fopen(INFILE, "rb"); + if (in == NULL) { + return EXIT_FAILURE; + } + + strcpy(buf, "test"); + if (fputs(buf, in) != EOF) { + printf("Error: can fputs to a file opened for reading\n"); + return EXIT_FAILURE; + } + clearerr(in); + + while (fgets(buf, 512, in) != NULL) { + fputs(buf, stdout); + } + + fclose(in); + return 0; +} From 1a5a7d67a7ebb4881a90234b596fdee4612b09ef Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Tue, 30 Jan 2024 17:59:33 +0100 Subject: [PATCH 135/707] Rewrite fputc in assembly -36 bytes, -12% cycles --- libsrc/common/fputc.c | 41 ------------------------ libsrc/common/fputc.s | 72 +++++++++++++++++++++++++++++++++++++++++++ libsrc/common/fputs.s | 4 +-- test/ref/test_fputc.c | 39 +++++++++++++++++++++++ 4 files changed, 113 insertions(+), 43 deletions(-) delete mode 100644 libsrc/common/fputc.c create mode 100644 libsrc/common/fputc.s create mode 100644 test/ref/test_fputc.c diff --git a/libsrc/common/fputc.c b/libsrc/common/fputc.c deleted file mode 100644 index b623949d3..000000000 --- a/libsrc/common/fputc.c +++ /dev/null @@ -1,41 +0,0 @@ -/* -** fputc.c -** -** Ullrich von Bassewitz, 02.06.1998 -*/ - - - -#include -#include -#include "_file.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -int __fastcall__ fputc (int c, register FILE* f) -{ - /* Check if the file is open or if there is an error condition */ - if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) { - goto ReturnEOF; - } - - /* Write the byte */ - if (write (f->f_fd, &c, 1) != 1) { - /* Error */ - f->f_flags |= _FERROR; -ReturnEOF: - return EOF; - } - - /* Return the byte written */ - return c & 0xFF; -} - - - diff --git a/libsrc/common/fputc.s b/libsrc/common/fputc.s new file mode 100644 index 000000000..4633f24f1 --- /dev/null +++ b/libsrc/common/fputc.s @@ -0,0 +1,72 @@ +; +; Colin Leroy-Mira, 2024 +; +; int __fastcall__ fputc (int c, FILE* f); +; + + .export _fputc + .importzp ptr1 + .import _write + .import pushax, pusha0, popax, incsp2 + .import pushptr1, popptr1, returnFFFF + + .include "stdio.inc" + .include "_file.inc" + +_fputc: + sta ptr1 + stx ptr1+1 + + jsr popax ; Get char, as we'll have + sta c ; to return it anyway + stx c+1 + + ldy #_FILE::f_flags + lda (ptr1),y + tax + and #_FOPEN ; Check for file open + beq ret_eof + txa + and #(_FERROR|_FEOF); Check for error/eof + bne ret_eof + + jsr pushptr1 ; Backup fp pointer + + ; Push _write parameters + ldy #_FILE::f_fd + lda (ptr1),y + jsr pusha0 + + lda #c + jsr pushax + + lda #$01 + ldx #$00 + + ; Write + jsr _write + + ; Check for errors + cmp #$01 + bne set_ferror + + ; Return char + lda c + ldx #$00 + jmp incsp2 ; Drop fp pointer copy + +ret_eof: + jmp returnFFFF + +set_ferror: + jsr popptr1 + lda #_FERROR + ldy #_FILE::f_flags + ora (ptr1),y + sta (ptr1),y + jmp returnFFFF + + .bss + +c: .res 2 diff --git a/libsrc/common/fputs.s b/libsrc/common/fputs.s index e70374058..00415aef1 100644 --- a/libsrc/common/fputs.s +++ b/libsrc/common/fputs.s @@ -32,9 +32,9 @@ _fputs: jsr swapstk ; Push fd, get s jsr pushax ; Push s - + jsr _strlen ; Get length - + ; Write jmp _write diff --git a/test/ref/test_fputc.c b/test/ref/test_fputc.c new file mode 100644 index 000000000..a19aeafaf --- /dev/null +++ b/test/ref/test_fputc.c @@ -0,0 +1,39 @@ +/* + !!DESCRIPTION!! fgets test + !!LICENCE!! Public domain +*/ + +#include "common.h" + +#include +#include +#include +#include +#include +#include + +FILE *in, *out; +int c, err; + +#define INFILE "cf.in" + +int main(int argc,char **argv) +{ + in = fopen(INFILE, "rb"); + if (in == NULL) { + return EXIT_FAILURE; + } + + if (fputc(c, in) != EOF) { + printf("Error: can fputc to a file opened for reading\n"); + return EXIT_FAILURE; + } + clearerr(in); + + while ((c = fgetc(in)) != EOF) { + fputc(c, stdout); + } + + fclose(in); + return 0; +} From 2b97735d5d150f1ce9d568b10fd878fa503ca232 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Tue, 30 Jan 2024 18:11:10 +0100 Subject: [PATCH 136/707] Factorize file pointer check --- libsrc/common/checkferror.s | 24 ++++++++++++++++++++++++ libsrc/common/fgetc.s | 13 ++++--------- libsrc/common/fputc.s | 10 ++-------- libsrc/common/fputs.s | 10 ++-------- 4 files changed, 32 insertions(+), 25 deletions(-) create mode 100644 libsrc/common/checkferror.s diff --git a/libsrc/common/checkferror.s b/libsrc/common/checkferror.s new file mode 100644 index 000000000..736fa3ccd --- /dev/null +++ b/libsrc/common/checkferror.s @@ -0,0 +1,24 @@ +; +; Colin Leroy-Mira, 2024 +; +; Helper to check for file opened, not eof, not ferror +; Expects file pointer in ptr1, +; Returns with Z flag set if everything is OK, +; Destroys A, X, Y, +; Sets file flags in A +; + + .export checkferror + .importzp ptr1 + + .include "_file.inc" + +checkferror: + ldy #_FILE::f_flags + lda (ptr1),y + tax + and #(_FOPEN|_FERROR|_FEOF); Check for file open, error/eof + tay + txa + cpy #_FOPEN + rts diff --git a/libsrc/common/fgetc.s b/libsrc/common/fgetc.s index 777696b7a..98e6bb2f7 100644 --- a/libsrc/common/fgetc.s +++ b/libsrc/common/fgetc.s @@ -5,7 +5,8 @@ ; .export _fgetc - .import _read, pusha0, pushax, popptr1, incsp2, returnFFFF + .import _read, checkferror + .import pusha0, pushax, popptr1, incsp2, returnFFFF .importzp ptr1 .include "stdio.inc" @@ -16,16 +17,10 @@ _fgetc: stx ptr1+1 jsr pushax ; Backup our ptr - ldy #_FILE::f_flags - lda (ptr1),y - tax - and #_FOPEN ; Check for file open - beq ret_eof - txa - and #(_FERROR|_FEOF); Check for error/eof + jsr checkferror bne ret_eof - txa + tax and #_FPUSHBACK ; Check for pushed back char beq do_read diff --git a/libsrc/common/fputc.s b/libsrc/common/fputc.s index 4633f24f1..358723538 100644 --- a/libsrc/common/fputc.s +++ b/libsrc/common/fputc.s @@ -6,7 +6,7 @@ .export _fputc .importzp ptr1 - .import _write + .import _write, checkferror .import pushax, pusha0, popax, incsp2 .import pushptr1, popptr1, returnFFFF @@ -21,13 +21,7 @@ _fputc: sta c ; to return it anyway stx c+1 - ldy #_FILE::f_flags - lda (ptr1),y - tax - and #_FOPEN ; Check for file open - beq ret_eof - txa - and #(_FERROR|_FEOF); Check for error/eof + jsr checkferror bne ret_eof jsr pushptr1 ; Backup fp pointer diff --git a/libsrc/common/fputs.s b/libsrc/common/fputs.s index 00415aef1..b79a4707f 100644 --- a/libsrc/common/fputs.s +++ b/libsrc/common/fputs.s @@ -6,7 +6,7 @@ .export _fputs .importzp ptr1, ptr2 - .import _write, _strlen + .import _write, _strlen, checkferror .import swapstk, pushax, returnFFFF .include "stdio.inc" @@ -16,13 +16,7 @@ _fputs: sta ptr1 stx ptr1+1 - ldy #_FILE::f_flags - lda (ptr1),y - tax - and #_FOPEN ; Check for file open - beq ret_eof - txa - and #(_FERROR|_FEOF); Check for error/eof + jsr checkferror bne ret_eof ; Push _write parameters From afd8ee627e4e71900f9cbacda20e010fa529684d Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Tue, 30 Jan 2024 19:52:48 +0100 Subject: [PATCH 137/707] Remove useless branching code in fgets --- libsrc/common/fgets.s | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libsrc/common/fgets.s b/libsrc/common/fgets.s index 465658191..172ca10dd 100644 --- a/libsrc/common/fgets.s +++ b/libsrc/common/fgets.s @@ -90,9 +90,7 @@ read_loop: : cmp #$0A ; Stop at \n beq done - - clc - bcc read_loop + bne read_loop got_eof: lda didread From ce606bb19e293339d31d82888fe7659d11b64b9d Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Wed, 31 Jan 2024 08:11:46 +0100 Subject: [PATCH 138/707] Fix tests... --- test/val/lib_runtime_aslax7.c | 4 ++-- test/val/lib_runtime_asrax7.c | 4 ++-- test/val/lib_runtime_shlax7.c | 4 ++-- test/val/lib_runtime_shrax7.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/val/lib_runtime_aslax7.c b/test/val/lib_runtime_aslax7.c index ea8f0b375..7e3b4796a 100644 --- a/test/val/lib_runtime_aslax7.c +++ b/test/val/lib_runtime_aslax7.c @@ -26,7 +26,7 @@ int main (void) printf("wrong result on int %d << 7: %04X, expected %04X\n", ai, ti, refi); return 1; } - } while (ai != -32768); + } while (++ai != -32768); do { refc = ac << 4; @@ -38,7 +38,7 @@ int main (void) printf("wrong result on char %d << 7: %04X, expected %04X\n", ac, tc, refc); return 1; } - } while (ac != -128); + } while (++ac != -128); return 0; } diff --git a/test/val/lib_runtime_asrax7.c b/test/val/lib_runtime_asrax7.c index 942efea1d..3cdf2aab8 100644 --- a/test/val/lib_runtime_asrax7.c +++ b/test/val/lib_runtime_asrax7.c @@ -26,7 +26,7 @@ int main (void) printf("wrong result on int %d >> 7: %04X, expected %04X\n", ai, ti, refi); return 1; } - } while (ai != -32768); + } while (++ai != -32768); do { refc = ac >> 4; @@ -38,7 +38,7 @@ int main (void) printf("wrong result on char %d >> 7: %04X, expected %04X\n", ac, tc, refc); return 1; } - } while (ac != -128); + } while (++ac != -128); return 0; } diff --git a/test/val/lib_runtime_shlax7.c b/test/val/lib_runtime_shlax7.c index 9a4869438..d2073ca3a 100644 --- a/test/val/lib_runtime_shlax7.c +++ b/test/val/lib_runtime_shlax7.c @@ -26,7 +26,7 @@ int main (void) printf("wrong result on int %u << 7: %04X, expected %04X\n", ai, ti, refi); return 1; } - } while (ai != 0); + } while (++ai != 0); do { refc = ac << 4; @@ -38,7 +38,7 @@ int main (void) printf("wrong result on char %u << 7: %04X, expected %04X\n", ac, tc, refc); return 1; } - } while (ac != 0); + } while (++ac != 0); return 0; } diff --git a/test/val/lib_runtime_shrax7.c b/test/val/lib_runtime_shrax7.c index db7356d0e..d3bc0db73 100644 --- a/test/val/lib_runtime_shrax7.c +++ b/test/val/lib_runtime_shrax7.c @@ -26,7 +26,7 @@ int main (void) printf("wrong result on int %d >> 7: %04X, expected %04X\n", ai, ti, refi); return 1; } - } while (ai != 0); + } while (++ai != 0); do { refc = ac >> 4; @@ -38,7 +38,7 @@ int main (void) printf("wrong result on char %d >> 7: %04X, expected %04X\n", ac, tc, refc); return 1; } - } while (ac != 0); + } while (++ac != 0); return 0; } From 1e300bf768b949498895062b157d71aa3ac9bbc1 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Thu, 1 Feb 2024 20:13:05 +0100 Subject: [PATCH 139/707] Add test case for issue #2395 --- test/todo/bug2395.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 test/todo/bug2395.c diff --git a/test/todo/bug2395.c b/test/todo/bug2395.c new file mode 100644 index 000000000..4f4d2a6d0 --- /dev/null +++ b/test/todo/bug2395.c @@ -0,0 +1,51 @@ + +/* bug #2395: Bitwise operators with a boolean expression fail when optimized */ + +#include +#include +#include + +unsigned char a, b; +unsigned char c = 199; +unsigned char d = 100; + +int main(void) { + int fails = 0; + + a = c ^ (d != 0); + b = c ^ 1; + + printf("%u ^ (%u != 0) => %u\n", c, d, a); + if (a != b) { + printf("XOR error: a %d instead of %d\n", a, b); + fails++; + } + + a = c | (d != 0); + b = c | 1; + + printf("%u | (%u != 0) => %u\n", c, d, a); + if (a != b) { + printf("OR error: a %d instead of %d\n", a, b); + fails++; + } + + a = c & (d != 0); + b = c & 1; + + printf("%u & (%u != 0) => %u\n", c, d, a); + if (a != b) { + printf("AND error: a %d instead of %d\n", a, b); + fails++; + } + printf("%d errors\n", fails); + +#ifdef __OPT__ + return fails; +#else + /* Force exit failure on non-optimised version, which works, + * otherwise it breaks the build + */ + return 1; +#endif +} From 96d55e3703de9a9b079cc7f4da8e6b5ed82fb6e5 Mon Sep 17 00:00:00 2001 From: acqn Date: Fri, 2 Feb 2024 19:00:33 +0800 Subject: [PATCH 140/707] Fixed optimization for char-size bitwise XOR/OR/AND when the rhs operand is complicated. --- src/cc65/coptstop.c | 6 +++--- test/{todo => val}/bug2395.c | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename test/{todo => val}/bug2395.c (100%) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 7e024ae88..402f16b97 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1488,7 +1488,7 @@ static const OptFuncDesc FuncTable[] = { }; static const OptFuncDesc FuncRegATable[] = { - { "tosandax", Opt_a_tosand, REG_NONE, OP_NONE }, + { "tosandax", Opt_a_tosand, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, { "toseqax", Opt_a_toseq, REG_NONE, OP_NONE }, { "tosgeax", Opt_a_tosuge, REG_NONE, OP_NONE }, { "tosgtax", Opt_a_tosugt, REG_NONE, OP_NONE }, @@ -1496,13 +1496,13 @@ static const OptFuncDesc FuncRegATable[] = { { "tosleax", Opt_a_tosule, REG_NONE, OP_NONE }, { "tosltax", Opt_a_tosult, REG_NONE, OP_NONE }, { "tosneax", Opt_a_tosne, REG_NONE, OP_NONE }, - { "tosorax", Opt_a_tosor, REG_NONE, OP_NONE }, + { "tosorax", Opt_a_tosor, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, { "tossubax", Opt_a_tossub, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, { "tosugeax", Opt_a_tosuge, REG_NONE, OP_NONE }, { "tosugtax", Opt_a_tosugt, REG_NONE, OP_NONE }, { "tosuleax", Opt_a_tosule, REG_NONE, OP_NONE }, { "tosultax", Opt_a_tosult, REG_NONE, OP_NONE }, - { "tosxorax", Opt_a_tosxor, REG_NONE, OP_NONE }, + { "tosxorax", Opt_a_tosxor, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, }; #define FUNC_COUNT(Table) (sizeof(Table) / sizeof(Table[0])) diff --git a/test/todo/bug2395.c b/test/val/bug2395.c similarity index 100% rename from test/todo/bug2395.c rename to test/val/bug2395.c From 54b423a99efbfec9634d68cbddc596f13da89f7f Mon Sep 17 00:00:00 2001 From: Bob Andrews Date: Fri, 2 Feb 2024 13:13:57 +0100 Subject: [PATCH 141/707] fix test --- test/val/bug2395.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/val/bug2395.c b/test/val/bug2395.c index 4f4d2a6d0..07c5cd7c5 100644 --- a/test/val/bug2395.c +++ b/test/val/bug2395.c @@ -40,12 +40,5 @@ int main(void) { } printf("%d errors\n", fails); -#ifdef __OPT__ return fails; -#else - /* Force exit failure on non-optimised version, which works, - * otherwise it breaks the build - */ - return 1; -#endif } From c4c6967e4a557915707f549e01cc24205b68265b Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Fri, 2 Feb 2024 19:34:45 +0100 Subject: [PATCH 142/707] Enable Windows tests on pull requests --- .github/workflows/build-on-pull-request.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 045bc048d..6217c42a2 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -54,7 +54,7 @@ jobs: make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=x86_64-w64-mingw32- build_windows: - name: Build (Windows) + name: Build and Test (Windows) runs-on: windows-latest steps: @@ -79,4 +79,14 @@ jobs: - name: Build app (x64 release) run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release -property:Platform=x64 + - name: Build utils (MinGW) + shell: cmd + run: make -j2 util SHELL=cmd + - name: Build the platform libraries (make lib) + shell: cmd + run: make -j2 lib QUIET=1 SHELL=cmd + + - name: Run the regression tests (make test) + shell: cmd + run: make test QUIET=1 SHELL=cmd From 1fab179cb467e13c581ec65f635658cb9acf3264 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Thu, 1 Feb 2024 20:05:57 +0100 Subject: [PATCH 143/707] a BIT of 65C02 optimisations Use BIT immediate instead of AND when reloading A is required afterwards. Add an fread unit test as the optimisation touches fread. Sprinkle a few zero page indexed while we're at it. --- libsrc/common/_printf.s | 29 +++++++++++++++-- libsrc/common/fgetc.s | 9 +++++- libsrc/common/fread.s | 32 +++++++++++++++++-- libsrc/common/fwrite.s | 15 ++++++--- test/ref/test_fread.c | 70 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 test/ref/test_fread.c diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index a0074583e..d7eeb072d 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -13,6 +13,7 @@ .import _strlower, _strlen .macpack generic + .macpack cpu ; ---------------------------------------------------------------------------- ; We will store variables into the register bank in the zeropage. Define @@ -37,7 +38,11 @@ FCount = ptr2 GetFormatChar: ldy #0 + .if (.cpu .bitand ::CPU_ISET_65SC02) + lda (Format) + .else lda (Format),y + .endif IncFormatPtr: inc Format bne @L1 @@ -110,7 +115,11 @@ GetIntArg: lda (ArgList),y tax dey + .if (.cpu .bitand ::CPU_ISET_65SC02) + lda (ArgList) + .else lda (ArgList),y + .endif rts ; ---------------------------------------------------------------------------- @@ -135,9 +144,9 @@ ReadInt: pha ; Save digit value lda ptr1 ldx ptr1+1 - asl ptr1 + asl a rol ptr1+1 ; * 2 - asl ptr1 + asl a rol ptr1+1 ; * 4, assume carry clear adc ptr1 sta ptr1 @@ -265,10 +274,16 @@ Save: lda regbank,y ; Initialize the output counter in the output descriptor to zero lda #0 + .if (.cpu .bitand ::CPU_ISET_65SC02) + sta (OutData) + ldy #$01 + sta (OutData),y + .else tay sta (OutData),y iny sta (OutData),y + .endif ; Get the output function from the output descriptor and remember it @@ -338,7 +353,11 @@ MainLoop: sta (sp),y dey lda FCount + .if (.cpu .bitand ::CPU_ISET_65SC02) + sta (sp) + .else sta (sp),y + .endif jsr CallOutFunc ; Call the output function ; We're back from out(), or we didn't call it. Check for end of string. @@ -551,10 +570,16 @@ CheckCount: jsr GetIntArg sta ptr1 stx ptr1+1 ; Get user supplied pointer + .if (.cpu .bitand ::CPU_ISET_65SC02) + lda (OutData) ; Low byte of OutData->ccount + sta (ptr1) + ldy #1 + .else ldy #0 lda (OutData),y ; Low byte of OutData->ccount sta (ptr1),y iny + .endif lda (OutData),y ; High byte of OutData->ccount sta (ptr1),y jmp MainLoop ; Done diff --git a/libsrc/common/fgetc.s b/libsrc/common/fgetc.s index 98e6bb2f7..34d4df3aa 100644 --- a/libsrc/common/fgetc.s +++ b/libsrc/common/fgetc.s @@ -12,6 +12,8 @@ .include "stdio.inc" .include "_file.inc" + .macpack cpu + _fgetc: sta ptr1 stx ptr1+1 @@ -20,11 +22,16 @@ _fgetc: jsr checkferror bne ret_eof + .if (.cpu .bitand ::CPU_ISET_65SC02) + bit #_FPUSHBACK ; Check for pushed back char + beq do_read + .else tax and #_FPUSHBACK ; Check for pushed back char beq do_read - txa + .endif + and #<(~_FPUSHBACK) ; Reset flag sta (ptr1),y diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index 647a7f2c8..b39b9d748 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -20,6 +20,7 @@ .include "_file.inc" .macpack generic + .macpack cpu ; ------------------------------------------------------------------------ ; Code @@ -47,13 +48,21 @@ ldy #_FILE::f_flags lda (file),y + .if (.cpu .bitand ::CPU_ISET_65SC02) + bit #_FOPEN ; Is the file open? + .else and #_FOPEN ; Is the file open? + .endif beq @L1 ; Branch if no ; Check if the stream is in an error state + .if (.cpu .bitand ::CPU_ISET_65SC02) + bit #_FERROR + .else lda (file),y ; get file->f_flags again and #_FERROR + .endif beq @L2 ; File not open or in error state @@ -65,11 +74,19 @@ ; Remember if we have a pushed back character and reset the flag. -@L2: tax ; X = 0 +@L2: .if (.cpu .bitand ::CPU_ISET_65SC02) + ldx #$00 + bit #_FPUSHBACK + .else + tax ; X = 0 lda (file),y and #_FPUSHBACK + .endif beq @L3 + + .if (.not .cpu .bitand ::CPU_ISET_65SC02) lda (file),y + .endif and #<~_FPUSHBACK sta (file),y ; file->f_flags &= ~_FPUSHBACK; inx ; X = 1 @@ -118,12 +135,20 @@ ; Copy the buffer pointer into ptr1, and increment the pointer value passed ; to read() by one, so read() starts to store data at buf+1. + .if (.cpu .bitand ::CPU_ISET_65SC02) + lda (sp) + sta ptr1 + add #1 + sta (sp) + ldy #1 + .else ldy #0 lda (sp),y sta ptr1 add #1 sta (sp),y iny + .endif lda (sp),y sta ptr1+1 adc #0 @@ -134,8 +159,12 @@ ldy #_FILE::f_pushback lda (file),y + .if (.cpu .bitand ::CPU_ISET_65SC02) + sta (ptr1) ; *buf = file->f_pushback; + .else ldy #0 sta (ptr1),y ; *buf = file->f_pushback; + .endif ; Restore the low byte of count and decrement count by one. This may result ; in count being zero, so check for that. @@ -210,4 +239,3 @@ .bss save: .res 2 pb: .res 1 - diff --git a/libsrc/common/fwrite.s b/libsrc/common/fwrite.s index 861feb120..e7151da95 100644 --- a/libsrc/common/fwrite.s +++ b/libsrc/common/fwrite.s @@ -8,7 +8,7 @@ .export _fwrite .import _write - .import pushax, incsp6, addysp, ldaxysp, pushwysp, return0 + .import pushax, pusha0, incsp6, addysp, ldaxysp, pushwysp, return0 .import tosumulax, tosudivax .importzp ptr1 @@ -16,6 +16,7 @@ .include "errno.inc" .include "_file.inc" + .macpack cpu ; ------------------------------------------------------------------------ ; Code @@ -33,7 +34,11 @@ ldy #_FILE::f_flags lda (ptr1),y + .if (.cpu .bitand ::CPU_ISET_65SC02) + bit #_FOPEN + .else and #_FOPEN ; Is the file open? + .endif bne @L2 ; Branch if yes ; File not open @@ -45,7 +50,9 @@ ; Check if the stream is in an error state -@L2: lda (ptr1),y ; get file->f_flags again +@L2: .if (.not .cpu .bitand ::CPU_ISET_65SC02) + lda (ptr1),y ; get file->f_flags again + .endif and #_FERROR bne @L1 @@ -53,8 +60,7 @@ ldy #_FILE::f_fd lda (ptr1),y - ldx #$00 - jsr pushax ; file->f_fd + jsr pusha0 ; file->f_fd ldy #9 jsr pushwysp ; buf @@ -123,4 +129,3 @@ .bss file: .res 2 - diff --git a/test/ref/test_fread.c b/test/ref/test_fread.c new file mode 100644 index 000000000..5d180d723 --- /dev/null +++ b/test/ref/test_fread.c @@ -0,0 +1,70 @@ +/* + !!DESCRIPTION!! fgets test + !!LICENCE!! Public domain +*/ + +#include "common.h" + +#include +#include +#include +#include +#include +#include + +FILE *in, *out; +char buf[32]; + +#define INFILE "cf.in" + +int main(int argc,char **argv) +{ + static char outfile_path[FILENAME_MAX+1]; + static int r; + + sprintf(outfile_path, "%s.test.out", argv[0]); + + out = fopen(outfile_path, "wb"); + if (out == NULL) { + return EXIT_FAILURE; + } + if (fread(buf, 1, sizeof(buf), out) != NULL) { + printf("Error, could fread with write-only file\n"); + return 1; + } + if (!ferror(out)) { + printf("Error: file pointer should be in error state\n"); + } + fclose(out); + unlink(outfile_path); + + in = fopen(INFILE, "rb"); + if (in == NULL) { + return EXIT_FAILURE; + } + + /* Test that ungetc doesn't break fread */ + buf[0] = fgetc(in); + ungetc(buf[0], in); + + r = fread(buf, 1, sizeof(buf), out); + + if (r == 0) { + printf("Error: could not start reading.\n"); + } + fwrite(buf, 1, r, stdout); + + /* Finish reading file. */ + while ((r = fread(buf, 1, sizeof(buf), out)) != 0) + { + fwrite(buf, 1, r, stdout); + } + + if (!feof(in)) + { + printf("We should have EOF!\n"); + } + + fclose(in); + return 0; +} From 934de685bcc6501631c51ccb96e9f499ecb4709c Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sat, 3 Feb 2024 01:34:21 +0100 Subject: [PATCH 144/707] this is pr #2194 - removed ramfont.o --- cfg/kim1-mtu60k.cfg | 41 ++ cfg/kim1-mtuE000.cfg | 41 ++ samples/kim1/Makefile | 61 +- samples/kim1/font.rom | 0 samples/kim1/kimGFX.c | 290 ++++++++++ samples/kim1/kimLife.c | 144 +++++ samples/kim1/kimTest.c | 262 +++++++++ samples/kim1/ramfont.asm | 272 +++++++++ samples/kim1/subs.asm | 1140 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 2248 insertions(+), 3 deletions(-) create mode 100644 cfg/kim1-mtu60k.cfg create mode 100644 cfg/kim1-mtuE000.cfg create mode 100644 samples/kim1/font.rom create mode 100644 samples/kim1/kimGFX.c create mode 100644 samples/kim1/kimLife.c create mode 100644 samples/kim1/kimTest.c create mode 100644 samples/kim1/ramfont.asm create mode 100644 samples/kim1/subs.asm diff --git a/cfg/kim1-mtu60k.cfg b/cfg/kim1-mtu60k.cfg new file mode 100644 index 000000000..4f24a4bf4 --- /dev/null +++ b/cfg/kim1-mtu60k.cfg @@ -0,0 +1,41 @@ +# kim1-mtu60k.cfg (4k) +# +# for expanded KIM-1 w/ K-1008 Graphics and 60K RAM +# +# ld65 --config kim1-mtu60k.cfg -o .bin .o + +FEATURES { + STARTADDRESS: default = $2000; + CONDES: segment = STARTUP, + type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__; + CONDES: segment = STARTUP, + type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__; +} + +SYMBOLS { + __STACKSIZE__: type = weak, value = $0080; # 128 byte program stack + __STARTADDRESS__: type = export, value = %S; +} + +MEMORY { + ZP: file = %O, define = yes, start = $0000, size = $00EE; + CPUSTACK: file = "", define = yes, start = $0100, size = $0100; + RAM: file = %O, define = yes, start = %S, size = $E000 - %S - __STACKSIZE__; + MAINROM: file = "", define = yes, start = $E000, size = $1000; + TOP: file = "", define = yes, start = $F000, size = $1000; +} + +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, define = yes; + STARTUP: load = RAM, type = ro, define = yes; + CODE: load = RAM, type = ro, define = yes; + RODATA: load = RAM, type = ro, define = yes; + ONCE: load = RAM, type = ro, define = yes; + DATA: load = RAM, type = rw, define = yes; + BSS: load = RAM, type = bss, define = yes; +} + diff --git a/cfg/kim1-mtuE000.cfg b/cfg/kim1-mtuE000.cfg new file mode 100644 index 000000000..5f93cc13f --- /dev/null +++ b/cfg/kim1-mtuE000.cfg @@ -0,0 +1,41 @@ +# kim1-mtu60k.cfg (4k) +# +# for expanded KIM-1 w/ K-1008 Graphics and 60K RAM +# +# ld65 --config kim1-mtu60k.cfg -o .bin .o + +FEATURES { + STARTADDRESS: default = $E000; + CONDES: segment = STARTUP, + type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__; + CONDES: segment = STARTUP, + type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__; +} + +SYMBOLS { + __STACKSIZE__: type = weak, value = $0080; # 128 byte program stack + __STARTADDRESS__: type = export, value = %S; +} + +MEMORY { + ZP: file = %O, define = yes, start = $0000, size = $00EE; + CPUSTACK: file = "", define = yes, start = $0100, size = $0100; + RAM: file = %O, define = yes, start = $2000, size = $E000 - $2000 - __STACKSIZE__; + MAINROM: file = "", define = yes, start = $E000, size = $1000; + TOP: file = "", define = yes, start = $F000, size = $1000; +} + +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, define = yes; + STARTUP: load = RAM, type = ro, define = yes; + CODE: load = RAM, type = ro, define = yes; + RODATA: load = RAM, type = ro, define = yes; + ONCE: load = RAM, type = ro, define = yes; + DATA: load = RAM, type = rw, define = yes; + BSS: load = RAM, type = bss, define = yes; +} + diff --git a/samples/kim1/Makefile b/samples/kim1/Makefile index 74c415fdc..08bb2a780 100644 --- a/samples/kim1/Makefile +++ b/samples/kim1/Makefile @@ -31,9 +31,12 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif -EXELIST_kim1 = \ - kimHello.bin \ - kimSieve.bin +EXELIST_kim1 = \ + kimHello.bin \ + kimSieve.bin \ + kimLife.bin \ + kimTest.bin \ + kimGFX.bin ifneq ($(EXELIST_$(SYS)),) samples: $(EXELIST_$(SYS)) @@ -50,13 +53,65 @@ else @echo > $(NULLDEV) endif +subs.o: subs.asm + $(AS) subs.asm -o subs.o + +ramfont.o: ramfont.asm + $(AS) ramfont.asm -o ramfont.o + +kimLife.bin: kimLife.c + $(CL) -t kim1 -C kim1-60k.cfg -Oi -o kimLife.bin kimLife.c + +kimTest.bin: kimTest.c + $(CL) -t kim1 -C kim1-60k.cfg -Oi -o kimTest.bin kimTest.c + +kimGFX.bin: kimGFX.c subs.o ramfont.o + $(CL) -t kim1 --listing kimGFX.lst -C kim1-mtuE000.cfg -o kimGFX.bin kimGFX.c subs.o ramfont.o -Ln kimgfx.lbl + kimSieve.bin: kimSieve.c $(CL) -t kim1 -C kim1-60k.cfg -O -o kimSieve.bin kimSieve.c kimHello.bin: kimHello.c $(CL) -t kim1 -O -o kimHello.bin kimHello.c +# To build an intel-format file for the CORSHAM SD card reader + +kimLife.hex: kimLife.bin + srec_cat kimLife.bin -binary -offset 0x2000 -o kimLife.hex -Intel -address-length=2 + +kimTest.hex: kimTest.bin + srec_cat kimTest.bin -binary -offset 0x2000 -o kimTest.hex -Intel -address-length=2 + +kimGFX.hex: kimGFX.bin ramfont.o + srec_cat kimGFX.bin -binary -offset 0x2000 -o kimGFX.hex -Intel -address-length=2 + +# To build a paper tape file for uploading to the KIM-1 via terminal + +kimLife.ptp: kimLife.bin + srec_cat kimLife.bin -binary -offset 0x2000 -o kimLife.ptp -MOS_Technologies + +kimGFX.ptp: kimGFX.bin + srec_cat kimGFX.bin -binary -offset 0x2000 -o kimGFX.ptp -MOS_Technologies + +kimTest.ptp: kimTest.bin + srec_cat kimTest.bin -binary -offset 0x2000 -o kimTest.ptp -MOS_Technologies + clean: @$(DEL) kimSieve.bin 2>$(NULLDEV) @$(DEL) kimHello.bin 2>$(NULLDEV) + @$(DEL) kimLife.bin 2>$(NULLDEV) + @$(DEL) kimLife.ptp 2>$(NULLDEV) + @$(DEL) kimLife.hex 2>$(NULLDEV) + @$(DEL) kimTest.bin 2>$(NULLDEV) + @$(DEL) kimTest.ptp 2>$(NULLDEV) + @$(DEL) kimTest.hex 2>$(NULLDEV) + @$(DEL) kimGFX.bin 2>$(NULLDEV) + @$(DEL) kimGFX.ptp 2>$(NULLDEV) + @$(DEL) kimGFX.hex 2>$(NULLDEV) + @$(DEL) kimgfx.lbl 2>$(NULLDEV) + @$(DEL) kimGFX.lst 2>$(NULLDEV) + @$(DEL) subs.o 2>$(NULLDEV) + @$(DEL) ramfont.o 2>$(NULLDEV) + + diff --git a/samples/kim1/font.rom b/samples/kim1/font.rom new file mode 100644 index 000000000..e69de29bb diff --git a/samples/kim1/kimGFX.c b/samples/kim1/kimGFX.c new file mode 100644 index 000000000..45daafa1e --- /dev/null +++ b/samples/kim1/kimGFX.c @@ -0,0 +1,290 @@ +// -------------------------------------------------------------------------- +// Simple Graphics Test for KIM-1 with MTU Visible Memory Board +// +// Assumes the MTU Visible Memory Board mapped at 0xA000 for 8K of video RAM +// +// davepl@davepl.com +// -------------------------------------------------------------------------- + +#include // For printf +#include // For rand, srand +#include // For memcpy +#include + +typedef unsigned char byte; + +extern void ClearScreen(void); // In subs.asm +extern void ScrollScreen(void); +extern void DrawCircle(void); +extern void SetPixel(void); +extern void ClearPixel(void); +extern void DrawChar(void); +extern void Demo(void); +extern void __fastcall__ Delay(byte loops); +extern void __fastcall__ DrawLine(byte bSet); +extern byte __fastcall__ AscToPet(byte in); +extern byte __fastcall__ PetToAsc(byte in); +extern byte __fastcall__ ReverseBits(byte in); +extern void __fastcall__ CharOut(byte asci_char); +extern byte __fastcall__ getch(); +extern unsigned char font8x8_basic[256][8]; + +extern int x1cord; +extern int y1cord; +extern int x2cord; +extern int y2cord; +extern int cursorX; +extern int cursorY; + +// If in zeropage: +// +// #pragma zpsym("x1cord") +// #pragma zpsym("x2cord") +// #pragma zpsym("y1cord") +// #pragma zpsym("y2cord") + +// Screen memory is placed at A000-BFFF, 320x200 pixels, mapped right to left within each horizontal byte + +byte * screen = (byte *) 0xA000; + +// Cursor position + +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 200 +#define CHARWIDTH 8 +#define CHARHEIGHT 8 +#define BYTESPERROW (SCREEN_WIDTH / 8) +#define BYTESPERCHARROW (BYTESPERROW * 8) +#define CHARSPERROW (SCREEN_WIDTH / CHARWIDTH) +#define ROWSPERCOLUMN (SCREEN_HEIGHT / CHARHEIGHT) + +// SETPIXEL +// +// 0 <= x < 320 +// 0 <= y < 200 +// +// Draws a pixel on the screen in white or black at pixel pos x, y + +void SETPIXEL(int x, int y, byte b) +{ + x1cord = x; + y1cord = y; + + if (b) + SetPixel(); + else + ClearPixel(); +} + +// DRAWPIXEL +// +// 0 <= x < 320 +// 0 <= y < 200 +// +// Turns on a screen pixel at pixel pos x,y + +void DRAWPIXEL(int x, int y) +{ + x1cord = x; + y1cord = y; + SetPixel(); +} + +int c; + +void DrawText(char * psz) +{ + while (*psz) + { + while (cursorX >= CHARSPERROW) + { + cursorX -= CHARSPERROW; + cursorY += 1; + } + + // If we've gone off the bottom of the screen, we scroll the screen and back up to the last line again + + if (cursorY >= ROWSPERCOLUMN) + { + cursorY = ROWSPERCOLUMN - 1; + ScrollScreen(); + } + + // If we output a newline we advanced the cursor down one line and reset it to the left + + if (*psz == 0x0A) + { + cursorX = 0; + cursorY++; + psz++; + } + else + { + c = *psz; + + __asm__ ("ldx %v", cursorX); + __asm__ ("ldy %v", cursorY); + __asm__ ("lda %v", c); + DrawChar(); + cursorX++; + psz++; + } + } +} + +void DrawTextAt(int x, int y, char * psz) +{ + cursorX = x; + cursorY = y; + DrawText(psz); +} + +// Something like Bresenham's algorithm for drawing a line +/* +void DrawLine(int x0, int y0, int x1, int y1, byte val) +{ + int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + int err = (dx > dy ? dx : -dy) / 2, e2; + + while (1) + { + SETPIXEL(x0, y0, val); + + if (x0 == x1 && y0 == y1) + break; + + e2 = err; + + if (e2 > -dx) + { + err -= dy; + x0 += sx; + } + if (e2 < dy) + { + err += dx; + y0 += sy; + } + } +} +*/ + +// DrawCircle +// +// Draw a circle without sin, cos, or floating point! + +void DrawCircleC(int x0, int y0, int radius, byte) +{ + x1cord = x0; + y1cord = y0; + y2cord = radius; + DrawCircle(); +} + +void DrawLineC(int x1, int y1, int x2, int y2, byte bSet) +{ + x1cord = x1; + y1cord = y1; + x2cord = x2; + y2cord = y2; + DrawLine(bSet); +} + +// MirrorFont +// +// RAM font is backwards left-right relative to the way memory is laid out on the KIM-1, so we swap all the +// bytes in place by reversing the order of the bits in every byte + +void MirrorFont() +{ + int c; + byte * pb = (byte *) font8x8_basic; + + for (c = 0; c < 128 * 8; c++) + pb[c] = ReverseBits(pb[c]); +} + +// DrawScreenMoire +// +// Draws a moire pattern on the screen without clearing it first + +void DrawMoire(int left, int top, int right, int bottom, byte pixel) +{ + int x, y; + + for (x = left; x < right; x += 6) + DrawLineC(x, top, right - x + left, bottom, pixel); + + for (y = top; y < bottom; y += 6) + DrawLineC(left, y, right, bottom - y + top, pixel); +} + +void DrawScreenMoire(int left, int top, int right, int bottom) +{ + int x, y; + + DrawLineC(left, top, right, top, 1); + DrawLineC(left, bottom, right, bottom, 1); + DrawLineC(left, top, left, bottom, 1); + DrawLineC(right, top, right, bottom, 1); + + left++; top++; right--; bottom--; + + for (x = left; x < right; x += 6) + DrawLineC(x, top, right - x + left, bottom, 1); + for (y = top; y < bottom; y += 6) + DrawLineC(left, y, right, bottom - y + top, 1); + for (x = left; x < right; x += 6) + DrawLineC(x, top, right - x + left, bottom, 0); + for (y = top; y < bottom; y += 6) + DrawLineC(left, y, right, bottom - y + top, 0); + +} + +int main (void) +{ + + int i; + int c = 0; + + Demo(); + + CharOut('R'); + CharOut('E'); + CharOut('A'); + CharOut('D'); + CharOut('Y'); + CharOut('.'); + CharOut('\n'); + + + while(1) + { + c = toupper(getch()); + if (c != EOF) + CharOut(c); + } + + // Clear the screen memory + while(1) + { + Demo(); + DrawScreenMoire(0,30, 319, 199); + Delay(10); + + Demo(); + for (i = 5; i < 80; i+=5) + { + DrawCircleC(SCREEN_WIDTH/2, SCREEN_HEIGHT/2 + 20, i, 1); + DrawCircleC(SCREEN_WIDTH/4, SCREEN_HEIGHT/2 + 20, i, 1); + DrawCircleC(SCREEN_WIDTH*3/4, SCREEN_HEIGHT/2 + 20, i, 1); + } + + Delay(10); + + } + + printf("Done, exiting...\r\n"); + return 0; +} diff --git a/samples/kim1/kimLife.c b/samples/kim1/kimLife.c new file mode 100644 index 000000000..fb1696b9e --- /dev/null +++ b/samples/kim1/kimLife.c @@ -0,0 +1,144 @@ +// -------------------------------------------------------------------------- +// Conway's Game of Life for KIM-1 +// +// Assumes the MTU Visible Memory Board mapped at 0x8000 for 8K of video RAM +// +// Dave Plummer on a rainy Thursday +// +// davepl@davepl.com +// -------------------------------------------------------------------------- + +#include // For printf +#include // For rand, srand +#include // For memcpy + +typedef unsigned char byte; + +// World size + +#define WIDTH 320 +#define HEIGHT 200 +#define NUMBITS 64000 +#define NUMBYTES 8000 +#define DENSITY 50 + +// Screen memory is placed at 8000, our world copy at A000, and they use the same layout so +// that we can memcpy from one to the other without translating + +byte * world = (byte *) 0x8000; +byte * new_world = (byte *) 0xA000; + +// BITARRAY +// +// Access individual bits in a block of memory + +// Access to the screen bitmap + +byte GETBIT(byte *p, int n) +{ + return (p[n >> 3] & (1 << (n & 7))) ? 1 : 0; +} + +void SETBIT(byte *p, int n) +{ + p[n >> 3] |= (1 << (n & 7)); +} + +void CLRBIT(byte *p, int n) +{ + p[n >> 3] &= ~(1 << (n & 7)); +} + +void SETPIXEL(byte * p, int x, int y, byte b) +{ + if (b) + SETBIT(p, y * WIDTH + x); + else + CLRBIT(p, y * WIDTH + x); +} + +byte GETPIXEL(byte *p, int x, int y) +{ + return GETBIT(p, y * WIDTH + x); +} + +// RandomFillWorld +// +// Populates the initial world with random cells + +void RandomFillWorld() +{ + int x, y; + + // I need a better way to see the RNG or it'll be the same game every time! + srand(0); + for (x = 0; x < WIDTH; x++) + { + for (y = 0; y < HEIGHT; y++) + { + byte b = ((rand() % 100) < DENSITY) ? 1 : 0; + SETPIXEL(world, x, y, b); + } + } +} + +// CountNeighbors +// +// Count the number of live cells around the given spot, excluding the actual spot specified + +int CountNeighbors(int x, int y) +{ + int i, j, nx, ny, count = 0; + + for (j = -1; j <= 1; j++) + { + for (i = -1; i <= 1; i++) + { + if (i != 0 || j != 0) + { + nx = (x + i + WIDTH) % WIDTH; + ny = (y + j + HEIGHT) % HEIGHT; + count += GETPIXEL(world, nx, ny) ? 1 : 0; + } + } + } + return count; +} + +// UpdateWorld +// +// Applies the rules of Conway's Game of Life to the cells + +void UpdateWorld() +{ + int x, y; + + for (y = 0; y < HEIGHT; y++) + { + for (x = 0; x < WIDTH; x++) + { + int neighbors = CountNeighbors(x, y); + if (GETPIXEL(world, x, y)) + SETPIXEL(new_world, x, y, (neighbors == 2 || neighbors == 3)); + else + SETPIXEL(new_world, x, y, (neighbors == 3)); + } + } +} + +int main (void) +{ + printf("\r\nStarting Conway's Game of Life: Randomizing World...\r\n"); + RandomFillWorld(); + printf("World Ready, Running!\r\n"); + + for (;;) + { + UpdateWorld(); + printf("["); + memcpy(world, new_world, NUMBYTES); + printf("]"); + } + + return 0; +} diff --git a/samples/kim1/kimTest.c b/samples/kim1/kimTest.c new file mode 100644 index 000000000..273aeb584 --- /dev/null +++ b/samples/kim1/kimTest.c @@ -0,0 +1,262 @@ +// -------------------------------------------------------------------------- +// Diagnostics Test for KIM-1 +// +// Dave Plummer +// davepl@davepl.com +// +// Memory test examples by Michael Barr +// +// -------------------------------------------------------------------------- + +#include // For printf +#include // For rand, srand +#include // For memcpy + +typedef unsigned char byte; + +// RepeatChar +// +// Outputs a given character N times + +void RepeatChar(char c, size_t count) +{ + while (count--) + putc(c, stdout); +} + +/********************************************************************** + * + * Function: memTestDataBus() + * + * Description: Test the data bus wiring in a memory region by + * performing a walking 1's test at a fixed address + * within that region. The address (and hence the + * memory region) is selected by the caller. + * + * Returns: 0 if the test succeeds. + * A non-zero result is the first pattern that failed. + * + **********************************************************************/ + +byte memTestDataBus(volatile byte * address) +{ + byte pattern; + + // Perform a walking 1's test at the given address. + + for (pattern = 1; pattern != 0; pattern <<= 1) + { + // Write the test pattern. + *address = pattern; + + // Read it back and check it + if (*address != pattern) + { + printf("\r\nmemTestDataBus: FAILED at %04x with pattern %02x\r\n", address, pattern); + return (pattern); + } + } + + return (0); +} + +/********************************************************************** + * + * Function: memTestAddressBus() + * + * Description: Test the address bus wiring in a memory region by + * performing a walking 1's test on the relevant bits + * of the address and checking for aliasing. This test + * will find single-bit address failures such as stuck + * -high, stuck-low, and shorted pins. The base address + * and size of the region are selected by the caller. + * + * Notes: For best results, the selected base address should + * have enough LSB 0's to guarantee single address bit + * changes. For example, to test a 64-Kbyte region, + * select a base address on a 64-Kbyte boundary. Also, + * select the region size as a power-of-two--if at all + * possible. + * + * Returns: NULL if the test succeeds. + * A non-zero result is the first address at which an + * aliasing problem was uncovered. By examining the + * contents of memory, it may be possible to gather + * additional information about the problem. + * + **********************************************************************/ + +byte * memTestAddressBus(volatile byte * baseAddress, unsigned long nBytes) +{ + unsigned long addressMask = (nBytes/sizeof(byte) - 1); + unsigned long offset; + unsigned long testOffset; + + byte pattern = (byte) 0xAAAAAAAA; + byte antipattern = (byte) 0x55555555; + + + //Write the default pattern at each of the power-of-two offsets. + + for (offset = 1; (offset & addressMask) != 0; offset <<= 1) + { + baseAddress[offset] = pattern; + } + + // Check for address bits stuck high. + + testOffset = 0; + baseAddress[testOffset] = antipattern; + + for (offset = 1; (offset & addressMask) != 0; offset <<= 1) + { + if (baseAddress[offset] != pattern) + { + printf("\r\nmemTestAddressBus: FAILED at %04x with pattern %02x\r\n", baseAddress+offset, pattern); + return ((byte *) &baseAddress[offset]); + } + if (offset % 1024 == 0) + printf("."); + } + + baseAddress[testOffset] = pattern; + + + // Check for address bits stuck low or shorted. + + for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1) + { + baseAddress[testOffset] = antipattern; + + if (baseAddress[0] != pattern) + { + return ((byte *) &baseAddress[testOffset]); + } + + for (offset = 1; (offset & addressMask) != 0; offset <<= 1) + { + if ((baseAddress[offset] != pattern) && (offset != testOffset)) + { + printf("\r\nmemTestAddressBus: FAILED at %04x with pattern %02x\r\n", baseAddress+offset, pattern); + return ((byte *) &baseAddress[testOffset]); + } + } + baseAddress[testOffset] = pattern; + } + return (NULL); +} + +/********************************************************************** + * + * Function: memTestDevice() + * + * Description: Test the integrity of a physical memory device by + * performing an increment/decrement test over the + * entire region. In the process every storage bit + * in the device is tested as a zero and a one. The + * base address and the size of the region are + * selected by the caller. + * + * Returns: NULL if the test succeeds. + * + * A non-zero result is the first address at which an + * incorrect value was read back. By examining the + * contents of memory, it may be possible to gather + * additional information about the problem. + * + **********************************************************************/ + +byte * memTestDevice(volatile byte * baseAddress, unsigned long nBytes) +{ + unsigned long offset; + unsigned long nWords = nBytes / sizeof(byte); + + byte pattern; + byte antipattern; + + + // Fill memory with a known pattern. + + for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) + baseAddress[offset] = pattern; + + // Check each location and invert it for the second pass. + + for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) + { + if (offset % 1024 == 0) + printf("%04X ", (int) &baseAddress[offset]); + + if (baseAddress[offset] != pattern) + { + printf("\r\nmemTestDevice: FAILED at %04x with pattern %02x\r\n", (int) &baseAddress[offset], pattern); + return ((byte *) &baseAddress[offset]); + } + + antipattern = ~pattern; + baseAddress[offset] = antipattern; + + } + + // Check each location for the inverted pattern and zero it. + + for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) + { + if (offset % 1024 == 0) + printf("%04X ", (int) &baseAddress[offset]); + + antipattern = ~pattern; + if (baseAddress[offset] != antipattern) + { + printf("\r\nmemTestDevice: FAILED at %04x with antipattern %02x\r\n", (int) &baseAddress[offset], pattern); + return ((byte *) &baseAddress[offset]); + } + } + + return (NULL); +} + +// TestMemory +// +// Run all three memory tests + +byte TestMemory(byte * startAddress, unsigned long size) +{ + if ((memTestDataBus(startAddress) != 0) || + (memTestAddressBus(startAddress, size) != NULL) || + (memTestDevice(startAddress, size) != NULL)) + { + return (-1); + } + else + { + return (0); + } +} + +int main (void) +{ + printf("\r\nTesting KIM-1...\r\n"); + RepeatChar('-', 39); + + printf("\r\nTesting RIOT RAM: 1780-17BF\r\n"); + if (TestMemory((byte *)0x1780, 0x17BF - 0x1780)) + return 0; + + printf("\r\nTesting RIOT RAM: 17C0-17E6\r\n"); + if (TestMemory((byte *)0x17C0, 0x17E6 - 0x17C0)) + return 0; + + printf("\r\nTesting Memory: 0400-13FF\r\n"); + if (TestMemory((byte *)0x0400, 0x13FF - 0x0400)) + return 0; + + printf("\r\nTesting Memory: 4000-DFFF\r\n"); + if (TestMemory((byte *)0x4000, 0xDFFF - 0x4000)) + return 0; + + printf("\r\nPASS!\r\n"); + return 1; +} + + diff --git a/samples/kim1/ramfont.asm b/samples/kim1/ramfont.asm new file mode 100644 index 000000000..ac0b2c9cd --- /dev/null +++ b/samples/kim1/ramfont.asm @@ -0,0 +1,272 @@ +;----------------------------------------------------------------------------------- +; KIMGFX: Simple pixel graphics for the MOS/Commodore KIM-1 +;----------------------------------------------------------------------------------- +; (c) Plummer's Software Ltd, 04/25/2023 Created +; David Plummer +;----------------------------------------------------------------------------------- +; +; File: ramfont.s +; Magnetic OCR (check number style) Font data +; +;----------------------------------------------------------------------------------- + +.segment "CODE" +.export _font8x8_basic + +_font8x8_basic: + .byte $1c, $22, $4a, $56, $4c, $20, $1e, $00 ; PETSCII code 0 + .byte $3c, $24, $24, $7e, $62, $62, $62, $00 ; PETSCII code 1 + .byte $78, $44, $44, $7c, $62, $62, $7e, $00 ; PETSCII code 2 + .byte $7e, $42, $40, $60, $60, $62, $7e, $00 ; PETSCII code 3 + .byte $7c, $46, $42, $62, $62, $66, $7c, $00 ; PETSCII code 4 + .byte $7e, $40, $40, $7c, $60, $60, $7e, $00 ; PETSCII code 5 + .byte $7e, $40, $40, $7e, $60, $60, $60, $00 ; PETSCII code 6 + .byte $7e, $42, $40, $6e, $62, $62, $7e, $00 ; PETSCII code 7 + .byte $42, $42, $42, $7e, $62, $62, $62, $00 ; PETSCII code 8 + .byte $08, $08, $08, $0c, $0c, $0c, $0c, $00 ; PETSCII code 9 + .byte $04, $04, $04, $06, $06, $46, $7e, $00 ; PETSCII code 10 + .byte $42, $44, $48, $7c, $62, $62, $62, $00 ; PETSCII code 11 + .byte $40, $40, $40, $60, $60, $60, $7e, $00 ; PETSCII code 12 + .byte $7e, $4a, $4a, $6a, $6a, $6a, $6a, $00 ; PETSCII code 13 + .byte $7e, $42, $42, $62, $62, $62, $62, $00 ; PETSCII code 14 + .byte $7e, $46, $42, $42, $42, $42, $7e, $00 ; PETSCII code 15 + .byte $7e, $42, $42, $7e, $60, $60, $60, $00 ; PETSCII code 16 + .byte $7e, $42, $42, $42, $4a, $4e, $7e, $00 ; PETSCII code 17 + .byte $7c, $44, $44, $7c, $62, $62, $62, $00 ; PETSCII code 18 + .byte $7e, $42, $40, $7e, $06, $46, $7e, $00 ; PETSCII code 19 + .byte $3e, $10, $10, $18, $18, $18, $18, $00 ; PETSCII code 20 + .byte $42, $42, $42, $62, $62, $62, $7e, $00 ; PETSCII code 21 + .byte $62, $62, $62, $66, $24, $24, $3c, $00 ; PETSCII code 22 + .byte $4a, $4a, $4a, $6a, $6a, $6a, $7e, $00 ; PETSCII code 23 + .byte $42, $42, $66, $18, $66, $62, $62, $00 ; PETSCII code 24 + .byte $22, $22, $22, $3e, $18, $18, $18, $00 ; PETSCII code 25 + .byte $7e, $42, $06, $18, $60, $62, $7e, $00 ; PETSCII code 26 + .byte $3c, $20, $20, $20, $20, $20, $3c, $00 ; PETSCII code 27 + .byte $00, $40, $20, $10, $08, $04, $02, $00 ; PETSCII code 28 + .byte $3c, $04, $04, $04, $04, $04, $3c, $00 ; PETSCII code 29 + .byte $00, $08, $1c, $2a, $08, $08, $14, $14 ; PETSCII code 30 + .byte $00, $00, $10, $20, $7f, $20, $10, $00 ; PETSCII code 31 + .byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 32 + .byte $08, $08, $08, $0c, $0c, $00, $0c, $00 ; PETSCII code 33 + .byte $6c, $24, $6c, $00, $00, $00, $00, $00 ; PETSCII code 34 + .byte $24, $24, $7e, $24, $7e, $24, $24, $00 ; PETSCII code 35 + .byte $08, $3e, $20, $3e, $06, $3e, $08, $00 ; PETSCII code 36 + .byte $00, $62, $64, $08, $10, $26, $46, $00 ; PETSCII code 37 + .byte $3c, $20, $24, $7e, $64, $64, $7c, $00 ; PETSCII code 38 + .byte $1c, $18, $10, $00, $00, $00, $00, $00 ; PETSCII code 39 + .byte $04, $08, $10, $10, $10, $08, $04, $00 ; PETSCII code 40 + .byte $20, $10, $08, $08, $08, $10, $20, $00 ; PETSCII code 41 + .byte $08, $2a, $1c, $3e, $1c, $2a, $08, $00 ; PETSCII code 42 + .byte $00, $08, $08, $3e, $08, $08, $00, $00 ; PETSCII code 43 + .byte $00, $00, $00, $00, $00, $18, $18, $08 ; PETSCII code 44 + .byte $00, $00, $00, $7e, $00, $00, $00, $00 ; PETSCII code 45 + .byte $00, $00, $00, $00, $00, $18, $18, $00 ; PETSCII code 46 + .byte $00, $02, $04, $08, $10, $20, $40, $00 ; PETSCII code 47 + .byte $7e, $62, $52, $4a, $46, $46, $7e, $00 ; PETSCII code 48 + .byte $18, $08, $08, $18, $18, $1a, $3e, $00 ; PETSCII code 49 + .byte $7e, $42, $02, $7e, $60, $60, $7e, $00 ; PETSCII code 50 + .byte $7c, $44, $04, $1e, $06, $46, $7e, $00 ; PETSCII code 51 + .byte $44, $44, $44, $44, $7e, $0c, $0c, $00 ; PETSCII code 52 + .byte $7e, $40, $7e, $06, $06, $46, $7e, $00 ; PETSCII code 53 + .byte $7e, $42, $40, $7e, $46, $46, $7e, $00 ; PETSCII code 54 + .byte $7e, $02, $02, $06, $06, $06, $06, $00 ; PETSCII code 55 + .byte $3c, $24, $24, $7e, $46, $46, $7e, $00 ; PETSCII code 56 + .byte $7e, $42, $42, $7e, $06, $06, $06, $00 ; PETSCII code 57 + .byte $00, $00, $18, $00, $00, $18, $00, $00 ; PETSCII code 58 + .byte $00, $00, $18, $00, $00, $18, $18, $08 ; PETSCII code 59 + .byte $0e, $18, $30, $60, $30, $18, $0e, $00 ; PETSCII code 60 + .byte $00, $00, $7e, $00, $7e, $00, $00, $00 ; PETSCII code 61 + .byte $70, $18, $0c, $06, $0c, $18, $70, $00 ; PETSCII code 62 + .byte $7e, $02, $02, $7e, $60, $00, $60, $00 ; PETSCII code 63 + .byte $00, $00, $00, $00, $ff, $00, $00, $00 ; PETSCII code 64 + .byte $08, $1c, $3e, $7f, $7f, $1c, $3e, $00 ; PETSCII code 65 + .byte $10, $10, $10, $10, $10, $10, $10, $10 ; PETSCII code 66 + .byte $00, $00, $00, $ff, $00, $00, $00, $00 ; PETSCII code 67 + .byte $00, $00, $ff, $00, $00, $00, $00, $00 ; PETSCII code 68 + .byte $00, $ff, $00, $00, $00, $00, $00, $00 ; PETSCII code 69 + .byte $00, $00, $00, $00, $00, $ff, $00, $00 ; PETSCII code 70 + .byte $20, $20, $20, $20, $20, $20, $20, $20 ; PETSCII code 71 + .byte $04, $04, $04, $04, $04, $04, $04, $04 ; PETSCII code 72 + .byte $00, $00, $00, $00, $e0, $10, $08, $08 ; PETSCII code 73 + .byte $08, $08, $08, $04, $03, $00, $00, $00 ; PETSCII code 74 + .byte $08, $08, $08, $10, $e0, $00, $00, $00 ; PETSCII code 75 + .byte $80, $80, $80, $80, $80, $80, $80, $ff ; PETSCII code 76 + .byte $80, $40, $20, $10, $08, $04, $02, $01 ; PETSCII code 77 + .byte $01, $02, $04, $08, $10, $20, $40, $80 ; PETSCII code 78 + .byte $ff, $80, $80, $80, $80, $80, $80, $80 ; PETSCII code 79 + .byte $ff, $01, $01, $01, $01, $01, $01, $01 ; PETSCII code 80 + .byte $00, $3c, $7e, $7e, $7e, $7e, $3c, $00 ; PETSCII code 81 + .byte $00, $00, $00, $00, $00, $00, $ff, $00 ; PETSCII code 82 + .byte $36, $7f, $7f, $7f, $3e, $1c, $08, $00 ; PETSCII code 83 + .byte $40, $40, $40, $40, $40, $40, $40, $40 ; PETSCII code 84 + .byte $00, $00, $00, $00, $03, $04, $08, $08 ; PETSCII code 85 + .byte $81, $42, $24, $18, $18, $24, $42, $81 ; PETSCII code 86 + .byte $00, $3c, $42, $42, $42, $42, $3c, $00 ; PETSCII code 87 + .byte $08, $1c, $2a, $77, $2a, $08, $08, $00 ; PETSCII code 88 + .byte $02, $02, $02, $02, $02, $02, $02, $02 ; PETSCII code 89 + .byte $08, $1c, $3e, $7f, $3e, $1c, $08, $00 ; PETSCII code 90 + .byte $08, $08, $08, $08, $ff, $08, $08, $08 ; PETSCII code 91 + .byte $a0, $50, $a0, $50, $a0, $50, $a0, $50 ; PETSCII code 92 + .byte $08, $08, $08, $08, $08, $08, $08, $08 ; PETSCII code 93 + .byte $00, $00, $01, $3e, $54, $14, $14, $00 ; PETSCII code 94 + .byte $ff, $7f, $3f, $1f, $0f, $07, $03, $01 ; PETSCII code 95 + .byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 96 + .byte $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0 ; PETSCII code 97 + .byte $00, $00, $00, $00, $ff, $ff, $ff, $ff ; PETSCII code 98 + .byte $ff, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 99 + .byte $00, $00, $00, $00, $00, $00, $00, $ff ; PETSCII code 100 + .byte $80, $80, $80, $80, $80, $80, $80, $80 ; PETSCII code 101 + .byte $aa, $55, $aa, $55, $aa, $55, $aa, $55 ; PETSCII code 102 + .byte $01, $01, $01, $01, $01, $01, $01, $01 ; PETSCII code 103 + .byte $00, $00, $00, $00, $aa, $55, $aa, $55 ; PETSCII code 104 + .byte $ff, $fe, $fc, $f8, $f0, $e0, $c0, $80 ; PETSCII code 105 + .byte $03, $03, $03, $03, $03, $03, $03, $03 ; PETSCII code 106 + .byte $08, $08, $08, $08, $0f, $08, $08, $08 ; PETSCII code 107 + .byte $00, $00, $00, $00, $0f, $0f, $0f, $0f ; PETSCII code 108 + .byte $08, $08, $08, $08, $0f, $00, $00, $00 ; PETSCII code 109 + .byte $00, $00, $00, $00, $f8, $08, $08, $08 ; PETSCII code 110 + .byte $00, $00, $00, $00, $00, $00, $ff, $ff ; PETSCII code 111 + .byte $00, $00, $00, $00, $0f, $08, $08, $08 ; PETSCII code 112 + .byte $08, $08, $08, $08, $ff, $00, $00, $00 ; PETSCII code 113 + .byte $00, $00, $00, $00, $ff, $08, $08, $08 ; PETSCII code 114 + .byte $08, $08, $08, $08, $f8, $08, $08, $08 ; PETSCII code 115 + .byte $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0 ; PETSCII code 116 + .byte $e0, $e0, $e0, $e0, $e0, $e0, $e0, $e0 ; PETSCII code 117 + .byte $07, $07, $07, $07, $07, $07, $07, $07 ; PETSCII code 118 + .byte $ff, $ff, $00, $00, $00, $00, $00, $00 ; PETSCII code 119 + .byte $ff, $ff, $ff, $00, $00, $00, $00, $00 ; PETSCII code 120 + .byte $00, $00, $00, $00, $00, $ff, $ff, $ff ; PETSCII code 121 + .byte $01, $01, $01, $01, $01, $01, $01, $ff ; PETSCII code 122 + .byte $00, $00, $00, $00, $f0, $f0, $f0, $f0 ; PETSCII code 123 + .byte $0f, $0f, $0f, $0f, $00, $00, $00, $00 ; PETSCII code 124 + .byte $08, $08, $08, $08, $f8, $00, $00, $00 ; PETSCII code 125 + .byte $f0, $f0, $f0, $f0, $00, $00, $00, $00 ; PETSCII code 126 + .byte $f0, $f0, $f0, $f0, $0f, $0f, $0f, $0f ; PETSCII code 127 + .byte $1c, $22, $4a, $56, $4c, $20, $1e, $00 ; PETSCII code 128 + .byte $00, $00, $3c, $04, $7c, $64, $7c, $00 ; PETSCII code 129 + .byte $40, $40, $7e, $42, $62, $62, $7e, $00 ; PETSCII code 130 + .byte $00, $00, $7e, $42, $60, $62, $7e, $00 ; PETSCII code 131 + .byte $02, $02, $7e, $42, $62, $62, $7e, $00 ; PETSCII code 132 + .byte $00, $00, $7e, $42, $7e, $60, $7e, $00 ; PETSCII code 133 + .byte $1e, $12, $10, $7c, $18, $18, $18, $00 ; PETSCII code 134 + .byte $00, $00, $7e, $42, $62, $7e, $02, $7e ; PETSCII code 135 + .byte $40, $40, $7e, $42, $62, $62, $62, $00 ; PETSCII code 136 + .byte $18, $00, $10, $10, $18, $18, $18, $00 ; PETSCII code 137 + .byte $0c, $00, $08, $0c, $0c, $0c, $44, $7c ; PETSCII code 138 + .byte $40, $40, $44, $48, $78, $64, $64, $00 ; PETSCII code 139 + .byte $10, $10, $10, $10, $18, $18, $18, $00 ; PETSCII code 140 + .byte $00, $00, $7f, $49, $6d, $6d, $6d, $00 ; PETSCII code 141 + .byte $00, $00, $7e, $42, $62, $62, $62, $00 ; PETSCII code 142 + .byte $00, $00, $7e, $42, $62, $62, $7e, $00 ; PETSCII code 143 + .byte $00, $00, $7e, $42, $62, $7e, $40, $40 ; PETSCII code 144 + .byte $00, $00, $7e, $42, $46, $7e, $02, $02 ; PETSCII code 145 + .byte $00, $00, $7e, $40, $60, $60, $60, $00 ; PETSCII code 146 + .byte $00, $00, $7e, $40, $7e, $06, $7e, $00 ; PETSCII code 147 + .byte $10, $10, $7c, $10, $18, $18, $18, $00 ; PETSCII code 148 + .byte $00, $00, $42, $42, $62, $62, $7e, $00 ; PETSCII code 149 + .byte $00, $00, $62, $62, $66, $24, $3c, $00 ; PETSCII code 150 + .byte $00, $00, $49, $49, $6d, $6d, $7f, $00 ; PETSCII code 151 + .byte $00, $00, $42, $42, $3c, $62, $62, $00 ; PETSCII code 152 + .byte $00, $00, $62, $62, $42, $7e, $02, $7e ; PETSCII code 153 + .byte $00, $00, $7e, $06, $18, $60, $7e, $00 ; PETSCII code 154 + .byte $3c, $20, $20, $20, $20, $20, $3c, $00 ; PETSCII code 155 + .byte $00, $40, $20, $10, $08, $04, $02, $00 ; PETSCII code 156 + .byte $3c, $04, $04, $04, $04, $04, $3c, $00 ; PETSCII code 157 + .byte $00, $08, $1c, $2a, $08, $08, $14, $14 ; PETSCII code 158 + .byte $00, $00, $10, $20, $7f, $20, $10, $00 ; PETSCII code 159 + .byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 160 + .byte $08, $08, $08, $0c, $0c, $00, $0c, $00 ; PETSCII code 161 + .byte $6c, $24, $6c, $00, $00, $00, $00, $00 ; PETSCII code 162 + .byte $24, $24, $7e, $24, $7e, $24, $24, $00 ; PETSCII code 163 + .byte $08, $3e, $20, $3e, $06, $3e, $08, $00 ; PETSCII code 164 + .byte $00, $62, $64, $08, $10, $26, $46, $00 ; PETSCII code 165 + .byte $3c, $20, $24, $7e, $64, $64, $7c, $00 ; PETSCII code 166 + .byte $1c, $18, $10, $00, $00, $00, $00, $00 ; PETSCII code 167 + .byte $04, $08, $10, $10, $10, $08, $04, $00 ; PETSCII code 168 + .byte $20, $10, $08, $08, $08, $10, $20, $00 ; PETSCII code 169 + .byte $08, $2a, $1c, $3e, $1c, $2a, $08, $00 ; PETSCII code 170 + .byte $00, $08, $08, $3e, $08, $08, $00, $00 ; PETSCII code 171 + .byte $00, $00, $00, $00, $00, $18, $18, $08 ; PETSCII code 172 + .byte $00, $00, $00, $7e, $00, $00, $00, $00 ; PETSCII code 173 + .byte $00, $00, $00, $00, $00, $18, $18, $00 ; PETSCII code 174 + .byte $00, $02, $04, $08, $10, $20, $40, $00 ; PETSCII code 175 + .byte $7e, $62, $52, $4a, $46, $46, $7e, $00 ; PETSCII code 176 + .byte $38, $08, $08, $18, $18, $1a, $3e, $00 ; PETSCII code 177 + .byte $7e, $42, $02, $7e, $60, $60, $7e, $00 ; PETSCII code 178 + .byte $7c, $44, $04, $1e, $06, $46, $7e, $00 ; PETSCII code 179 + .byte $44, $44, $44, $44, $7e, $0c, $0c, $00 ; PETSCII code 180 + .byte $7e, $40, $7e, $06, $06, $46, $7e, $00 ; PETSCII code 181 + .byte $7e, $42, $40, $7e, $46, $46, $7e, $00 ; PETSCII code 182 + .byte $7e, $02, $02, $06, $06, $06, $06, $00 ; PETSCII code 183 + .byte $3c, $24, $24, $7e, $46, $46, $7e, $00 ; PETSCII code 184 + .byte $7e, $42, $42, $7e, $06, $06, $06, $00 ; PETSCII code 185 + .byte $00, $00, $18, $00, $00, $18, $00, $00 ; PETSCII code 186 + .byte $00, $00, $18, $00, $00, $18, $18, $08 ; PETSCII code 187 + .byte $0e, $18, $30, $60, $30, $18, $0e, $00 ; PETSCII code 188 + .byte $00, $00, $7e, $00, $7e, $00, $00, $00 ; PETSCII code 189 + .byte $70, $18, $0c, $06, $0c, $18, $70, $00 ; PETSCII code 190 + .byte $7e, $02, $02, $7e, $60, $00, $60, $00 ; PETSCII code 191 + .byte $00, $00, $00, $00, $ff, $00, $00, $00 ; PETSCII code 192 + .byte $3c, $24, $24, $7e, $62, $62, $62, $00 ; PETSCII code 193 + .byte $78, $44, $44, $7c, $62, $62, $7e, $00 ; PETSCII code 194 + .byte $7e, $42, $40, $60, $60, $62, $7e, $00 ; PETSCII code 195 + .byte $7c, $46, $42, $62, $62, $66, $7c, $00 ; PETSCII code 196 + .byte $7e, $40, $40, $78, $60, $60, $7e, $00 ; PETSCII code 197 + .byte $7e, $40, $40, $7e, $60, $60, $60, $00 ; PETSCII code 198 + .byte $7e, $42, $40, $6e, $62, $62, $7e, $00 ; PETSCII code 199 + .byte $42, $42, $42, $7e, $62, $62, $62, $00 ; PETSCII code 200 + .byte $08, $08, $08, $0c, $0c, $0c, $0c, $00 ; PETSCII code 201 + .byte $04, $04, $04, $06, $06, $46, $7e, $00 ; PETSCII code 202 + .byte $42, $44, $48, $7c, $62, $62, $62, $00 ; PETSCII code 203 + .byte $40, $40, $40, $60, $60, $60, $7e, $00 ; PETSCII code 204 + .byte $7e, $4a, $4a, $6a, $6a, $6a, $6a, $00 ; PETSCII code 205 + .byte $7e, $42, $42, $62, $62, $62, $62, $00 ; PETSCII code 206 + .byte $7e, $46, $42, $42, $42, $42, $7e, $00 ; PETSCII code 207 + .byte $7e, $42, $42, $7e, $60, $60, $60, $00 ; PETSCII code 208 + .byte $7e, $42, $42, $42, $4a, $4e, $7e, $00 ; PETSCII code 209 + .byte $7c, $44, $44, $7c, $62, $62, $62, $00 ; PETSCII code 210 + .byte $7e, $42, $40, $7e, $06, $46, $7e, $00 ; PETSCII code 211 + .byte $3e, $10, $10, $18, $18, $18, $18, $00 ; PETSCII code 212 + .byte $42, $42, $42, $62, $62, $62, $7e, $00 ; PETSCII code 213 + .byte $62, $62, $62, $66, $24, $24, $3c, $00 ; PETSCII code 214 + .byte $4a, $4a, $4a, $6a, $6a, $6a, $7e, $00 ; PETSCII code 215 + .byte $42, $42, $66, $3c, $66, $62, $62, $00 ; PETSCII code 216 + .byte $22, $22, $22, $3e, $18, $18, $18, $00 ; PETSCII code 217 + .byte $7e, $42, $06, $18, $60, $62, $7e, $00 ; PETSCII code 218 + .byte $08, $08, $08, $08, $ff, $08, $08, $08 ; PETSCII code 219 + .byte $a0, $50, $a0, $50, $a0, $50, $a0, $50 ; PETSCII code 220 + .byte $08, $08, $08, $08, $08, $08, $08, $08 ; PETSCII code 221 + .byte $cc, $cc, $33, $33, $cc, $cc, $33, $33 ; PETSCII code 222 + .byte $cc, $66, $33, $99, $cc, $66, $33, $99 ; PETSCII code 223 + .byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 224 + .byte $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0 ; PETSCII code 225 + .byte $00, $00, $00, $00, $ff, $ff, $ff, $ff ; PETSCII code 226 + .byte $ff, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 227 + .byte $00, $00, $00, $00, $00, $00, $00, $ff ; PETSCII code 228 + .byte $80, $80, $80, $80, $80, $80, $80, $80 ; PETSCII code 229 + .byte $aa, $55, $aa, $55, $aa, $55, $aa, $55 ; PETSCII code 230 + .byte $01, $01, $01, $01, $01, $01, $01, $01 ; PETSCII code 231 + .byte $00, $00, $00, $00, $aa, $55, $aa, $55 ; PETSCII code 232 + .byte $99, $33, $66, $cc, $99, $33, $66, $cc ; PETSCII code 233 + .byte $03, $03, $03, $03, $03, $03, $03, $03 ; PETSCII code 234 + .byte $08, $08, $08, $08, $0f, $08, $08, $08 ; PETSCII code 235 + .byte $00, $00, $00, $00, $0f, $0f, $0f, $0f ; PETSCII code 236 + .byte $08, $08, $08, $08, $0f, $00, $00, $00 ; PETSCII code 237 + .byte $00, $00, $00, $00, $f8, $08, $08, $08 ; PETSCII code 238 + .byte $00, $00, $00, $00, $00, $00, $ff, $ff ; PETSCII code 239 + .byte $00, $00, $00, $00, $0f, $08, $08, $08 ; PETSCII code 240 + .byte $08, $08, $08, $08, $ff, $00, $00, $00 ; PETSCII code 241 + .byte $00, $00, $00, $00, $ff, $08, $08, $08 ; PETSCII code 242 + .byte $08, $08, $08, $08, $f8, $08, $08, $08 ; PETSCII code 243 + .byte $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0 ; PETSCII code 244 + .byte $e0, $e0, $e0, $e0, $e0, $e0, $e0, $e0 ; PETSCII code 245 + .byte $07, $07, $07, $07, $07, $07, $07, $07 ; PETSCII code 246 + .byte $ff, $ff, $00, $00, $00, $00, $00, $00 ; PETSCII code 247 + .byte $ff, $ff, $ff, $00, $00, $00, $00, $00 ; PETSCII code 248 + .byte $00, $00, $00, $00, $00, $ff, $ff, $ff ; PETSCII code 249 + .byte $01, $02, $44, $48, $50, $60, $40, $00 ; PETSCII code 250 + .byte $00, $00, $00, $00, $f0, $f0, $f0, $f0 ; PETSCII code 251 + .byte $0f, $0f, $0f, $0f, $00, $00, $00, $00 ; PETSCII code 252 + .byte $08, $08, $08, $08, $f8, $00, $00, $00 ; PETSCII code 253 + .byte $f0, $f0, $f0, $f0, $00, $00, $00, $00 ; PETSCII code 254 + .byte $f0, $f0, $f0, $f0, $0f, $0f, $0f, $0f ; PETSCII code 255 diff --git a/samples/kim1/subs.asm b/samples/kim1/subs.asm new file mode 100644 index 000000000..5b525749e --- /dev/null +++ b/samples/kim1/subs.asm @@ -0,0 +1,1140 @@ +;----------------------------------------------------------------------------------- +; KIMGFX: Simple pixel graphics for the MOS/Commodore KIM-1 +;----------------------------------------------------------------------------------- +; (c) Plummer's Software Ltd, 04/25/2023 Created +; David Plummer +;----------------------------------------------------------------------------------- +; +; File: subs.asm Assembly language subroutines for KIMGFX +; +;----------------------------------------------------------------------------------- + + +.SETCPU "6502" + +.export _ClearScreen +.export _ScrollScreen +.export _SetPixel +.export _ClearPixel +.export _DrawCircle +.export _DrawLine +.export _AscToPet +.export _ReverseBits +.export _DrawChar +.export _CharOut +.export _Demo +.export _Delay +.export _getch + + +.import _font8x8_basic + +; This is the assumed location of the MTU visible memory board's 8K of memory. You can adjust this +; constant to refelct other locations as needed. + +SCREEN = $A000 + +; Note that even though these constants are defined here and respected, there are still going to be +; logic assumptions in GetPixelAddress that assume a 320x200 screen. If you change these, you'll +; need to adjust GetPixelAddress to match. + +SCREEN_WIDTH = 320 +SCREEN_HEIGHT = 200 +SCREEN_BYTES = SCREEN_WIDTH * SCREEN_HEIGHT / 8 +CHARWIDTH = 8 +CHARHEIGHT = 8 +BYTESPERROW = (SCREEN_WIDTH / 8) +BYTESPERCHARROW = (BYTESPERROW * 8) +CHARSPERROW = (SCREEN_WIDTH / CHARWIDTH) +ROWSPERCOLUMN = (SCREEN_HEIGHT / CHARHEIGHT) +LASTROW = SCREEN + SCREEN_BYTES - BYTESPERCHARROW + +.segment "ZEROPAGE" + +btpt: .res 1 + +dest: +dest_lo: .res 1 +dest_hi: .res 1 + +src: +src_lo: .res 1 +src_hi: .res 1 + +adp1: +adp1_lo: .res 1 +adp1_hi: .res 1 + +adp2: +adp2_lo: .res 1 +adp2_hi: .res 1 + +scroll_src: +scroll_src_lo: .res 1 +scroll_src_hi: .res 1 + +scroll_dest: +scroll_dest_lo: .res 1 +scroll_dest_hi: .res 1 + + +.segment "DATA" + +; Arguments for graphics functions + +_x1cord: .res 2 +_x2cord: .res 2 +_y1cord: .res 2 +_y2cord: .res 2 +_cursorX: .res 1 +_cursorY: .res 1 + +; Linedraw + +dx: .res 2 +dy: .res 2 +e2: .res 2 +sx: .res 1 +sy: .res 1 +dltemp: .res 2 +pixel: .res 1 + +; DrawCircle + +xval: .res 2 ; These could move to zeropage for perf, but presume we +yval: .res 2 ; we want to minimize the amount we grow zero page use +err: .res 2 +temp: .res 2 +tempa: .res 1 +tempx: .res 1 +tempy: .res 1 +temp2: .res 2 +x0: .res 2 +y0: .res 2 + +; CharOut + +tempstr: .res 2 + +.export _x1cord ; Make sure these show up on the C side as zero page +.export _x2cord +.export _y1cord +.export _y2cord +.export _cursorX +.export _cursorY + +.segment "CODE" + +;----------------------------------------------------------------------------------- +; GetPixelAddress - Calculate the address of a pixel in the video memory +;----------------------------------------------------------------------------------- +; Based on MTU PIXADR code +;----------------------------------------------------------------------------------- +; In: _x1cord (16-bit) +; _y1cord (16-bit) +; Out: adp1 (16-bit) Address of pixel to set +;----------------------------------------------------------------------------------- + +_GetPixelAddress: + lda _x1cord ; compute bit address first + sta adp1 ; also transfer x1cord to adp1 + and #$07 ; + which is simply the low 3 bits of x + sta btpt + lda _x1cord+1 ; finish transferring x1cord to adp1 + sta adp1+1 + lsr adp1+1 ; double shift adp1 right 3 to get + ror adp1 ; int(xcord/8 ) + lsr adp1+1 + ror adp1 + lsr adp1+1 + ror adp1 + sec ; and temporary storage + lda _y1cord + sta adp2 + sta temp + lda #0 + sbc _y1cord+1 + sta adp2+1 + sta temp+1 + asl adp2 ; compute 40*(y1cord) + rol adp2+1 ; 2*(y1cord) + asl adp2 + rol adp2+1 ; 4*(y1cord) + lda adp2 ; add in temporary save of (y1cord) + clc ; to make 5*(y1cord) + adc temp + sta adp2 + lda adp2+1 + adc temp+1 + sta adp2+1 ; 5*(y1cord) + asl adp2 ; 10*(1cord) + rol adp2+1 + asl adp2 ; 20#(y1cord) + rol adp2+1 + asl adp2 ; 40*(y1cord) + rol adp2+1 + lda adp2 ; add in int(x1cord/8) computed earlier + clc + adc adp1 + sta adp1 + lda adp2+1 + adc adp1+1 + adc #>SCREEN ; add in vmorg*256 + sta adp1+1 ; final result + rts ; return + +;----------------------------------------------------------------------------------- +; Mask tables for individual pixel subroutines +; +; MSKTB1 is a table of 1 bits corresponding to bit numbers +; MSKTB2 is a table of 0 bits corresponding to bit numbers +;----------------------------------------------------------------------------------- + +msktb1: .byte $80,$40,$20,$10,$08,$04,$02,$01 +msktb2: .byte $7F,$BF,$DF,$EF,$F7,$FB,$FD,$FE + +_Delay: pha + sta temp + txa + pha + tya + pha + +@loopa: ldx #$ff +@loopx: ldy #$ff +@loopy: dey + bne @loopy + dex + bne @loopx + dec temp + bne @loopa + + pla + tay + pla + tax + pla + rts + +;----------------------------------------------------------------------------------- +; SetPixel - Set a pixel in the video memory +;----------------------------------------------------------------------------------- +; x - _x1cord (16-bit) +; y - _y1cord (16-bit) +;----------------------------------------------------------------------------------- +; Mask tables for individual pixel subroutines +;----------------------------------------------------------------------------------- + +_SetPixel: jsr _GetPixelAddress + ldy btpt ; get bit number in y + lda msktb1,y ; get a byte with that bit =1, others =0 + ldy #0 + ora (adp1),y ; combine the bit with the addressed vm + sta (adp1),y ; byte + rts + +;----------------------------------------------------------------------------------- +; ClearPixel - Clears a pixel in the video memory +;----------------------------------------------------------------------------------- +; x - _x1cord (16-bit) +; y - _y1cord (16-bit) +;----------------------------------------------------------------------------------- + +_ClearPixel: jsr _GetPixelAddress + ldy btpt ; get bit number in y + lda msktb2,y ; get a byte with that bit =0, others =1 + ldy #0 + and (adp1),y ; remove the bit from the addressed vm + sta (adp1),y ; byte + rts + +;----------------------------------------------------------------------------------- +; ClearScreen - Clears the entire video memory (and thus the screen) +;----------------------------------------------------------------------------------- + +_ClearScreen: + lda #$00 + + ldx #SCREEN + stx dest_hi + + ldy #0 +: sta (dest), y ; Loop unwound by a factor of 8, which means our iny before the branchh + iny ; will still work as it's on a page crossing boundary. + sta (dest), y ; This will avoid most of the overhead of the branch. + iny + sta (dest), y + iny + sta (dest), y + iny + sta (dest), y + iny + sta (dest), y + iny + sta (dest), y + iny + sta (dest), y + iny + bne :- + + inc dest_hi + ldx dest_hi + cpx #>SCREEN + $20 + bne :- + + rts + +;----------------------------------------------------------------------------------- +; ScrollScreen - Scrolls the entire video memory (and thus the screen) up one row +;----------------------------------------------------------------------------------- + +BYTES_TO_MOVE = SCREEN_BYTES - BYTESPERCHARROW +PAGES_TO_MOVE = BYTES_TO_MOVE / 256 + +_ScrollScreen: + pha + tya + pha + txa + pha + + ; Load the source (A140) and destination (A000) addresses + lda #<(SCREEN+BYTESPERCHARROW) + sta scroll_src_lo + lda #>(SCREEN+BYTESPERCHARROW) + sta scroll_src_hi + lda #SCREEN + sta scroll_dest_hi + + ldx #PAGES_TO_MOVE +@outerLoop: + ldy #0 +@innerLoop: ; + ; I could do this faster in self-modifying code (avoiding the zero page overhead) but then it + ; couldn't go into ROM + + lda (scroll_src),y ; I've unwound the loop to do 8 bytes at a time. Since we're doing full pages + sta (scroll_dest),y ; as long as we unwind the loop to do 8 bytes at a time, we know we'll still + iny ; do the final increment on a page boundary. + lda (scroll_src),y + sta (scroll_dest),y + iny + lda (scroll_src),y + sta (scroll_dest),y + iny + lda (scroll_src),y + sta (scroll_dest),y + iny + lda (scroll_src),y + sta (scroll_dest),y + iny + lda (scroll_src),y + sta (scroll_dest),y + iny + lda (scroll_src),y + sta (scroll_dest),y + iny + lda (scroll_src),y + sta (scroll_dest),y + iny + bne @innerLoop ; If Y overflows, it will be 0, so won't branch + inc scroll_src_hi + inc scroll_dest_hi + dex + bne @outerLoop + + ; Clear the last line + lda #LASTROW + sta scroll_dest_hi + lda #$00 + ldy #0 +fullPageLoop: + sta (scroll_dest_lo),y + iny + bne fullPageLoop + inc scroll_dest_hi +partialPageLoop: + sta (scroll_dest_lo),y + iny + cpy #BYTESPERCHARROW - 256 ; Only clear up to the 64th byte (256 + 64 == 320) + bne partialPageLoop + + pla + tax + pla + tay + pla + rts + +;----------------------------------------------------------------------------------- +; DrawCircle - Draws a circle in video memory of a given radius at a given coord +;----------------------------------------------------------------------------------- +; x - _x1cord (16-bit) +; y - _y1cord (16-bit) +; radius - _y2cord (16-bit) +;----------------------------------------------------------------------------------- +; Implements the midpoint circle algorithm without floating point or trig functions +;----------------------------------------------------------------------------------- +; int x = radius; +; int y = 0; +; int err = 0; +; +; while (x >= y) +; { +; SETPIXEL(x0 + x, y0 + y, val); +; SETPIXEL(x0 + y, y0 + x, val); +; SETPIXEL(x0 - y, y0 + x, val); +; SETPIXEL(x0 - x, y0 + y, val); +; SETPIXEL(x0 - x, y0 - y, val); +; SETPIXEL(x0 - y, y0 - x, val); +; SETPIXEL(x0 + y, y0 - x, val); +; SETPIXEL(x0 + x, y0 - y, val); +; +; y++; +; err += 1 + 2 * y; +; if (2 * (err - x) + 1 > 0) { +; x--; +; err += 1 - 2 * x; +; } +; } +;----------------------------------------------------------------------------------- + +_DrawCircle: lda _x1cord ; x0 = _x1cord + sta x0 + lda _x1cord+1 + sta x0+1 + lda _y1cord ; y0 = _y1cord + sta y0 + lda _y1cord+1 + sta y0+1 + + lda _y2cord ; x = radius + sta xval + lda _y2cord+1 + sta xval+1 + + lda #$0 ; yval = 0; + sta yval + sta yval+1 + sta err ; err = 0; + sta err+1 +circleloop: + lda xval+1 ; if (xval < yval) we're done; + sec + cmp yval+1 + bcc doneCircle ; if high byteof yval is greater, we can draw + bne doCircle ; it not greater and not equal, is less, so done + lda xval ; in other cases we need to compare the LSB next + cmp yval + bcs doCircle ; if it's less, but MSB was equal, we go draw + +doneCircle: rts + +doCircle: lda x0 ; Draw the first of 8 symmetric quadrant copies + clc + adc yval + sta _x1cord + lda x0+1 + adc yval+1 + sta _x1cord+1 + lda y0 + sec + sbc xval + sta _y1cord + lda y0+1 + sbc xval+1 + sta _y1cord+1 + jsr _SetPixel ; SETPIXEL(x0 + y, y0 - x, val); + + lda x0 + sec + sbc yval + sta _x1cord + lda x0+1 + sbc yval+1 + sta _x1cord+1 + lda y0 + sec + sbc xval + sta _y1cord + lda y0+1 + sbc xval+1 + sta _y1cord+1 + jsr _SetPixel ; SETPIXEL(x0 - y, y0 - x, val); + + lda x0 + sec + sbc xval + sta _x1cord + lda x0+1 + sbc xval+1 + sta _x1cord+1 + lda y0 + sec + sbc yval + sta _y1cord + lda y0+1 + sbc yval+1 + sta _y1cord+1 + jsr _SetPixel ; SETPIXEL(x0 - x, y0 - y, val); + + lda x0 + sec + sbc xval + sta _x1cord + lda x0+1 + sbc xval+1 + sta _x1cord+1 + lda y0 + clc + adc yval + sta _y1cord + lda y0+1 + adc yval+1 + sta _y1cord+1 + jsr _SetPixel ; SETPIXEL(x0 - x, y0 + y, val); + + lda x0 + clc + adc yval + sta _x1cord + lda x0+1 + adc yval+1 + sta _x1cord+1 + lda y0 + clc + adc xval + sta _y1cord + lda y0+1 + adc xval+1 + sta _y1cord+1 + jsr _SetPixel ; SETPIXEL(x0 + y, y0 + x, val); + + lda x0 + clc + adc xval + sta _x1cord + lda x0+1 + adc xval+1 + sta _x1cord+1 + lda y0 + clc + adc yval + sta _y1cord + lda y0+1 + adc yval+1 + sta _y1cord+1 + jsr _SetPixel ; SETPIXEL(x0 + x, y0 + y, val); + + lda x0 + clc + adc xval + sta _x1cord + lda x0+1 + adc xval+1 + sta _x1cord+1 + lda y0 + sec + sbc yval + sta _y1cord + lda y0+1 + sbc yval+1 + sta _y1cord+1 + jsr _SetPixel ; SETPIXEL(x0 + x, y0 - y, val); + + lda x0 + sec + sbc yval + sta _x1cord + lda x0+1 + sbc yval+1 + sta _x1cord+1 + lda y0 + clc + adc xval + sta _y1cord + lda y0+1 + adc xval+1 + sta _y1cord+1 + jsr _SetPixel ; SETPIXEL(x0 - y, y0 + x, val); + + inc yval ; yval++; + bne :+ + inc yval+1 + +: lda yval ; temp = 2 * yval + 1; + asl + sta temp + lda yval+1 + rol + sta temp+1 + inc temp + bne :+ + inc temp+1 +: + lda err ; err += temp + clc + adc temp + sta err + lda err+1 + adc temp+1 + sta err+1 + ; if (2 * (err - xval) + 1 > 0) then dec xval + lda err ; temp = err-xval + sec + sbc xval + sta temp + lda err+1 + sbc xval+1 + sta temp+1 + + asl temp ; temp = 2*(err-xval)+1 + rol temp+1 + inc temp + bne :+ + inc temp+1 +: + lda temp+1 ; if (temp > 0) we'll dec xval + bmi doneLoop ; less than zero, so no dec + bne decxval ; if not zero, go ahead and dec + + lda temp ; MSB is zero so now check the LSB + beq doneLoop ; both bytes are zero, so no dec + +decxval: lda xval ; xval-- + bne :+ + dec xval+1 +: dec xval + +updateerr: lda xval ; temp = xval * 2 + asl + sta temp + lda xval+1 + rol + sta temp+1 + + lda #1 ; temp2 == 1-temp == 1-(xval*2) + sec + sbc temp + sta temp2 + lda #0 + sbc temp+1 + sta temp2+1 + + lda err ; err += 1-(xval*2) + clc + adc temp2 + sta err + lda err+1 + adc temp2+1 + sta err+1 + +doneLoop: jmp circleloop + +;----------------------------------------------------------------------------------- +; Character set translation tables +;----------------------------------------------------------------------------------- + +ascToPetTable: .byte $00,$01,$02,$03,$04,$05,$06,$07,$14,$20,$0d,$11,$93,$0a,$0e,$0f + .byte $10,$0b,$12,$13,$08,$15,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f + .byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f + .byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f + .byte $40,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf + .byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$5b,$5c,$5d,$5e,$5f + .byte $c0,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f + .byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$db,$dc,$dd,$de,$df + .byte $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f + .byte $90,$91,$92,$0c,$94,$95,$96,$97,$98,$99,$9a,$9b,$9c,$9d,$9e,$9f + .byte $a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af + .byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf + .byte $60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f + .byte $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$7b,$7c,$7d,$7e,$7f + .byte $e0,$e1,$e2,$e3,$e4,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ee,$ef + .byte $f0,$f1,$f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$fa,$fb,$fc,$fd,$fe,$ff + +; PETSCI to Ascii lookup table - not current used, so commented out, but can be used to map fonts +; +; + petToAscTable: .byte $00,$01,$02,$03,$04,$05,$06,$07,$14,$09,$0d,$11,$93,$0a,$0e,$0f + .byte $10,$0b,$12,$13,$08,$15,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f + .byte $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f + .byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f + .byte $40,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f + .byte $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$5b,$5c,$5d,$5e,$5f + .byte $c0,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf + .byte $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$db,$dc,$dd,$de,$df + .byte $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f + .byte $90,$91,$92,$0c,$94,$95,$96,$97,$98,$99,$9a,$9b,$9c,$9d,$9e,$9f + .byte $a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af + .byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf + .byte $60,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f + .byte $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$7b,$7c,$7d,$7e,$7f + .byte $a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af + .byte $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf + +;----------------------------------------------------------------------------------- +; PetToAsc - Convert a PETSCII character to ASCII +;----------------------------------------------------------------------------------- +; A - Character to convert +;----------------------------------------------------------------------------------- + +_AscToPet: tay + lda ascToPetTable, y + rts + +_PetToAsc: tay + lda petToAscTable, Y + rts + +;----------------------------------------------------------------------------------- +; ReverseBits - Reverse the bits in a byte +;----------------------------------------------------------------------------------- +; A = octet to be reversed +;----------------------------------------------------------------------------------- + +_ReverseBits: + ldx #8 ; set counter to 8 (for 8 bits) + lda #0 ; initialize A to 0 + sta temp ; clear result byte (accumulator for the reversed octet) +: asl ; shift leftmost bit of input into carry + lda temp ; load the temporary result byte into A + ror ; rotate carry into leftmost bit of result + sta temp ; store the updated result back into memory + dex ; decrement counter + bne :- ; repeat until all bits are processed + lda temp ; load the final reversed byte into A + rts ; return with result in A + +;----------------------------------------------------------------------------------- +; LoadFont - Makes sure the font data is ready to use. This usually requires +; reversing the bits so that they match the bit order of the screen +;----------------------------------------------------------------------------------- + +_LoadFont: ldx #3 + lda #<_font8x8_basic + sta adp1_lo + lda #>_font8x8_basic + sta adp1_hi + ldy #0 +@loop: lda (adp1), y + jsr _ReverseBits + sta (adp1), y + iny + bne @loop + + inc adp1_lo + bne :+ + inc adp1_hi +: dex + bne @loop + rts + +ScreenLineAddresses: + .word SCREEN + 0 * BYTESPERCHARROW, SCREEN + 1 * BYTESPERCHARROW + .word SCREEN + 2 * BYTESPERCHARROW, SCREEN + 3 * BYTESPERCHARROW + .word SCREEN + 4 * BYTESPERCHARROW, SCREEN + 5 * BYTESPERCHARROW + .word SCREEN + 6 * BYTESPERCHARROW, SCREEN + 7 * BYTESPERCHARROW + .word SCREEN + 8 * BYTESPERCHARROW, SCREEN + 9 * BYTESPERCHARROW + .word SCREEN + 10 * BYTESPERCHARROW, SCREEN + 11 * BYTESPERCHARROW + .word SCREEN + 12 * BYTESPERCHARROW, SCREEN + 13 * BYTESPERCHARROW + .word SCREEN + 14 * BYTESPERCHARROW, SCREEN + 15 * BYTESPERCHARROW + .word SCREEN + 16 * BYTESPERCHARROW, SCREEN + 17 * BYTESPERCHARROW + .word SCREEN + 18 * BYTESPERCHARROW, SCREEN + 19 * BYTESPERCHARROW + .word SCREEN + 20 * BYTESPERCHARROW, SCREEN + 21 * BYTESPERCHARROW + .word SCREEN + 22 * BYTESPERCHARROW, SCREEN + 23 * BYTESPERCHARROW + .word SCREEN + 24 * BYTESPERCHARROW + .assert( (* - ScreenLineAddresses) = ROWSPERCOLUMN * 2), error + +;----------------------------------------------------------------------------------- +; DrawChar - Draws an ASCII character at char location x, y +;----------------------------------------------------------------------------------- +; 0 <= x < 40 +; 0 <= y < 25 +; Preserves all registers, but its not very threadsafe or reentrant +;----------------------------------------------------------------------------------- + +_DrawChar: sty tempy + stx tempx + sta tempa + + tya ; Get the address in screen memory where this + asl ; character X/Y cursor pos should be drawn + tay + txa + clc + adc ScreenLineAddresses, y + sta dest_lo + lda ScreenLineAddresses+1, y + adc #0 + sta dest_hi + + lda #0 ; Get the address in font memory where this + sta src_hi ; Petscii chracter lives (after conversion from + lda tempa ; ascii) + + sty temp2 + jsr _AscToPet + ldy temp2 + + asl + rol src_hi + asl + rol src_hi + asl + rol src_hi + clc + adc #<_font8x8_basic ; Add the base address of the font table to the offset + sta src_lo + lda src_hi + adc #>_font8x8_basic + sta src_hi + + ldy #0 ; opy the character def to the screen, one byte at a time + ldx #0 +: lda (src), y ; Copy this byte from the character def to the screen target + sta (dest, x) + lda dest_lo ; Advance to the next "scanline", or pixel row, down + clc + adc #BYTESPERROW + sta dest_hi + + iny + cpy #8 + bne :- + + ldy tempy + ldx tempx + lda tempa + rts + +;----------------------------------------------------------------------------------- +; CursorOn - Turns on the text cursor and draws it at the current cursor pos +;----------------------------------------------------------------------------------- + +CursorOn: ldx _cursorX + ldy _cursorY + lda #'_' + jsr _DrawChar + rts + +CursorOff: ldx _cursorX + ldy _cursorY + lda #' ' + jsr _DrawChar + rts + +;----------------------------------------------------------------------------------- +; DrawText - Draws an ASCII char in A at the current cursor pos, saves all regs +;----------------------------------------------------------------------------------- + +_CharOut: sta temp + lda #0 + sta temp+1 + txa + pha + tya + pha + + ldx #temp + jsr _DrawText + + pla + tay + pla + tax + rts + +;----------------------------------------------------------------------------------- +; Backspace - Erase the current character and move back one position. Does not +; move back up to previous line +;----------------------------------------------------------------------------------- + +Backspace: lda _cursorX + beq colzero + jsr CursorOff + dec _cursorX + jsr CursorOn +colzero: rts + +;----------------------------------------------------------------------------------- +; DrawText - Draws an ASCII string at the current cursor position +;----------------------------------------------------------------------------------- +; XY - Pointer to the string to draw, stops on NUL or 255 chars later +;----------------------------------------------------------------------------------- + +_DrawText: stx adp1_lo + sty adp1_hi + jsr CursorOff + + ldy #0 +checkHWrap: lda _cursorX + cmp #CHARSPERROW + bcc checkVWrap + lda #0 + sta _cursorX + inc _cursorY + +checkVWrap: lda _cursorY + cmp #ROWSPERCOLUMN + bcc loadChar + jsr _ScrollScreen + lda #ROWSPERCOLUMN-1 + sta _cursorY + +loadChar: lda (adp1), y + beq doneText + + cmp #$0a + bne :+ + + lda #0 ; Back to the left edge + sta _cursorX + inc _cursorY ; Advance to the next line + iny + bne checkHWrap + +: sty temp + ldx _cursorX + ldy _cursorY + jsr _DrawChar + ldy temp + inc _cursorX + iny + bne checkHWrap + +doneText: jsr CursorOn + rts + +demoText1: .byte " *** COMMODORE KIM-1 SHELL V0.1 ***", $0A, $0A + .byte " 60K RAM SYSTEM. 49152 BYTES FREE.", $0A, $0A, $00 +readyText: .byte $0A,"READY.", $0A, 00 + +_Demo: jsr _ClearScreen + lda #0 + sta _cursorX + sta _cursorY + ldx #demoText1 + jsr _DrawText + rts + +_Ready: ldx #readyText + jsr _DrawText + rts + + +;----------------------------------------------------------------------------------- +; DrawLine - Draws a line between two points +;----------------------------------------------------------------------------------- +; _x1cord (16-bit) +; _y1cord ( 8-bit) +; _x2cord (16-bit) +; _y2cord ( 8-bit) +;----------------------------------------------------------------------------------- +; Implements something like Bresenham's algorithm for drawing a line: +;----------------------------------------------------------------------------------- +; void DrawLine(int x0, int y0, int x1, int y1, byte val) +; { +; int dx = abs(_x2cord - _x1cord), sx = _x1cord < _x2cord ? 1 : -1; +; int dy = abs(_y2cord - _y1cord), sy = _y1cord < _y2cord ? 1 : -1; +; int err = (dx > dy ? dx : -dy) / 2, e2; +; +; while (1) +; { +; SETPIXEL(_x1cord, _y1cord, val); +; +; if (_x1cord == _x2cord && _y1cord == _y2cord) +; break; +; +; e2 = err; +; +; if (e2 > -dx) +; { +; err -= dy; +; _x1cord += sx; +; } +; if (e2 < dy) +; { +; err += dx; +; _y1cord += sy; +; } +; } +; } +;----------------------------------------------------------------------------------- + +_DrawLine: sta pixel + + ldx #$01 ; positive x-step for now + stx sx + + ; Calculate dx = (x2cord - X1cord) and see if its positive or not + + lda _x2cord ; Calculate dx = (x2cord - X1cord) + sec + sbc _x1cord + sta dx + lda _x2cord+1 + sbc _x1cord+1 + sta dx+1 + bpl calcdy ; dx is positive (dx >= 0), so we're good + + ; dx was negative (dx < 0), so we set sx to -1 and get the absolute + ; value by subtracting the other direction + + ldx #$FF ; negative x-step + stx sx + lda _x1cord ; Calculate dx = (x2cord - X1cord) + sec + sbc _x2cord + sta dx + lda _x1cord+1 + sbc _x2cord+1 + sta dx+1 + + ; Calculate dy = (y2cord - y1cord) and see if its positive or not + +calcdy: ldx #$01 ; positive y-step for now + stx sy + lda _y2cord + sec + sbc _y1cord + sta dy + bcs positivedy ; If y2cord > y1cord, then dy is positive and we're good + + ; dy was negative (dy < 0), so we set sy to -1 and get the absolute value + + ldx #$FF ; negative y-step + stx sy + lda _y1cord + sec + sbc _y2cord + sta dy + + ; Now we have dx and dy, so we can calculate err, but first we need + ; to see if dx > dy or not + +positivedy: lda dx+1 ; Check if dx > dy (both are always positive now) + bne dxgt ; If MSB of dx is greater than zero, then dx > dy since dy is 8-bits + lda dy + cmp dx + bcs dygte + +dxgt: lda dx ; We found dx>dy so set err = dx / 2 + sta err + lda dx+1 + lsr + sta err+1 ; err = dx/2 + ror err + jmp loop + +dygte: lda #0 ; we found dx <= dy so set err = -dy / 2 + sec + sbc dy ; else err = -dy / 2 + ror + ora #$80 + sta err + lda #$FF + sta err+1 + + ; Now we have dx, dy, and err, so we can start drawing pixels + +loop: lda pixel + beq clearpixel + jsr _SetPixel ; Plot the current _x1cord, _y1cord + jmp next +clearpixel: jsr _ClearPixel ; Clear the current _x1cord, _y1cord + +next: lda _x1cord ; if (_x1cord == _x2cord && _y1cord == _y2cord) then we rts + cmp _x2cord + bne noteq + lda _y1cord + cmp _y2cord + bne noteq + lda _x1cord+1 + cmp _x2cord+1 + bne noteq + + rts + +noteq: lda err ; e2 = err + sta e2 + lda err+1 + sta e2+1 + + ; Check the two update conditions for x and y, and update if needed + + lda e2 ; if (e2 > -dx) is the same as if (e2 + dx > 0), so we test that because its easier + clc ; If its true then we dec err and inc _x1cord + adc dx + sta temp + lda e2+1 + adc dx+1 + bmi doneupdatex ; If result is negative, then e2 + dx < 0, so we don't dec err or inc _x1cord + bne stepx ; If MSB is non-zero, then e2 + dx > 0, so we DO dec err and inc _x1cord + lda temp ; If result is zero in MSB, then we check the LSB here + beq doneupdatex ; If LSB is zero, then we don't dec err or inc _x1cord + ; We already know e2 + dx > 0, so LSB can't be negative +stepx: lda sx + bmi decx +incxval: inc _x1cord ; _x1cord += 1 because sx == 1 + bne updatexerr + inc _x1cord+1 + jmp updatexerr + +decx: lda _x1cord ; _x1cord += 1 because sx == 1 + sec + sbc #1 + sta _x1cord + lda _x1cord+1 + sbc #0 + sta _x1cord+1 + +updatexerr: lda err ; err -= dy + sec + sbc dy + sta err + lda err+1 + sbc #0 + sta err+1 + +doneupdatex: lda e2+1 ; if (e2 < dy) then we inc err and inc _y1cord + bmi updateerry ; If MSB is negative, then e2 < dy, so we inc err and inc _y1cord + bne noupdatey ; If the MSB of e2 is set and positive, then we know e2 > dy, so we don't inc err or inc _y1cord + lda e2 + sec + sbc dy + beq noupdatey ; e2 - dy == 0 so we don't inc err or inc _y1cord + bcs noupdatey ; if e2 was large enough that carry never cleared, then e2 > dy do no update + +updateerry: lda err ; err += dx + clc + adc dx + sta err + lda err+1 + adc dx+1 + sta err+1 + +stepy: lda _y1cord + clc + adc sy + sta _y1cord + +noupdatey: jmp loop + +_getch: jsr $1E5A ; Get character using Monitor ROM call + and #$7F ; Clear top bit + cmp #$0D ; Check for '\r' + bne gotch ; ...if CR character + lda #$0A ; Replace with '\n' +gotch: rts From 5acfb027941d3a8adac538078b7ccc587775af60 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sat, 3 Feb 2024 16:20:17 +0100 Subject: [PATCH 145/707] update actions/checkout@v3 -> actions/checkout@v4 and microsoft/setup-msbuild@v1.1 -> microsoft/setup-msbuild@v2. lets see what happens :) --- .github/workflows/build-on-pull-request.yml | 6 +++--- .github/workflows/snapshot-on-push-master.yml | 8 ++++---- .github/workflows/windows-test-scheduled.yml | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 6217c42a2..1064776cf 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -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 @@ -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 diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index 571947c9b..f66b1a745 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -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 @@ -97,7 +97,7 @@ jobs: 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 diff --git a/.github/workflows/windows-test-scheduled.yml b/.github/workflows/windows-test-scheduled.yml index 451b37f79..25f0d3e50 100644 --- a/.github/workflows/windows-test-scheduled.yml +++ b/.github/workflows/windows-test-scheduled.yml @@ -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' From 3dfe0330003f19680f2afc9a607bea397b5c9fec Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sat, 3 Feb 2024 17:02:08 +0100 Subject: [PATCH 146/707] update actions/upload-artifact@v3->actions/upload-artifact@v4, actions/cache@v3->actions/cache@v4 --- .github/workflows/build-on-pull-request.yml | 2 +- .github/workflows/snapshot-on-push-master.yml | 6 +++--- .github/workflows/windows-test-scheduled.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 1064776cf..146964a30 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -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 diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index f66b1a745..d58bff8ed 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -86,12 +86,12 @@ 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 @@ -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 diff --git a/.github/workflows/windows-test-scheduled.yml b/.github/workflows/windows-test-scheduled.yml index 25f0d3e50..f72254273 100644 --- a/.github/workflows/windows-test-scheduled.yml +++ b/.github/workflows/windows-test-scheduled.yml @@ -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 From 7b790cf8833668c21447490b8b84a0e704a3f134 Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Sun, 4 Feb 2024 23:38:44 -0800 Subject: [PATCH 147/707] add RIA_OP_CLOCK to asm inc --- asminc/rp6502.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/asminc/rp6502.inc b/asminc/rp6502.inc index 7dd1b8fcd..816712abb 100644 --- a/asminc/rp6502.inc +++ b/asminc/rp6502.inc @@ -37,6 +37,7 @@ RIA_OP_PHI2 := $02 RIA_OP_CODEPAGE := $03 RIA_OP_LRAND := $04 RIA_OP_STDIN_OPT := $05 +RIA_OP_CLOCK := $0F RIA_OP_CLOCK_GETRES := $10 RIA_OP_CLOCK_GETTIME := $11 RIA_OP_CLOCK_SETTIME := $12 From b04d79b1da2bc5b79c4ff78b6819ee0924376ec2 Mon Sep 17 00:00:00 2001 From: Carlo Bramini Date: Thu, 4 Jan 2024 13:12:52 +0100 Subject: [PATCH 148/707] [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 --- asminc/cpu.mac | 2 +- libsrc/sim6502/exehdr.s | 12 +- src/sim65/6502.c | 2703 ++++++++++++++++++++++++++------------- src/sim65/6502.h | 3 +- src/sim65/main.c | 10 +- 5 files changed, 1805 insertions(+), 925 deletions(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 31170fbed..084a42119 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -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 diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s index 09d099da5..529ad9b94 100644 --- a/libsrc/sim6502/exehdr.s +++ b/libsrc/sim6502/exehdr.s @@ -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 diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 9d2c93da8..448e81669 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -12,6 +12,8 @@ /* EMail: uz@cc65.org */ /* */ /* Mar-2017, Christian Krueger, added support for 65SC02 */ +/* Dec-2023, Carlo Bramini, rewritten for better maintenance and added */ +/* support for undocumented opcodes for 6502 */ /* */ /* This software is provided 'as-is', without any expressed or implied */ /* warranty. In no event will the authors be held liable for any damages */ @@ -44,7 +46,337 @@ #include "6502.h" #include "paravirt.h" +/* + 6502 opcode map: + + x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF +0x BRK ORA --- SLO NOP ORA ASL SLO PHP ORA ASL ANC NOP ORA ASL SLO + inx inx zp zp zp zp imm acc imm abs abs abs abs + +1x BPL ORA --- SLO NOP ORA ASL SLO CLC ORA NOP SLO NOP ORA ASL SLO + rel iny iny zpx zpx zpx zpy aby aby abx abx abx abx + +2x JSR AND --- RLA BIT AND ROL RLA PLP AND ROL ANC BIT AND ROL RLA + abs inx inx zp zp zp zp imm acc imm abs abs abs abs + +3x BMI AND --- RLA NOP AND ROL RLA SEC AND NOP RLA NOP AND ROL RLA + rel iny iny zpx zpx zpx zpy aby aby abx abx abx abx + +4x RTI EOR --- SRE NOP EOR LSR SRE PHA EOR LSR ASR JMP EOR LSR SRE + inx inx zp zp zp zp imm acc imm abs abs abs abs + +5x BVC EOR --- SRE NOP EOR LSR SRE CLI EOR NOP SRE NOP EOR LSR SRE + rel iny iny zpx zpx zpx zpx aby aby abx abx abx abx + +6x RTS ADC --- RRA NOP ADC ROR RRA PLA ADC ROR ARR JMP ADC ROR RRA + inx inx zp zp zp zp imm acc imm ind abs abs abs + +7x BVS ADC --- RRA NOP ADC ROR RRA SEI ADC NOP RRA NOP ADC ROR RRA + rel iny iny zpx zpx zpx zpx aby aby abx abx abx abx + +8x NOP STA NOP SAX STY STA STX SAX DEY NOP TXA ANE STY STA STX SAX + imm inx imm inx zp zp zp zp imm imm abs abs abs abs + +9x BCC STA --- SHA STY STA STX SAX TYA STA TXS TAS SHY STA SHX SHA + rel iny iny zpx zpx zpy zpy aby aby abx abx aby aby + +Ax LDY LDA LDX LAX LDY LDA LDX LAX TAY LDA TAX LXA LDY LDA LDX LAX + imm inx imm inx zp zp zp zp imm imm abs abs abs abs + +Bx BCS LDA --- LAX LDY LDA LDX LAX CLV LDA TSX LAS LDY LDA LDX LAX + rel iny iny zpx zpx zpy zpy aby aby abx abx aby aby + +Cx CPY CMP NOP DCP CPY CMP DEC DCP INY CMP DEX SBX CPY CMP DEC DCP + imm inx imm inx zp zp zp zp imm imm abs abs abs abs + +Dx BNE CMP --- DCP NOP CMP DEC DCP CLD CMP NOP DCP NOP CMP DEC DCP + rel iny iny zpx zpx zpx zpx aby zpx aby abx abx abx abx + +Ex CPX SBC NOP ISC CPX SBC INC ISC INX SBC NOP SBC CPX SBC INC ISC + imm inx imm inx zp zp zp zp imm imm abs abs abs abs + +Fx BEQ SBC --- ISC NOP SBC INC ISC SED SBC NOP ISC NOP SBC INC ISC + rel iny iny zpx zpx zpx zpx aby zpx aby abx abx abx abx + +--- = CPU JAM/HALT + +*/ + +/* + +65xx ILLEGAL INSTRUCTIONS + + +* SLO: shift left the contents of a memory location and then OR the result with + the accumulator. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X X +SLO abs | 0Fh | 6 | +SLO abs,X | 1Fh | 7 | +SLO abs,Y | 1Bh | 7 | +SLO zp | 07h | 5 | +SLO zp,X | 17h | 6 | +SLO (zp,X) | 03h | 8 | +SLO (zp),Y | 13h | 8 | +-------------+--------+--------+ + + +* RLA: rotate left the contents of a memory location and then AND the result with + the accumulator. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X X +RLA abs | 2Fh | 6 | +RLA abs,X | 3Fh | 7 | +RLA abs,Y | 3Bh | 7 | +RLA zp | 27h | 5 | +RLA zp,X | 37h | 6 | +RLA (zp,X) | 23h | 8 | +RLA (zp),Y | 33h | 8 | +-------------+--------+--------+ + + +* SRE: shift right the contents of a memory location and then X-OR the result + with the accumulator. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X X +SRE abs | 4Fh | 6 | +SRE abs,X | 5Fh | 7 | +SRE abs,Y | 5Bh | 7 | +SRE zp | 47h | 5 | +SRE zp,X | 57h | 6 | +SRE (zp,X) | 43h | 8 | +SRE (zp),Y | 53h | 8 | +-------------+--------+--------+ + + +* RRA: rotate right the contents of a memory location and then adds with carry + the result with the accumulator. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X X . . . X X +RRA abs | 6Fh | 6 | +RRA abs,X | 7Fh | 7 | +RRA abs,Y | 7Bh | 7 | +RRA zp | 67h | 5 | +RRA zp,X | 77h | 6 | +RRA (zp,X) | 63h | 8 | +RRA (zp),Y | 73h | 8 | +-------------+--------+--------+ + + +* SAX: calculate AND between the A and X registers (without changing the + contents of the registers) and stores the result in memory. + Flags into P register are not modified. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: . . . . . . . +SAX abs | 8Fh | 4 | +SAX zp | 87h | 3 | +SAX zp,Y | 97h | 4 | +SAX (zp,X) | 83h | 6 | +-------------+--------+--------+ + + +* LAX: loads both the accumulator and the X register with the content of a memory + location. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X . +LAX abs | AFh | 4 | +LAX abs,Y | BFh | 4* | * = adds +1 if page cross is detected. +LAX zp | A7h | 3 | +LAX zp,Y | B7h | 4 | +LAX (zp,X) | A3h | 6 | +LAX (zp),Y | B3h | 5* | +-------------+--------+--------+ + + +* DCP: decrements the contents of a memory location and then compares the result + with the accumulator. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X X +DCP abs | CFh | 6 | +DCP abs,X | DFh | 7 | +DCP abs,Y | DBh | 7 | +DCP zp | C7h | 5 | +DCP zp,X | D7h | 6 | +DCP (zp,X) | C3h | 8 | +DCP (zp),Y | D3h | 8 | +-------------+--------+--------+ + + +* ISC: increments the contents of a memory location and then subtract with carry + the result from the accumulator. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X X . . . X X +ISC abs | EFh | 6 | +ISC abs,X | FFh | 7 | +ISC abs,Y | FBh | 7 | +ISC zp | E7h | 5 | +ISC zp,X | F7h | 6 | +ISC (zp,X) | E3h | 8 | +ISC (zp),Y | F3h | 8 | +-------------+--------+--------+ + + +* ASR: calculates the AND between the accumulator and an immediate value and then + shift right the result. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X X +ASR #imm | 4Bh | 2 | +-------------+--------+--------+ + + +* ARR: calculates the AND between the accumulator and an immediate value and then + rotate right the result. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X X +ARR #imm | 6Bh | 2 | +-------------+--------+--------+ + + +* ANE: calculates the OR of the accumulator with an unstable constant, then it does + an AND with the X register and an immediate value. + The unstable constant varies with temperature, the production batch and + maybe other factors. Experimental measures assume its value to 0xEF. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X . +ANE #imm | 8Bh | 2 | +-------------+--------+--------+ + + +* LXA: calculates the OR of the accumulator with an unstable constant, then it does + an AND with an immediate value. The result is copied into the X register and + the accumulator. + The unstable constant varies with temperature, the production batch and + maybe other factors. Experimental measures assume its value to 0xEE. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X . +LXA #imm | ABh | 2 | +-------------+--------+--------+ + + +* SBX: calculates the AND of the accumulator with the X register and the subtracts + an immediate value. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X X +SBX #imm | CBh | 2 | +-------------+--------+--------+ + + +* NOP: No-Operation. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: . . . . . . . +NOP | 1Ah | 2 | +NOP | 3Ah | 2 | * = adds +1 if page cross is detected. +NOP | 5Ah | 2 | +NOP | 7Ah | 2 | +NOP | DAh | 2 | +NOP | FAh | 2 | +NOP #imm | 80h | 2 | +NOP #imm | 82h | 2 | +NOP #imm | 89h | 2 | +NOP #imm | C2h | 2 | +NOP #imm | E2h | 2 | +NOP zp | 04h | 3 | +NOP zp,x | 14h | 4 | +NOP zp,x | 34h | 4 | +NOP zp | 44h | 3 | +NOP zp,x | 54h | 4 | +NOP zp | 64h | 3 | +NOP zp,x | 74h | 4 | +NOP zp,x | D4h | 4 | +NOP zp,x | F4h | 4 | +NOP abs | 0Ch | 4 | +NOP abs,x | 1Ch | 4* | +NOP abs,x | 3Ch | 4* | +NOP abs,x | 5Ch | 4* | +NOP abs,x | 7Ch | 4* | +NOP abs,x | DCh | 4* | +NOP abs,x | FCh | 4* | +-------------+--------+--------+ + + +* TAS: calculates the AND of the accumulator with the X register and stores the result + into the stack pointer. Then, it calculates the AND of the result with the + high byte of the memory pointer plus 1 and it stores the final result in memory. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: . . . . . . . +TAS abs,y | 9Bh | 5 | +-------------+--------+--------+ + + +* SHY: calculates the AND of the Y register with the high byte of the memory pointer + plus 1 and it stores the final result in memory. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: . . . . . . . +SHY abs,x | 9Ch | 5 | +-------------+--------+--------+ + + +* SHX: calculates the AND of the X register with the high byte of the memory pointer + plus 1 and it stores the final result in memory. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: . . . . . . . +SHX abs,y | 9Eh | 5 | +-------------+--------+--------+ + + +* SHA: calculates the AND of the accumulator with the X register with the high byte + of the memory pointer plus 1 and it stores the final result in memory. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: . . . . . . . +SHX abs,y | 9Fh | 5 | +SHX (zp),y | 93h | 6 | +-------------+--------+--------+ + + +* ANC: calculates the AND of the accumulator with an immediate value and then + updates the status of N and Z bits of the status register. + The N flag is also copied into the Carry flag. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X X +ANC #imm | 0Bh | 2 | +ANC #imm | 2Bh | 2 | +-------------+--------+--------+ + + +* LAS: calculates the contents of a memory location with the contents of the +stack pointer register and it stores the result in the accumulator, the X +register, and the stack pointer. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X . . . . X . +LAS abs,y | BBh | 4* | +-------------+--------+--------+ * = adds +1 if page cross is detected. + + +* SBC: alias of the official SBC opcode. + +Address mode | opcode | cycles | N V B D I Z C +-------------+--------+--------+ FLAGS: X X . . . X X +SBC #imm | EBh | 2 | +-------------+--------+--------+ + + +*/ /*****************************************************************************/ /* Data */ @@ -113,118 +445,223 @@ static unsigned HaveIRQRequest; /* Test for page cross */ #define PAGE_CROSS(addr,offs) ((((addr) & 0xFF) + offs) >= 0x100) -/* #imm */ -#define AC_OP_IMM(op) \ - Cycles = 2; \ - Regs.AC = Regs.AC op MemReadByte (Regs.PC+1); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ - Regs.PC += 2 +/* Address operators */ /* zp */ -#define AC_OP_ZP(op) \ - Cycles = 3; \ - Regs.AC = Regs.AC op MemReadByte (MemReadByte (Regs.PC+1)); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ +#define ADR_ZP(ad) \ + ad = MemReadByte (Regs.PC+1); \ Regs.PC += 2 /* zp,x */ -#define AC_OP_ZPX(op) \ - unsigned char ZPAddr; \ - Cycles = 4; \ - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; \ - Regs.AC = Regs.AC op MemReadByte (ZPAddr); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ +#define ADR_ZPX(ad) \ + ad = (MemReadByte (Regs.PC+1) + Regs.XR) & 0xFF; \ Regs.PC += 2 /* zp,y */ -#define AC_OP_ZPY(op) \ - unsigned char ZPAddr; \ - Cycles = 4; \ - ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR; \ - Regs.AC = Regs.AC op MemReadByte (ZPAddr); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ +#define ADR_ZPY(ad) \ + ad = (MemReadByte (Regs.PC+1) + Regs.YR) & 0xFF; \ Regs.PC += 2 /* abs */ -#define AC_OP_ABS(op) \ - unsigned Addr; \ - Cycles = 4; \ - Addr = MemReadWord (Regs.PC+1); \ - Regs.AC = Regs.AC op MemReadByte (Addr); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ +#define ADR_ABS(ad) \ + ad = MemReadWord (Regs.PC+1); \ Regs.PC += 3 /* abs,x */ -#define AC_OP_ABSX(op) \ - unsigned Addr; \ - Cycles = 4; \ - Addr = MemReadWord (Regs.PC+1); \ - if (PAGE_CROSS (Addr, Regs.XR)) { \ +#define ADR_ABSX(ad) \ + ad = MemReadWord (Regs.PC+1); \ + if (PAGE_CROSS (ad, Regs.XR)) { \ ++Cycles; \ } \ - Regs.AC = Regs.AC op MemReadByte (Addr + Regs.XR); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ + ad += Regs.XR; \ Regs.PC += 3 /* abs,y */ -#define AC_OP_ABSY(op) \ - unsigned Addr; \ - Cycles = 4; \ - Addr = MemReadWord (Regs.PC+1); \ - if (PAGE_CROSS (Addr, Regs.YR)) { \ +#define ADR_ABSY(ad) \ + ad = MemReadWord (Regs.PC+1); \ + if (PAGE_CROSS (ad, Regs.YR)) { \ ++Cycles; \ } \ - Regs.AC = Regs.AC op MemReadByte (Addr + Regs.YR); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ + ad += Regs.YR; \ Regs.PC += 3 /* (zp,x) */ -#define AC_OP_ZPXIND(op) \ - unsigned char ZPAddr; \ - unsigned Addr; \ - Cycles = 6; \ - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; \ - Addr = MemReadZPWord (ZPAddr); \ - Regs.AC = Regs.AC op MemReadByte (Addr); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ +#define ADR_ZPXIND(ad) \ + ad = (MemReadByte (Regs.PC+1) + Regs.XR) & 0xFF; \ + ad = MemReadZPWord (ad); \ Regs.PC += 2 /* (zp),y */ -#define AC_OP_ZPINDY(op) \ - unsigned char ZPAddr; \ - unsigned Addr; \ - Cycles = 5; \ - ZPAddr = MemReadByte (Regs.PC+1); \ - Addr = MemReadZPWord (ZPAddr); \ - if (PAGE_CROSS (Addr, Regs.YR)) { \ +#define ADR_ZPINDY(ad) \ + ad = MemReadZPWord (MemReadByte (Regs.PC+1)); \ + if (PAGE_CROSS (ad, Regs.YR)) { \ ++Cycles; \ } \ - Addr += Regs.YR; \ - Regs.AC = Regs.AC op MemReadByte (Addr); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ + ad += Regs.YR; \ Regs.PC += 2 /* (zp) */ -#define AC_OP_ZPIND(op) \ - unsigned char ZPAddr; \ - unsigned Addr; \ - Cycles = 5; \ - ZPAddr = MemReadByte (Regs.PC+1); \ - Addr = MemReadZPWord (ZPAddr); \ - Regs.AC = Regs.AC op MemReadByte (Addr); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ +#define ADR_ZPIND(ad) \ + ad = MemReadZPWord (MemReadByte (Regs.PC+1)); \ Regs.PC += 2 +/* Address operators (no penalty on page cross) */ + +/* abs,x - no penalty */ +#define ADR_ABSX_NP(ad) \ + ad = MemReadWord (Regs.PC+1); \ + ad += Regs.XR; \ + Regs.PC += 3 + +/* abs,y - no penalty */ +#define ADR_ABSY_NP(ad) \ + ad = MemReadWord (Regs.PC+1); \ + ad += Regs.YR; \ + Regs.PC += 3 + +/* (zp),y - no penalty */ +#define ADR_ZPINDY_NP(ad) \ + ad = MemReadZPWord (MemReadByte (Regs.PC+1)); \ + ad += Regs.YR; \ + Regs.PC += 2 + + + +/* Memory operators */ + +/* #imm */ +#define MEM_AD_OP_IMM(op) \ + op = MemReadByte (Regs.PC+1); \ + Regs.PC += 2 + +/* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y / (zp) */ +#define MEM_AD_OP(mode, ad, op) \ + ADR_##mode(ad); \ + op = MemReadByte (ad) + +/* ALU opcode helpers */ + +/* Execution cycles for ALU opcodes */ +#define ALU_CY_ZP 3 +#define ALU_CY_ZPX 4 +#define ALU_CY_ZPY 4 +#define ALU_CY_ABS 4 +#define ALU_CY_ABSX 4 +#define ALU_CY_ABSY 4 +#define ALU_CY_ZPXIND 6 +#define ALU_CY_ZPINDY 5 +#define ALU_CY_ZPIND 5 + +/* #imm */ +#define ALU_OP_IMM(op) \ + unsigned char immediate; \ + MEM_AD_OP_IMM(immediate); \ + Cycles = 2; \ + op (immediate) + +/* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y / (zp) */ +#define ALU_OP(mode, op) \ + unsigned address, operand; \ + Cycles = ALU_CY_##mode; \ + MEM_AD_OP (mode, address, operand); \ + op (operand) + +/* Store opcode helpers */ + +/* Execution cycles for store opcodes */ +#define STO_CY_ZP 3 +#define STO_CY_ZPX 4 +#define STO_CY_ZPY 4 +#define STO_CY_ABS 4 +#define STO_CY_ABSX 5 +#define STO_CY_ABSY 5 +#define STO_CY_ZPXIND 6 +#define STO_CY_ZPINDY 6 +#define STO_CY_ZPIND 5 + +/* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y / (zp) */ +#define STO_OP(mode, op) \ + unsigned address; \ + Cycles = STO_CY_##mode; \ + ADR_##mode (address); \ + MemWriteByte(address, op) + +/* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y / (zp) */ +#define STO_CB(mode, cb) \ + unsigned address, operand; \ + Cycles = STO_CY_##mode; \ + ADR_##mode (address); \ + cb (operand); \ + MemWriteByte(address, operand) + +/* Read-Modify-Write opcode helpers */ + +/* Execution cycles for R-M-W opcodes */ +#define RMW_CY_ZP 5 +#define RMW_CY_ZPX 6 +#define RMW_CY_ZPY 6 +#define RMW_CY_ABS 6 +#define RMW_CY_ABSX 7 +#define RMW_CY_ABSY 7 +#define RMW_CY_ZPXIND 6 +#define RMW_CY_ZPINDY 5 +#define RMW_CY_ZPIND 5 + +#define RMW_CY_ABSX_NP RMW_CY_ABSX +#define RMW_CY_ABSY_NP RMW_CY_ABSY +#define RMW_CY_ZPINDY_NP RMW_CY_ZPINDY + +/* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y / (zp) */ +#define MEM_OP(mode, op) \ + unsigned address, operand; \ + Cycles = RMW_CY_##mode; \ + MEM_AD_OP (mode, address, operand); \ + op (operand); \ + MemWriteByte (address, (unsigned char)operand) + +/* 2 x Read-Modify-Write opcode helpers (illegal opcodes) */ + +/* Execution cycles for 2 x R-M-W opcodes */ +#define RMW2_CY_ZP 5 +#define RMW2_CY_ZPX 6 +#define RMW2_CY_ZPY 6 +#define RMW2_CY_ABS 6 +#define RMW2_CY_ABSX 7 +#define RMW2_CY_ABSY 7 +#define RMW2_CY_ZPXIND 8 +#define RMW2_CY_ZPINDY 8 + +/* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y */ +#define ILLx2_OP(mode, op) \ + unsigned address; \ + unsigned operand; \ + Cycles = RMW2_CY_##mode; \ + MEM_AD_OP (mode, address, operand); \ + op (operand); \ + MemWriteByte (address, (unsigned char)operand) + +/* AC opcode helpers */ + +/* #imm */ +#define AC_OP_IMM(op) \ + unsigned char immediate; \ + MEM_AD_OP_IMM(immediate); \ + Cycles = 2; \ + Regs.AC = Regs.AC op immediate; \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC) + +/* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y / (zp) */ +#define AC_OP(mode, op) \ + unsigned address; \ + unsigned operand; \ + Cycles = ALU_CY_##mode; \ + MEM_AD_OP(mode, address, operand); \ + Regs.AC = Regs.AC op operand; \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC) + + /* ADC */ #define ADC(v) \ do { \ @@ -248,7 +685,7 @@ static unsigned HaveIRQRequest; } \ TEST_CF (Regs.AC); \ SET_OF ((res < -128) || (res > 127)); \ - if (CPU != CPU_6502) { \ + if (CPU == CPU_65C02) { \ ++Cycles; \ } \ } else { \ @@ -271,7 +708,7 @@ static unsigned HaveIRQRequest; ++Cycles; \ Offs = (signed char) MemReadByte (Regs.PC+1); \ OldPCH = PCH; \ - Regs.PC += 2 + (int) Offs; \ + Regs.PC = (Regs.PC + 2 + (int) Offs) & 0xFFFF; \ if (PCH != OldPCH) { \ ++Cycles; \ } \ @@ -280,14 +717,22 @@ static unsigned HaveIRQRequest; } /* compares */ -#define CMP(v1, v2) \ +#define COMPARE(v1, v2) \ do { \ unsigned Result = v1 - v2; \ - TEST_ZF (Result & 0xFF); \ + TEST_ZF (Result); \ TEST_SF (Result); \ SET_CF (Result <= 0xFF); \ } while (0) +#define CPX(operand) \ + COMPARE (Regs.XR, operand) + +#define CPY(operand) \ + COMPARE (Regs.YR, operand) + +#define CMP(operand) \ + COMPARE (Regs.AC, operand) /* ROL */ #define ROL(Val) \ @@ -309,38 +754,243 @@ static unsigned HaveIRQRequest; TEST_ZF (Val); \ TEST_SF (Val) -/* SBC */ -#define SBC(v) \ +/* ASL */ +#define ASL(Val) \ + SET_CF (Val & 0x80); \ + Val = (Val << 1) & 0xFF; \ + TEST_ZF (Val); \ + TEST_SF (Val) + +/* LSR */ +#define LSR(Val) \ + SET_CF (Val & 0x01); \ + Val >>= 1; \ + TEST_ZF (Val); \ + TEST_SF (Val) + +/* INC */ +#define INC(Val) \ + Val = (Val + 1) & 0xFF; \ + TEST_ZF (Val); \ + TEST_SF (Val) + +/* DEC */ +#define DEC(Val) \ + Val = (Val - 1) & 0xFF; \ + TEST_ZF (Val); \ + TEST_SF (Val) + +/* SLO */ +#define SLO(Val) \ + Val <<= 1; \ + SET_CF (Val & 0x100); \ + Regs.AC |= Val; \ + Regs.AC &= 0xFF; \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC) + +/* RLA */ +#define RLA(Val) \ + Val <<= 1; \ + if (GET_CF ()) { \ + Val |= 0x01; \ + } \ + SET_CF (Val & 0x100); \ + Regs.AC &= Val; \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC) + +/* SRE */ +#define SRE(Val) \ + SET_CF (Val & 0x01); \ + Val >>= 1; \ + Regs.AC ^= Val; \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC) + +/* RRA */ +#define RRA(Val) \ + if (GET_CF ()) { \ + Val |= 0x100; \ + } \ + SET_CF (Val & 0x01); \ + Val >>= 1; \ + ADC (Val) + +/* BIT */ +#define BIT(Val) \ + SET_SF (Val & 0x80); \ + SET_OF (Val & 0x40); \ + SET_ZF ((Val & Regs.AC) == 0) + +/* LDA */ +#define LDA(Val) \ + Regs.AC = Val; \ + TEST_SF (Val); \ + TEST_ZF (Val) + +/* LDX */ +#define LDX(Val) \ + Regs.XR = Val; \ + TEST_SF (Val); \ + TEST_ZF (Val) + +/* LDY */ +#define LDY(Val) \ + Regs.YR = Val; \ + TEST_SF (Val); \ + TEST_ZF (Val) + +/* LAX */ +#define LAX(Val) \ + Regs.AC = Val; \ + Regs.XR = Val; \ + TEST_SF (Val); \ + TEST_ZF (Val) + +/* TSB */ +#define TSB(Val) \ + SET_ZF ((Val & Regs.AC) == 0); \ + Val |= Regs.AC + +/* TRB */ +#define TRB(Val) \ + SET_ZF ((Val & Regs.AC) == 0); \ + Val &= ~Regs.AC + +/* DCP */ +#define DCP(Val) \ + Val = (Val - 1) & 0xFF; \ + COMPARE (Regs.AC, Val) + +/* ISC */ +#define ISC(Val) \ + Val = (Val + 1) & 0xFF; \ + SBC(Val) + +/* ASR */ +#define ASR(Val) \ + Regs.AC &= Val; \ + LSR(Regs.AC) + +/* ARR */ +#define ARR(Val) \ do { \ - unsigned old = Regs.AC; \ - unsigned rhs = (v & 0xFF); \ + unsigned tmp = Regs.AC & Val; \ + Val = tmp >> 1; \ + if (GET_CF ()) { \ + Val |= 0x80; \ + } \ if (GET_DF ()) { \ - unsigned lo; \ - int res; \ - lo = (old & 0x0F) - (rhs & 0x0F) + GET_CF () - 1; \ - if (lo & 0x80) { \ - lo = ((lo - 0x06) & 0x0F) - 0x10; \ + SET_SF (GET_CF ()); \ + TEST_ZF (Val); \ + SET_OF ((Val ^ tmp) & 0x40); \ + if (((tmp & 0x0f) + (tmp & 0x01)) > 0x05) { \ + Val = (Val & 0xf0) | ((Val + 0x06) & 0x0f); \ } \ - Regs.AC = (old & 0xF0) - (rhs & 0xF0) + lo; \ - if (Regs.AC & 0x80) { \ - Regs.AC -= 0x60; \ + if (((tmp & 0xf0) + (tmp & 0x10)) > 0x50) { \ + Val = (Val & 0x0f) | ((Val + 0x60) & 0xf0); \ + SET_CF(1); \ + } else { \ + SET_CF(0); \ } \ - res = Regs.AC - rhs + (!GET_CF ()); \ - TEST_ZF (res); \ - TEST_SF (res); \ - SET_CF (res <= 0xFF); \ - SET_OF (((old^rhs) & (old^res) & 0x80)); \ - if (CPU != CPU_6502) { \ + if (CPU == CPU_65C02) { \ ++Cycles; \ } \ } else { \ - Regs.AC -= rhs + (!GET_CF ()); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ - SET_CF (Regs.AC <= 0xFF); \ - SET_OF (((old^rhs) & (old^Regs.AC) & 0x80)); \ - Regs.AC &= 0xFF; \ + TEST_SF (Val); \ + TEST_ZF (Val); \ + SET_CF (Val & 0x40); \ + SET_OF ((Val & 0x40) ^ ((Val & 0x20) << 1)); \ } \ + Regs.AC = Val; \ + } while (0); + +/* ANE */ +#define ANE(Val) \ + Val = (Regs.AC | 0xEF) & Regs.XR & Val; \ + Regs.AC = Val; \ + TEST_SF (Val); \ + TEST_ZF (Val) + +/* LXA */ +#define LXA(Val) \ + Val = (Regs.AC | 0xEE) & Val; \ + Regs.AC = Val; \ + Regs.XR = Val; \ + TEST_SF (Val); \ + TEST_ZF (Val) + +/* SBX */ +#define SBX(Val) \ + do { \ + unsigned tmp = (Regs.AC & Regs.XR) - (Val); \ + SET_CF (tmp < 0x100); \ + tmp &= 0xFF; \ + Regs.XR = tmp; \ + TEST_SF (tmp); \ + TEST_ZF (tmp); \ + } while (0); + +/* NOP */ +#define NOP(Val) \ + (void)Val + +/* TAS */ +#define TAS(Val) \ + Val = Regs.AC & Regs.XR; \ + Regs.SP = Val; \ + Val &= (address >> 8) + 1 + +/* SHA */ +#define SHA(Val) \ + Val = Regs.AC & Regs.XR & ((address >> 8) + 1) + +/* ANC */ +#define ANC(Val) \ + Val = Regs.AC & Val; \ + Regs.AC = Val; \ + SET_CF (Val & 0x80); \ + TEST_SF (Val); \ + TEST_ZF (Val) + + +/* LAS */ +#define LAS(Val) \ + Val = Regs.SP & Val; \ + Regs.AC = Val; \ + Regs.XR = Val; \ + Regs.SP = Val; \ + TEST_SF (Val); \ + TEST_ZF (Val) + + +/* SBC */ +#define SBC(v) \ + do { \ + unsigned r_a = Regs.AC; \ + unsigned src = (v) & 0xFF; \ + unsigned ccc = (Regs.SR & CF) ^ CF; \ + unsigned tmp = r_a - src - ccc; \ + \ + SET_CF(tmp < 0x100); \ + TEST_SF(tmp); \ + TEST_ZF(tmp); \ + SET_OF((r_a ^ tmp) & (r_a ^ src) & 0x80); \ + \ + if (GET_DF ()) { \ + unsigned low = (r_a & 0x0f) - (src & 0x0f) - ccc; \ + tmp = (r_a & 0xf0) - (src & 0xf0); \ + if (low & 0x10) { \ + low -= 6; \ + tmp -= 0x10; \ + } \ + tmp = (low & 0xf) | tmp; \ + if (tmp & 0x100) { \ + tmp -= 0x60; \ + } \ + } \ + Regs.AC = tmp & 0xFF; \ } while (0) @@ -368,7 +1018,7 @@ static void OPC_6502_00 (void) PUSH (PCL); PUSH (Regs.SR); SET_IF (1); - if (CPU != CPU_6502) + if (CPU == CPU_65C02) { SET_DF (0); } @@ -380,7 +1030,27 @@ static void OPC_6502_00 (void) static void OPC_6502_01 (void) /* Opcode $01: ORA (ind,x) */ { - AC_OP_ZPXIND (|); + AC_OP (ZPXIND, |); +} + + + +static void OPC_6502_03 (void) +/* Opcode $03: SLO (zp,x) */ +{ + ILLx2_OP (ZPXIND, SLO); +} + + + +/* Aliases of opcode $04 */ +#define OPC_6502_44 OPC_6502_04 +#define OPC_6502_64 OPC_6502_04 + +static void OPC_6502_04 (void) +/* Opcode $04: NOP zp */ +{ + ALU_OP (ZP, NOP); } @@ -388,14 +1058,7 @@ static void OPC_6502_01 (void) static void OPC_65SC02_04 (void) /* Opcode $04: TSB zp */ { - unsigned char ZPAddr; - unsigned char Val; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); - SET_ZF ((Val & Regs.AC) == 0); - MemWriteByte (ZPAddr, (unsigned char)(Val | Regs.AC)); - Regs.PC += 2; + MEM_OP (ZP, TSB); } @@ -403,7 +1066,7 @@ static void OPC_65SC02_04 (void) static void OPC_6502_05 (void) /* Opcode $05: ORA zp */ { - AC_OP_ZP (|); + AC_OP (ZP, |); } @@ -411,16 +1074,15 @@ static void OPC_6502_05 (void) static void OPC_6502_06 (void) /* Opcode $06: ASL zp */ { - unsigned char ZPAddr; - unsigned Val; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr) << 1; - MemWriteByte (ZPAddr, (unsigned char) Val); - TEST_ZF (Val & 0xFF); - TEST_SF (Val); - SET_CF (Val & 0x100); - Regs.PC += 2; + MEM_OP (ZP, ASL); +} + + + +static void OPC_6502_07 (void) +/* Opcode $07: SLO zp */ +{ + ILLx2_OP (ZP, SLO); } @@ -447,27 +1109,35 @@ static void OPC_6502_0A (void) /* Opcode $0A: ASL a */ { Cycles = 2; - Regs.AC <<= 1; - TEST_ZF (Regs.AC & 0xFF); - TEST_SF (Regs.AC); - SET_CF (Regs.AC & 0x100); - Regs.AC &= 0xFF; + ASL(Regs.AC); Regs.PC += 1; } +/* Aliases of opcode $0B */ +#define OPC_6502_2B OPC_6502_0B + +static void OPC_6502_0B (void) +/* Opcode $0B: ANC #imm */ +{ + ALU_OP_IMM (ANC); +} + + + +static void OPC_6502_0C (void) +/* Opcode $0C: NOP abs */ +{ + ALU_OP (ABS, NOP); +} + + + static void OPC_65SC02_0C (void) /* Opcode $0C: TSB abs */ { - unsigned Addr; - unsigned char Val; - Cycles = 6; - Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr); - SET_ZF ((Val & Regs.AC) == 0); - MemWriteByte (Addr, (unsigned char) (Val | Regs.AC)); - Regs.PC += 3; + MEM_OP (ABS, TSB); } @@ -475,24 +1145,23 @@ static void OPC_65SC02_0C (void) static void OPC_6502_0D (void) /* Opcode $0D: ORA abs */ { - AC_OP_ABS (|); + AC_OP (ABS, |); } static void OPC_6502_0E (void) -/* Opcode $0E: ALS abs */ +/* Opcode $0E: ASL abs */ { - unsigned Addr; - unsigned Val; - Cycles = 6; - Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr) << 1; - MemWriteByte (Addr, (unsigned char) Val); - TEST_ZF (Val & 0xFF); - TEST_SF (Val); - SET_CF (Val & 0x100); - Regs.PC += 3; + MEM_OP (ABS, ASL); +} + + + +static void OPC_6502_0F (void) +/* Opcode $0F: SLO abs */ +{ + ILLx2_OP (ABS, SLO); } @@ -508,7 +1177,7 @@ static void OPC_6502_10 (void) static void OPC_6502_11 (void) /* Opcode $11: ORA (zp),y */ { - AC_OP_ZPINDY (|); + AC_OP (ZPINDY, |); } @@ -516,7 +1185,30 @@ static void OPC_6502_11 (void) static void OPC_65SC02_12 (void) /* Opcode $12: ORA (zp) */ { - AC_OP_ZPIND (|); + AC_OP (ZPIND, |); +} + + + +static void OPC_6502_13 (void) +/* Opcode $03: SLO (zp),y */ +{ + ILLx2_OP (ZPINDY, SLO); +} + + + +/* Aliases of opcode $14 */ +#define OPC_6502_34 OPC_6502_14 +#define OPC_6502_54 OPC_6502_14 +#define OPC_6502_74 OPC_6502_14 +#define OPC_6502_D4 OPC_6502_14 +#define OPC_6502_F4 OPC_6502_14 + +static void OPC_6502_14 (void) +/* Opcode $04: NOP zp,x */ +{ + ALU_OP (ZPX, NOP); } @@ -524,14 +1216,7 @@ static void OPC_65SC02_12 (void) static void OPC_65SC02_14 (void) /* Opcode $14: TRB zp */ { - unsigned char ZPAddr; - unsigned char Val; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); - SET_ZF ((Val & Regs.AC) == 0); - MemWriteByte (ZPAddr, (unsigned char)(Val & ~Regs.AC)); - Regs.PC += 2; + MEM_OP (ZP, TRB); } @@ -539,7 +1224,7 @@ static void OPC_65SC02_14 (void) static void OPC_6502_15 (void) /* Opcode $15: ORA zp,x */ { - AC_OP_ZPX (|); + AC_OP (ZPX, |); } @@ -547,16 +1232,15 @@ static void OPC_6502_15 (void) static void OPC_6502_16 (void) /* Opcode $16: ASL zp,x */ { - unsigned char ZPAddr; - unsigned Val; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr) << 1; - MemWriteByte (ZPAddr, (unsigned char) Val); - TEST_ZF (Val & 0xFF); - TEST_SF (Val); - SET_CF (Val & 0x100); - Regs.PC += 2; + MEM_OP (ZPX, ASL); +} + + + +static void OPC_6502_17 (void) +/* Opcode $17: SLO zp,x */ +{ + ILLx2_OP (ZPX, SLO); } @@ -574,7 +1258,7 @@ static void OPC_6502_18 (void) static void OPC_6502_19 (void) /* Opcode $19: ORA abs,y */ { - AC_OP_ABSY (|); + AC_OP (ABSY, |); } @@ -583,25 +1267,39 @@ static void OPC_65SC02_1A (void) /* Opcode $1A: INC a */ { Cycles = 2; - Regs.AC = (Regs.AC + 1) & 0xFF; - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); + INC(Regs.AC); Regs.PC += 1; } +static void OPC_6502_1B (void) +/* Opcode $1B: SLO abs,y */ +{ + ILLx2_OP (ABSY, SLO); +} + + + +/* Aliases of opcode $1C */ +#define OPC_6502_3C OPC_6502_1C +#define OPC_6502_5C OPC_6502_1C +#define OPC_6502_7C OPC_6502_1C +#define OPC_6502_DC OPC_6502_1C +#define OPC_6502_FC OPC_6502_1C + +static void OPC_6502_1C (void) +/* Opcode $1C: NOP abs,x */ +{ + ALU_OP (ABSX, NOP); +} + + + static void OPC_65SC02_1C (void) /* Opcode $1C: TRB abs */ { - unsigned Addr; - unsigned char Val; - Cycles = 6; - Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr); - SET_ZF ((Val & Regs.AC) == 0); - MemWriteByte (Addr, (unsigned char) (Val & ~Regs.AC)); - Regs.PC += 3; + MEM_OP (ABS, TRB); } @@ -609,7 +1307,7 @@ static void OPC_65SC02_1C (void) static void OPC_6502_1D (void) /* Opcode $1D: ORA abs,x */ { - AC_OP_ABSX (|); + AC_OP (ABSX, |); } @@ -617,18 +1315,23 @@ static void OPC_6502_1D (void) static void OPC_6502_1E (void) /* Opcode $1E: ASL abs,x */ { - unsigned Addr; - unsigned Val; - Cycles = 7; - Addr = MemReadWord (Regs.PC+1) + Regs.XR; - if (CPU != CPU_6502 && !PAGE_CROSS (Addr, Regs.XR)) - --Cycles; - Val = MemReadByte (Addr) << 1; - MemWriteByte (Addr, (unsigned char) Val); - TEST_ZF (Val & 0xFF); - TEST_SF (Val); - SET_CF (Val & 0x100); - Regs.PC += 3; + MEM_OP (ABSX, ASL); +} + + + +static void OPC_65C02_1E (void) +/* Opcode $1E: ASL abs,x */ +{ + MEM_OP (ABSX_NP, ASL); +} + + + +static void OPC_6502_1F (void) +/* Opcode $1F: SLO abs,x */ +{ + ILLx2_OP (ABSX, SLO); } @@ -652,23 +1355,23 @@ static void OPC_6502_20 (void) static void OPC_6502_21 (void) /* Opcode $21: AND (zp,x) */ { - AC_OP_ZPXIND (&); + AC_OP (ZPXIND, &); +} + + + +static void OPC_6502_23 (void) +/* Opcode $23: RLA (zp,x) */ +{ + ILLx2_OP (ZPXIND, RLA); } static void OPC_6502_24 (void) -/* Opcode $24: BIT zp */ { - unsigned char ZPAddr; - unsigned char Val; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); - SET_SF (Val & 0x80); - SET_OF (Val & 0x40); - SET_ZF ((Val & Regs.AC) == 0); - Regs.PC += 2; +/* Opcode $24: BIT zp */ + ALU_OP (ZP, BIT); } @@ -676,7 +1379,7 @@ static void OPC_6502_24 (void) static void OPC_6502_25 (void) /* Opcode $25: AND zp */ { - AC_OP_ZP (&); + AC_OP (ZP, &); } @@ -684,14 +1387,15 @@ static void OPC_6502_25 (void) static void OPC_6502_26 (void) /* Opcode $26: ROL zp */ { - unsigned char ZPAddr; - unsigned Val; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); - ROL (Val); - MemWriteByte (ZPAddr, Val); - Regs.PC += 2; + MEM_OP (ZP, ROL); +} + + + +static void OPC_6502_27 (void) +/* Opcode $27: RLA zp */ +{ + ILLx2_OP (ZP, RLA); } @@ -730,15 +1434,7 @@ static void OPC_6502_2A (void) static void OPC_6502_2C (void) /* Opcode $2C: BIT abs */ { - unsigned Addr; - unsigned char Val; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr); - SET_SF (Val & 0x80); - SET_OF (Val & 0x40); - SET_ZF ((Val & Regs.AC) == 0); - Regs.PC += 3; + ALU_OP (ABS, BIT); } @@ -746,7 +1442,7 @@ static void OPC_6502_2C (void) static void OPC_6502_2D (void) /* Opcode $2D: AND abs */ { - AC_OP_ABS (&); + AC_OP (ABS, &); } @@ -754,14 +1450,15 @@ static void OPC_6502_2D (void) static void OPC_6502_2E (void) /* Opcode $2E: ROL abs */ { - unsigned Addr; - unsigned Val; - Cycles = 6; - Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr); - ROL (Val); - MemWriteByte (Addr, Val); - Regs.PC += 3; + MEM_OP (ABS, ROL); +} + + + +static void OPC_6502_2F (void) +/* Opcode $2F: RLA abs */ +{ + ILLx2_OP (ABS, RLA); } @@ -777,7 +1474,7 @@ static void OPC_6502_30 (void) static void OPC_6502_31 (void) /* Opcode $31: AND (zp),y */ { - AC_OP_ZPINDY (&); + AC_OP (ZPINDY, &); } @@ -785,7 +1482,15 @@ static void OPC_6502_31 (void) static void OPC_65SC02_32 (void) /* Opcode $32: AND (zp) */ { - AC_OP_ZPIND (&); + AC_OP (ZPIND, &); +} + + + +static void OPC_6502_33 (void) +/* Opcode $33: RLA (zp),y */ +{ + ILLx2_OP (ZPINDY, RLA); } @@ -793,15 +1498,7 @@ static void OPC_65SC02_32 (void) static void OPC_65SC02_34 (void) /* Opcode $34: BIT zp,x */ { - unsigned char ZPAddr; - unsigned char Val; - Cycles = 4; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr); - SET_SF (Val & 0x80); - SET_OF (Val & 0x40); - SET_ZF ((Val & Regs.AC) == 0); - Regs.PC += 2; + ALU_OP (ZPX, BIT); } @@ -809,7 +1506,7 @@ static void OPC_65SC02_34 (void) static void OPC_6502_35 (void) /* Opcode $35: AND zp,x */ { - AC_OP_ZPX (&); + AC_OP (ZPX, &); } @@ -817,14 +1514,15 @@ static void OPC_6502_35 (void) static void OPC_6502_36 (void) /* Opcode $36: ROL zp,x */ { - unsigned char ZPAddr; - unsigned Val; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr); - ROL (Val); - MemWriteByte (ZPAddr, Val); - Regs.PC += 2; + MEM_OP (ZPX, ROL); +} + + + +static void OPC_6502_37 (void) +/* Opcode $37: RLA zp,x */ +{ + ILLx2_OP (ZPX, RLA); } @@ -842,7 +1540,7 @@ static void OPC_6502_38 (void) static void OPC_6502_39 (void) /* Opcode $39: AND abs,y */ { - AC_OP_ABSY (&); + AC_OP (ABSY, &); } @@ -851,28 +1549,24 @@ static void OPC_65SC02_3A (void) /* Opcode $3A: DEC a */ { Cycles = 2; - Regs.AC = (Regs.AC - 1) & 0xFF; - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); + DEC (Regs.AC); Regs.PC += 1; } +static void OPC_6502_3B (void) +/* Opcode $3B: RLA abs,y */ +{ + ILLx2_OP (ABSY, RLA); +} + + + static void OPC_65SC02_3C (void) /* Opcode $3C: BIT abs,x */ { - unsigned Addr; - unsigned char Val; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - if (PAGE_CROSS (Addr, Regs.XR)) - ++Cycles; - Val = MemReadByte (Addr + Regs.XR); - SET_SF (Val & 0x80); - SET_OF (Val & 0x40); - SET_ZF ((Val & Regs.AC) == 0); - Regs.PC += 3; + ALU_OP (ABSX, BIT); } @@ -880,7 +1574,7 @@ static void OPC_65SC02_3C (void) static void OPC_6502_3D (void) /* Opcode $3D: AND abs,x */ { - AC_OP_ABSX (&); + AC_OP (ABSX, &); } @@ -888,16 +1582,23 @@ static void OPC_6502_3D (void) static void OPC_6502_3E (void) /* Opcode $3E: ROL abs,x */ { - unsigned Addr; - unsigned Val; - Cycles = 7; - Addr = MemReadWord (Regs.PC+1) + Regs.XR; - if (CPU != CPU_6502 && !PAGE_CROSS (Addr, Regs.XR)) - --Cycles; - Val = MemReadByte (Addr); - ROL (Val); - MemWriteByte (Addr, Val); - Regs.PC += 2; + MEM_OP (ABSX, ROL); +} + + + +static void OPC_65C02_3E (void) +/* Opcode $3E: ROL abs,x */ +{ + MEM_OP (ABSX_NP, ROL); +} + + + +static void OPC_6502_3F (void) +/* Opcode $3B: RLA abs,x */ +{ + ILLx2_OP (ABSX, RLA); } @@ -918,16 +1619,15 @@ static void OPC_6502_40 (void) static void OPC_6502_41 (void) /* Opcode $41: EOR (zp,x) */ { - AC_OP_ZPXIND (^); + AC_OP (ZPXIND, ^); } -static void OPC_65C02_44 (void) -/* Opcode $44: 'zp' 3 cycle NOP */ +static void OPC_6502_43 (void) +/* Opcode $43: SRE (zp,x) */ { - Cycles = 3; - Regs.PC += 2; + ILLx2_OP (ZPXIND, SRE); } @@ -935,7 +1635,7 @@ static void OPC_65C02_44 (void) static void OPC_6502_45 (void) /* Opcode $45: EOR zp */ { - AC_OP_ZP (^); + AC_OP (ZP, ^); } @@ -943,17 +1643,15 @@ static void OPC_6502_45 (void) static void OPC_6502_46 (void) /* Opcode $46: LSR zp */ { - unsigned char ZPAddr; - unsigned char Val; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); - SET_CF (Val & 0x01); - Val >>= 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 2; + MEM_OP (ZP, LSR); +} + + + +static void OPC_6502_47 (void) +/* Opcode $47: SRE zp */ +{ + ILLx2_OP (ZP, SRE); } @@ -980,15 +1678,20 @@ static void OPC_6502_4A (void) /* Opcode $4A: LSR a */ { Cycles = 2; - SET_CF (Regs.AC & 0x01); - Regs.AC >>= 1; - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); + LSR (Regs.AC); Regs.PC += 1; } +static void OPC_6502_4B (void) +/* Opcode $4B: ASR imm */ +{ + ALU_OP_IMM (ASR); +} + + + static void OPC_6502_4C (void) /* Opcode $4C: JMP abs */ { @@ -1003,7 +1706,7 @@ static void OPC_6502_4C (void) static void OPC_6502_4D (void) /* Opcode $4D: EOR abs */ { - AC_OP_ABS (^); + AC_OP (ABS, ^); } @@ -1011,17 +1714,15 @@ static void OPC_6502_4D (void) static void OPC_6502_4E (void) /* Opcode $4E: LSR abs */ { - unsigned Addr; - unsigned char Val; - Cycles = 6; - Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr); - SET_CF (Val & 0x01); - Val >>= 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 3; + MEM_OP (ABS, LSR); +} + + + +static void OPC_6502_4F (void) +/* Opcode $4F: SRE abs */ +{ + ILLx2_OP (ABS, SRE); } @@ -1037,7 +1738,7 @@ static void OPC_6502_50 (void) static void OPC_6502_51 (void) /* Opcode $51: EOR (zp),y */ { - AC_OP_ZPINDY (^); + AC_OP (ZPINDY, ^); } @@ -1045,7 +1746,15 @@ static void OPC_6502_51 (void) static void OPC_65SC02_52 (void) /* Opcode $52: EOR (zp) */ { - AC_OP_ZPIND (^); + AC_OP (ZPIND, ^); +} + + + +static void OPC_6502_53 (void) +/* Opcode $43: SRE (zp),y */ +{ + ILLx2_OP (ZPINDY, SRE); } @@ -1053,7 +1762,7 @@ static void OPC_65SC02_52 (void) static void OPC_6502_55 (void) /* Opcode $55: EOR zp,x */ { - AC_OP_ZPX (^); + AC_OP (ZPX, ^); } @@ -1061,17 +1770,15 @@ static void OPC_6502_55 (void) static void OPC_6502_56 (void) /* Opcode $56: LSR zp,x */ { - unsigned char ZPAddr; - unsigned char Val; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr); - SET_CF (Val & 0x01); - Val >>= 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 2; + MEM_OP (ZPX, LSR); +} + + + +static void OPC_6502_57 (void) +/* Opcode $57: SRE zp,x */ +{ + ILLx2_OP (ZPX, SRE); } @@ -1089,7 +1796,7 @@ static void OPC_6502_58 (void) static void OPC_6502_59 (void) /* Opcode $59: EOR abs,y */ { - AC_OP_ABSY (^); + AC_OP (ABSY, ^); } @@ -1104,6 +1811,14 @@ static void OPC_65SC02_5A (void) +static void OPC_6502_5B (void) +/* Opcode $5B: SRE abs,y */ +{ + ILLx2_OP (ABSY, SRE); +} + + + static void OPC_65C02_5C (void) /* Opcode $5C: 'Absolute' 8 cycle NOP */ { @@ -1116,7 +1831,7 @@ static void OPC_65C02_5C (void) static void OPC_6502_5D (void) /* Opcode $5D: EOR abs,x */ { - AC_OP_ABSX (^); + AC_OP (ABSX, ^); } @@ -1124,19 +1839,23 @@ static void OPC_6502_5D (void) static void OPC_6502_5E (void) /* Opcode $5E: LSR abs,x */ { - unsigned Addr; - unsigned char Val; - Cycles = 7; - Addr = MemReadWord (Regs.PC+1) + Regs.XR; - if (CPU != CPU_6502 && !PAGE_CROSS (Addr, Regs.XR)) - --Cycles; - Val = MemReadByte (Addr); - SET_CF (Val & 0x01); - Val >>= 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 3; + MEM_OP (ABSX, LSR); +} + + + +static void OPC_65C02_5E (void) +/* Opcode $5E: LSR abs,x */ +{ + MEM_OP (ABSX_NP, LSR); +} + + + +static void OPC_6502_5F (void) +/* Opcode $5F: SRE abs,x */ +{ + ILLx2_OP (ABSX, SRE); } @@ -1155,13 +1874,15 @@ static void OPC_6502_60 (void) static void OPC_6502_61 (void) /* Opcode $61: ADC (zp,x) */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Addr = MemReadZPWord (ZPAddr); - ADC (MemReadByte (Addr)); - Regs.PC += 2; + ALU_OP (ZPXIND, ADC); +} + + + +static void OPC_6502_63 (void) +/* Opcode $63: RRA (zp,x) */ +{ + ILLx2_OP (ZPXIND, RRA); } @@ -1169,11 +1890,7 @@ static void OPC_6502_61 (void) static void OPC_65SC02_64 (void) /* Opcode $64: STZ zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - MemWriteByte (ZPAddr, 0); - Regs.PC += 2; + STO_OP (ZP, 0); } @@ -1181,11 +1898,7 @@ static void OPC_65SC02_64 (void) static void OPC_6502_65 (void) /* Opcode $65: ADC zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - ADC (MemReadByte (ZPAddr)); - Regs.PC += 2; + ALU_OP (ZP, ADC); } @@ -1193,14 +1906,15 @@ static void OPC_6502_65 (void) static void OPC_6502_66 (void) /* Opcode $66: ROR zp */ { - unsigned char ZPAddr; - unsigned Val; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr); - ROR (Val); - MemWriteByte (ZPAddr, Val); - Regs.PC += 2; + MEM_OP (ZP, ROR); +} + + + +static void OPC_6502_67 (void) +/* Opcode $67: RRA zp */ +{ + ILLx2_OP (ZP, RRA); } @@ -1220,9 +1934,7 @@ static void OPC_6502_68 (void) static void OPC_6502_69 (void) /* Opcode $69: ADC #imm */ { - Cycles = 2; - ADC (MemReadByte (Regs.PC+1)); - Regs.PC += 2; + ALU_OP_IMM (ADC); } @@ -1237,6 +1949,14 @@ static void OPC_6502_6A (void) +static void OPC_6502_6B (void) +/* Opcode $6B: ARR imm */ +{ + ALU_OP_IMM (ARR); +} + + + static void OPC_6502_6C (void) /* Opcode $6C: JMP (ind) */ { @@ -1285,11 +2005,7 @@ static void OPC_65C02_6C (void) static void OPC_6502_6D (void) /* Opcode $6D: ADC abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - ADC (MemReadByte (Addr)); - Regs.PC += 3; + ALU_OP (ABS, ADC); } @@ -1297,14 +2013,15 @@ static void OPC_6502_6D (void) static void OPC_6502_6E (void) /* Opcode $6E: ROR abs */ { - unsigned Addr; - unsigned Val; - Cycles = 6; - Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr); - ROR (Val); - MemWriteByte (Addr, Val); - Regs.PC += 3; + MEM_OP (ABS, ROR); +} + + + +static void OPC_6502_6F (void) +/* Opcode $6F: RRA abs */ +{ + ILLx2_OP (ABS, RRA); } @@ -1320,16 +2037,7 @@ static void OPC_6502_70 (void) static void OPC_6502_71 (void) /* Opcode $71: ADC (zp),y */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); - if (PAGE_CROSS (Addr, Regs.YR)) { - ++Cycles; - } - ADC (MemReadByte (Addr + Regs.YR)); - Regs.PC += 2; + ALU_OP (ZPINDY, ADC); } @@ -1337,13 +2045,15 @@ static void OPC_6502_71 (void) static void OPC_65SC02_72 (void) /* Opcode $72: ADC (zp) */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); - ADC (MemReadByte (Addr)); - Regs.PC += 2; + ALU_OP (ZPIND, ADC); +} + + + +static void OPC_6502_73 (void) +/* Opcode $73: RRA (zp),y */ +{ + ILLx2_OP (ZPINDY, RRA); } @@ -1351,11 +2061,7 @@ static void OPC_65SC02_72 (void) static void OPC_65SC02_74 (void) /* Opcode $74: STZ zp,x */ { - unsigned char ZPAddr; - Cycles = 4; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - MemWriteByte (ZPAddr, 0); - Regs.PC += 2; + STO_OP (ZPX, 0); } @@ -1363,11 +2069,7 @@ static void OPC_65SC02_74 (void) static void OPC_6502_75 (void) /* Opcode $75: ADC zp,x */ { - unsigned char ZPAddr; - Cycles = 4; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - ADC (MemReadByte (ZPAddr)); - Regs.PC += 2; + ALU_OP (ZPX, ADC); } @@ -1375,14 +2077,15 @@ static void OPC_6502_75 (void) static void OPC_6502_76 (void) /* Opcode $76: ROR zp,x */ { - unsigned char ZPAddr; - unsigned Val; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr); - ROR (Val); - MemWriteByte (ZPAddr, Val); - Regs.PC += 2; + MEM_OP (ZPX, ROR); +} + + + +static void OPC_6502_77 (void) +/* Opcode $77: RRA zp,x */ +{ + ILLx2_OP (ZPX, RRA); } @@ -1400,14 +2103,7 @@ static void OPC_6502_78 (void) static void OPC_6502_79 (void) /* Opcode $79: ADC abs,y */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - if (PAGE_CROSS (Addr, Regs.YR)) { - ++Cycles; - } - ADC (MemReadByte (Addr + Regs.YR)); - Regs.PC += 3; + ALU_OP (ABSY, ADC); } @@ -1424,6 +2120,14 @@ static void OPC_65SC02_7A (void) +static void OPC_6502_7B (void) +/* Opcode $7B: RRA abs,y */ +{ + ILLx2_OP (ABSY, RRA); +} + + + static void OPC_65SC02_7C (void) /* Opcode $7C: JMP (ind,X) */ { @@ -1441,14 +2145,7 @@ static void OPC_65SC02_7C (void) static void OPC_6502_7D (void) /* Opcode $7D: ADC abs,x */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - if (PAGE_CROSS (Addr, Regs.XR)) { - ++Cycles; - } - ADC (MemReadByte (Addr + Regs.XR)); - Regs.PC += 3; + ALU_OP (ABSX, ADC); } @@ -1456,16 +2153,37 @@ static void OPC_6502_7D (void) static void OPC_6502_7E (void) /* Opcode $7E: ROR abs,x */ { - unsigned Addr; - unsigned Val; - Cycles = 7; - Addr = MemReadWord (Regs.PC+1) + Regs.XR; - if (CPU != CPU_6502 && !PAGE_CROSS (Addr, Regs.XR)) - --Cycles; - Val = MemReadByte (Addr); - ROR (Val); - MemWriteByte (Addr, Val); - Regs.PC += 3; + MEM_OP (ABSX, ROR); +} + + + +static void OPC_65C02_7E (void) +/* Opcode $7E: ROR abs,x */ +{ + MEM_OP (ABSX_NP, ROR); +} + + + +static void OPC_6502_7F (void) +/* Opcode $7F: RRA abs,x */ +{ + ILLx2_OP (ABSX, RRA); +} + + + +/* Aliases of opcode $80 */ +#define OPC_6502_82 OPC_6502_80 +#define OPC_6502_C2 OPC_6502_80 +#define OPC_6502_E2 OPC_6502_80 +#define OPC_6502_89 OPC_6502_80 + +static void OPC_6502_80 (void) +/* Opcode $80: NOP imm */ +{ + ALU_OP_IMM (NOP); } @@ -1481,13 +2199,15 @@ static void OPC_65SC02_80 (void) static void OPC_6502_81 (void) /* Opcode $81: STA (zp,x) */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Addr = MemReadZPWord (ZPAddr); - MemWriteByte (Addr, Regs.AC); - Regs.PC += 2; + STO_OP (ZPXIND, Regs.AC); +} + + + +static void OPC_6502_83 (void) +/* Opcode $83: SAX (zp,x) */ +{ + STO_OP (ZPXIND, Regs.AC & Regs.XR); } @@ -1495,11 +2215,7 @@ static void OPC_6502_81 (void) static void OPC_6502_84 (void) /* Opcode $84: STY zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - MemWriteByte (ZPAddr, Regs.YR); - Regs.PC += 2; + STO_OP (ZP, Regs.YR); } @@ -1507,11 +2223,7 @@ static void OPC_6502_84 (void) static void OPC_6502_85 (void) /* Opcode $85: STA zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - MemWriteByte (ZPAddr, Regs.AC); - Regs.PC += 2; + STO_OP (ZP, Regs.AC); } @@ -1519,11 +2231,15 @@ static void OPC_6502_85 (void) static void OPC_6502_86 (void) /* Opcode $86: STX zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - MemWriteByte (ZPAddr, Regs.XR); - Regs.PC += 2; + STO_OP (ZP, Regs.XR); +} + + + +static void OPC_6502_87 (void) +/* Opcode $87: SAX zp */ +{ + STO_OP (ZP, Regs.AC & Regs.XR); } @@ -1532,9 +2248,7 @@ static void OPC_6502_88 (void) /* Opcode $88: DEY */ { Cycles = 2; - Regs.YR = (Regs.YR - 1) & 0xFF; - TEST_ZF (Regs.YR); - TEST_SF (Regs.YR); + DEC (Regs.YR); Regs.PC += 1; } @@ -1543,13 +2257,7 @@ static void OPC_6502_88 (void) static void OPC_65SC02_89 (void) /* Opcode $89: BIT #imm */ { - unsigned char Val; - Cycles = 2; - Val = MemReadByte (Regs.PC+1); - SET_SF (Val & 0x80); - SET_OF (Val & 0x40); - SET_ZF ((Val & Regs.AC) == 0); - Regs.PC += 2; + ALU_OP_IMM (BIT); } @@ -1566,14 +2274,18 @@ static void OPC_6502_8A (void) +static void OPC_6502_8B (void) +/* Opcode $8B: ANE imm */ +{ + ALU_OP_IMM (ANE); +} + + + static void OPC_6502_8C (void) /* Opcode $8C: STY abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - MemWriteByte (Addr, Regs.YR); - Regs.PC += 3; + STO_OP (ABS, Regs.YR); } @@ -1581,11 +2293,7 @@ static void OPC_6502_8C (void) static void OPC_6502_8D (void) /* Opcode $8D: STA abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - MemWriteByte (Addr, Regs.AC); - Regs.PC += 3; + STO_OP (ABS, Regs.AC); } @@ -1593,11 +2301,15 @@ static void OPC_6502_8D (void) static void OPC_6502_8E (void) /* Opcode $8E: STX abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - MemWriteByte (Addr, Regs.XR); - Regs.PC += 3; + STO_OP (ABS, Regs.XR); +} + + + +static void OPC_6502_8F (void) +/* Opcode $8F: SAX abs */ +{ + STO_OP (ABS, Regs.AC & Regs.XR); } @@ -1613,13 +2325,7 @@ static void OPC_6502_90 (void) static void OPC_6502_91 (void) /* Opcode $91: sta (zp),y */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr) + Regs.YR; - MemWriteByte (Addr, Regs.AC); - Regs.PC += 2; + STO_OP (ZPINDY, Regs.AC); } @@ -1627,13 +2333,15 @@ static void OPC_6502_91 (void) static void OPC_65SC02_92 (void) /* Opcode $92: sta (zp) */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); - MemWriteByte (Addr, Regs.AC); - Regs.PC += 2; + STO_OP (ZPIND, Regs.AC); +} + + + +static void OPC_6502_93 (void) +/* Opcode $93: SHA (zp),y */ +{ + STO_CB (ZPINDY, SHA); } @@ -1641,11 +2349,7 @@ static void OPC_65SC02_92 (void) static void OPC_6502_94 (void) /* Opcode $94: STY zp,x */ { - unsigned char ZPAddr; - Cycles = 4; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - MemWriteByte (ZPAddr, Regs.YR); - Regs.PC += 2; + STO_OP (ZPX, Regs.YR); } @@ -1653,11 +2357,7 @@ static void OPC_6502_94 (void) static void OPC_6502_95 (void) /* Opcode $95: STA zp,x */ { - unsigned char ZPAddr; - Cycles = 4; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - MemWriteByte (ZPAddr, Regs.AC); - Regs.PC += 2; + STO_OP (ZPX, Regs.AC); } @@ -1665,11 +2365,15 @@ static void OPC_6502_95 (void) static void OPC_6502_96 (void) /* Opcode $96: stx zp,y */ { - unsigned char ZPAddr; - Cycles = 4; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR; - MemWriteByte (ZPAddr, Regs.XR); - Regs.PC += 2; + STO_OP (ZPY, Regs.XR); +} + + + +static void OPC_6502_97 (void) +/* Opcode $97: SAX zp,y */ +{ + STO_OP (ZPY, Regs.AC & Regs.XR); } @@ -1689,11 +2393,7 @@ static void OPC_6502_98 (void) static void OPC_6502_99 (void) /* Opcode $99: STA abs,y */ { - unsigned Addr; - Cycles = 5; - Addr = MemReadWord (Regs.PC+1) + Regs.YR; - MemWriteByte (Addr, Regs.AC); - Regs.PC += 3; + STO_OP (ABSY, Regs.AC); } @@ -1708,14 +2408,26 @@ static void OPC_6502_9A (void) +static void OPC_6502_9B (void) +/* Opcode $9B: TAS abs,y */ +{ + STO_CB (ABSY, TAS); +} + + + +static void OPC_6502_9C (void) +/* Opcode $9D: SHY abs,x */ +{ + STO_OP (ABSX, Regs.YR & ((address >> 8) + 1)); +} + + + static void OPC_65SC02_9C (void) /* Opcode $9C: STZ abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - MemWriteByte (Addr, 0); - Regs.PC += 3; + STO_OP (ABS, 0); } @@ -1723,11 +2435,23 @@ static void OPC_65SC02_9C (void) static void OPC_6502_9D (void) /* Opcode $9D: STA abs,x */ { - unsigned Addr; - Cycles = 5; - Addr = MemReadWord (Regs.PC+1) + Regs.XR; - MemWriteByte (Addr, Regs.AC); - Regs.PC += 3; + STO_OP (ABSX, Regs.AC); +} + + + +static void OPC_6502_9E (void) +/* Opcode $9E: SHX abs,x */ +{ + STO_OP (ABSY, Regs.XR & ((address >> 8) + 1)); +} + + + +static void OPC_6502_9F (void) +/* Opcode $9F: SHA abs,y */ +{ + STO_CB (ABSY, SHA); } @@ -1735,11 +2459,7 @@ static void OPC_6502_9D (void) static void OPC_65SC02_9E (void) /* Opcode $9E: STZ abs,x */ { - unsigned Addr; - Cycles = 5; - Addr = MemReadWord (Regs.PC+1) + Regs.XR; - MemWriteByte (Addr, 0); - Regs.PC += 3; + STO_OP (ABSX, 0); } @@ -1747,11 +2467,7 @@ static void OPC_65SC02_9E (void) static void OPC_6502_A0 (void) /* Opcode $A0: LDY #imm */ { - Cycles = 2; - Regs.YR = MemReadByte (Regs.PC+1); - TEST_ZF (Regs.YR); - TEST_SF (Regs.YR); - Regs.PC += 2; + ALU_OP_IMM (LDY); } @@ -1759,15 +2475,7 @@ static void OPC_6502_A0 (void) static void OPC_6502_A1 (void) /* Opcode $A1: LDA (zp,x) */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Addr = MemReadZPWord (ZPAddr); - Regs.AC = MemReadByte (Addr); - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); - Regs.PC += 2; + ALU_OP (ZPXIND, LDA); } @@ -1775,11 +2483,15 @@ static void OPC_6502_A1 (void) static void OPC_6502_A2 (void) /* Opcode $A2: LDX #imm */ { - Cycles = 2; - Regs.XR = MemReadByte (Regs.PC+1); - TEST_ZF (Regs.XR); - TEST_SF (Regs.XR); - Regs.PC += 2; + ALU_OP_IMM (LDX); +} + + + +static void OPC_6502_A3 (void) +/* Opcode $A3: LAX (zp,x) */ +{ + ALU_OP (ZPXIND, LAX); } @@ -1787,13 +2499,7 @@ static void OPC_6502_A2 (void) static void OPC_6502_A4 (void) /* Opcode $A4: LDY zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - Regs.YR = MemReadByte (ZPAddr); - TEST_ZF (Regs.YR); - TEST_SF (Regs.YR); - Regs.PC += 2; + ALU_OP (ZP, LDY); } @@ -1801,13 +2507,7 @@ static void OPC_6502_A4 (void) static void OPC_6502_A5 (void) /* Opcode $A5: LDA zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - Regs.AC = MemReadByte (ZPAddr); - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); - Regs.PC += 2; + ALU_OP (ZP, LDA); } @@ -1815,13 +2515,15 @@ static void OPC_6502_A5 (void) static void OPC_6502_A6 (void) /* Opcode $A6: LDX zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - Regs.XR = MemReadByte (ZPAddr); - TEST_ZF (Regs.XR); - TEST_SF (Regs.XR); - Regs.PC += 2; + ALU_OP (ZP, LDX); +} + + + +static void OPC_6502_A7 (void) +/* Opcode $A7: LAX zp */ +{ + ALU_OP (ZP, LAX); } @@ -1841,11 +2543,7 @@ static void OPC_6502_A8 (void) static void OPC_6502_A9 (void) /* Opcode $A9: LDA #imm */ { - Cycles = 2; - Regs.AC = MemReadByte (Regs.PC+1); - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); - Regs.PC += 2; + ALU_OP_IMM (LDA); } @@ -1862,16 +2560,18 @@ static void OPC_6502_AA (void) +static void OPC_6502_AB (void) +/* Opcode $AB: LXA imm */ +{ + ALU_OP_IMM (LXA); +} + + + static void OPC_6502_AC (void) /* Opcode $Regs.AC: LDY abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - Regs.YR = MemReadByte (Addr); - TEST_ZF (Regs.YR); - TEST_SF (Regs.YR); - Regs.PC += 3; + ALU_OP (ABS, LDY); } @@ -1879,13 +2579,7 @@ static void OPC_6502_AC (void) static void OPC_6502_AD (void) /* Opcode $AD: LDA abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - Regs.AC = MemReadByte (Addr); - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); - Regs.PC += 3; + ALU_OP (ABS, LDA); } @@ -1893,13 +2587,15 @@ static void OPC_6502_AD (void) static void OPC_6502_AE (void) /* Opcode $AE: LDX abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - Regs.XR = MemReadByte (Addr); - TEST_ZF (Regs.XR); - TEST_SF (Regs.XR); - Regs.PC += 3; + ALU_OP (ABS, LDX); +} + + + +static void OPC_6502_AF (void) +/* Opcode $AF: LAX abs */ +{ + ALU_OP (ABS, LAX); } @@ -1915,18 +2611,7 @@ static void OPC_6502_B0 (void) static void OPC_6502_B1 (void) /* Opcode $B1: LDA (zp),y */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); - if (PAGE_CROSS (Addr, Regs.YR)) { - ++Cycles; - } - Regs.AC = MemReadByte (Addr + Regs.YR); - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); - Regs.PC += 2; + ALU_OP (ZPINDY, LDA); } @@ -1934,15 +2619,15 @@ static void OPC_6502_B1 (void) static void OPC_65SC02_B2 (void) /* Opcode $B2: LDA (zp) */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); - Regs.AC = MemReadByte (Addr); - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); - Regs.PC += 2; + ALU_OP (ZPIND, LDA); +} + + + +static void OPC_6502_B3 (void) +/* Opcode $B3: LAX (zp),y */ +{ + ALU_OP (ZPINDY, LAX); } @@ -1950,13 +2635,7 @@ static void OPC_65SC02_B2 (void) static void OPC_6502_B4 (void) /* Opcode $B4: LDY zp,x */ { - unsigned char ZPAddr; - Cycles = 4; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Regs.YR = MemReadByte (ZPAddr); - TEST_ZF (Regs.YR); - TEST_SF (Regs.YR); - Regs.PC += 2; + ALU_OP (ZPX, LDY); } @@ -1964,13 +2643,7 @@ static void OPC_6502_B4 (void) static void OPC_6502_B5 (void) /* Opcode $B5: LDA zp,x */ { - unsigned char ZPAddr; - Cycles = 4; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Regs.AC = MemReadByte (ZPAddr); - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); - Regs.PC += 2; + ALU_OP (ZPX, LDA); } @@ -1978,13 +2651,15 @@ static void OPC_6502_B5 (void) static void OPC_6502_B6 (void) /* Opcode $B6: LDX zp,y */ { - unsigned char ZPAddr; - Cycles = 4; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR; - Regs.XR = MemReadByte (ZPAddr); - TEST_ZF (Regs.XR); - TEST_SF (Regs.XR); - Regs.PC += 2; + ALU_OP (ZPY, LDX); +} + + + +static void OPC_6502_B7 (void) +/* Opcode $B7: LAX zp,y */ +{ + ALU_OP (ZPY, LAX); } @@ -2002,16 +2677,7 @@ static void OPC_6502_B8 (void) static void OPC_6502_B9 (void) /* Opcode $B9: LDA abs,y */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - if (PAGE_CROSS (Addr, Regs.YR)) { - ++Cycles; - } - Regs.AC = MemReadByte (Addr + Regs.YR); - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); - Regs.PC += 3; + ALU_OP (ABSY, LDA); } @@ -2028,19 +2694,18 @@ static void OPC_6502_BA (void) +static void OPC_6502_BB (void) +/* Opcode $BB: LAS abs,y */ +{ + ALU_OP (ABSY, LAS); +} + + + static void OPC_6502_BC (void) /* Opcode $BC: LDY abs,x */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - if (PAGE_CROSS (Addr, Regs.XR)) { - ++Cycles; - } - Regs.YR = MemReadByte (Addr + Regs.XR); - TEST_ZF (Regs.YR); - TEST_SF (Regs.YR); - Regs.PC += 3; + ALU_OP (ABSX, LDY); } @@ -2048,16 +2713,7 @@ static void OPC_6502_BC (void) static void OPC_6502_BD (void) /* Opcode $BD: LDA abs,x */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - if (PAGE_CROSS (Addr, Regs.XR)) { - ++Cycles; - } - Regs.AC = MemReadByte (Addr + Regs.XR); - TEST_ZF (Regs.AC); - TEST_SF (Regs.AC); - Regs.PC += 3; + ALU_OP (ABSX, LDA); } @@ -2065,16 +2721,15 @@ static void OPC_6502_BD (void) static void OPC_6502_BE (void) /* Opcode $BE: LDX abs,y */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - if (PAGE_CROSS (Addr, Regs.YR)) { - ++Cycles; - } - Regs.XR = MemReadByte (Addr + Regs.YR); - TEST_ZF (Regs.XR); - TEST_SF (Regs.XR); - Regs.PC += 3; + ALU_OP (ABSY, LDX); +} + + + +static void OPC_6502_BF (void) +/* Opcode $BF: LAX abs,y */ +{ + ALU_OP (ABSY, LAX); } @@ -2082,9 +2737,7 @@ static void OPC_6502_BE (void) static void OPC_6502_C0 (void) /* Opcode $C0: CPY #imm */ { - Cycles = 2; - CMP (Regs.YR, MemReadByte (Regs.PC+1)); - Regs.PC += 2; + ALU_OP_IMM (CPY); } @@ -2092,13 +2745,15 @@ static void OPC_6502_C0 (void) static void OPC_6502_C1 (void) /* Opcode $C1: CMP (zp,x) */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Addr = MemReadZPWord (ZPAddr); - CMP (Regs.AC, MemReadByte (Addr)); - Regs.PC += 2; + ALU_OP (ZPXIND, CMP); +} + + + +static void OPC_6502_C3 (void) +/* Opcode $C3: DCP (zp,x) */ +{ + MEM_OP (ZPXIND, DCP); } @@ -2106,11 +2761,7 @@ static void OPC_6502_C1 (void) static void OPC_6502_C4 (void) /* Opcode $C4: CPY zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - CMP (Regs.YR, MemReadByte (ZPAddr)); - Regs.PC += 2; + ALU_OP (ZP, CPY); } @@ -2118,11 +2769,7 @@ static void OPC_6502_C4 (void) static void OPC_6502_C5 (void) /* Opcode $C5: CMP zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - CMP (Regs.AC, MemReadByte (ZPAddr)); - Regs.PC += 2; + ALU_OP (ZP, CMP); } @@ -2130,15 +2777,15 @@ static void OPC_6502_C5 (void) static void OPC_6502_C6 (void) /* Opcode $C6: DEC zp */ { - unsigned char ZPAddr; - unsigned char Val; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr) - 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 2; + MEM_OP (ZP, DEC); +} + + + +static void OPC_6502_C7 (void) +/* Opcode $C7: DCP zp */ +{ + MEM_OP (ZP, DCP); } @@ -2147,9 +2794,7 @@ static void OPC_6502_C8 (void) /* Opcode $C8: INY */ { Cycles = 2; - Regs.YR = (Regs.YR + 1) & 0xFF; - TEST_ZF (Regs.YR); - TEST_SF (Regs.YR); + INC(Regs.YR); Regs.PC += 1; } @@ -2158,9 +2803,7 @@ static void OPC_6502_C8 (void) static void OPC_6502_C9 (void) /* Opcode $C9: CMP #imm */ { - Cycles = 2; - CMP (Regs.AC, MemReadByte (Regs.PC+1)); - Regs.PC += 2; + ALU_OP_IMM (CMP); } @@ -2169,22 +2812,24 @@ static void OPC_6502_CA (void) /* Opcode $CA: DEX */ { Cycles = 2; - Regs.XR = (Regs.XR - 1) & 0xFF; - TEST_ZF (Regs.XR); - TEST_SF (Regs.XR); + DEC (Regs.XR); Regs.PC += 1; } +static void OPC_6502_CB (void) +/* Opcode $CB: SBX imm */ +{ + ALU_OP_IMM (SBX); +} + + + static void OPC_6502_CC (void) /* Opcode $CC: CPY abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - CMP (Regs.YR, MemReadByte (Addr)); - Regs.PC += 3; + ALU_OP (ABS, CPY); } @@ -2192,11 +2837,7 @@ static void OPC_6502_CC (void) static void OPC_6502_CD (void) /* Opcode $CD: CMP abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - CMP (Regs.AC, MemReadByte (Addr)); - Regs.PC += 3; + ALU_OP (ABS, CMP); } @@ -2204,15 +2845,15 @@ static void OPC_6502_CD (void) static void OPC_6502_CE (void) /* Opcode $CE: DEC abs */ { - unsigned Addr; - unsigned char Val; - Cycles = 6; - Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr) - 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 3; + MEM_OP (ABS, DEC); +} + + + +static void OPC_6502_CF (void) +/* Opcode $CF: DCP abs */ +{ + MEM_OP (ABS, DCP); } @@ -2228,16 +2869,7 @@ static void OPC_6502_D0 (void) static void OPC_6502_D1 (void) /* Opcode $D1: CMP (zp),y */ { - unsigned ZPAddr; - unsigned Addr; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadWord (ZPAddr); - if (PAGE_CROSS (Addr, Regs.YR)) { - ++Cycles; - } - CMP (Regs.AC, MemReadByte (Addr + Regs.YR)); - Regs.PC += 2; + ALU_OP (ZPINDY, CMP); } @@ -2245,13 +2877,15 @@ static void OPC_6502_D1 (void) static void OPC_65SC02_D2 (void) /* Opcode $D2: CMP (zp) */ { - unsigned ZPAddr; - unsigned Addr; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadWord (ZPAddr); - CMP (Regs.AC, MemReadByte (Addr)); - Regs.PC += 2; + ALU_OP (ZPIND, CMP); +} + + + +static void OPC_6502_D3 (void) +/* Opcode $D3: DCP (zp),y */ +{ + MEM_OP (ZPINDY, DCP); } @@ -2259,11 +2893,7 @@ static void OPC_65SC02_D2 (void) static void OPC_6502_D5 (void) /* Opcode $D5: CMP zp,x */ { - unsigned char ZPAddr; - Cycles = 4; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - CMP (Regs.AC, MemReadByte (ZPAddr)); - Regs.PC += 2; + ALU_OP (ZPX, CMP); } @@ -2271,15 +2901,15 @@ static void OPC_6502_D5 (void) static void OPC_6502_D6 (void) /* Opcode $D6: DEC zp,x */ { - unsigned char ZPAddr; - unsigned char Val; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr) - 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 2; + MEM_OP (ZPX, DEC); +} + + + +static void OPC_6502_D7 (void) +/* Opcode $D7: DCP zp,x */ +{ + MEM_OP (ZPX, DCP); } @@ -2297,14 +2927,7 @@ static void OPC_6502_D8 (void) static void OPC_6502_D9 (void) /* Opcode $D9: CMP abs,y */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - if (PAGE_CROSS (Addr, Regs.YR)) { - ++Cycles; - } - CMP (Regs.AC, MemReadByte (Addr + Regs.YR)); - Regs.PC += 3; + ALU_OP (ABSY, CMP); } @@ -2319,17 +2942,18 @@ static void OPC_65SC02_DA (void) +static void OPC_6502_DB (void) +/* Opcode $DB: DCP abs,y */ +{ + MEM_OP (ABSY, DCP); +} + + + static void OPC_6502_DD (void) /* Opcode $DD: CMP abs,x */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - if (PAGE_CROSS (Addr, Regs.XR)) { - ++Cycles; - } - CMP (Regs.AC, MemReadByte (Addr + Regs.XR)); - Regs.PC += 3; + ALU_OP (ABSX, CMP); } @@ -2337,15 +2961,15 @@ static void OPC_6502_DD (void) static void OPC_6502_DE (void) /* Opcode $DE: DEC abs,x */ { - unsigned Addr; - unsigned char Val; - Cycles = 7; - Addr = MemReadWord (Regs.PC+1) + Regs.XR; - Val = MemReadByte (Addr) - 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 3; + MEM_OP (ABSX, DEC); +} + + + +static void OPC_6502_DF (void) +/* Opcode $DF: DCP abs,x */ +{ + MEM_OP (ABSX, DCP); } @@ -2353,9 +2977,7 @@ static void OPC_6502_DE (void) static void OPC_6502_E0 (void) /* Opcode $E0: CPX #imm */ { - Cycles = 2; - CMP (Regs.XR, MemReadByte (Regs.PC+1)); - Regs.PC += 2; + ALU_OP_IMM (CPX); } @@ -2363,13 +2985,15 @@ static void OPC_6502_E0 (void) static void OPC_6502_E1 (void) /* Opcode $E1: SBC (zp,x) */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Addr = MemReadZPWord (ZPAddr); - SBC (MemReadByte (Addr)); - Regs.PC += 2; + ALU_OP (ZPXIND, SBC); +} + + + +static void OPC_6502_E3 (void) +/* Opcode $E3: ISC (zp,x) */ +{ + MEM_OP (ZPXIND, ISC); } @@ -2377,11 +3001,7 @@ static void OPC_6502_E1 (void) static void OPC_6502_E4 (void) /* Opcode $E4: CPX zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - CMP (Regs.XR, MemReadByte (ZPAddr)); - Regs.PC += 2; + ALU_OP (ZP, CPX); } @@ -2389,11 +3009,7 @@ static void OPC_6502_E4 (void) static void OPC_6502_E5 (void) /* Opcode $E5: SBC zp */ { - unsigned char ZPAddr; - Cycles = 3; - ZPAddr = MemReadByte (Regs.PC+1); - SBC (MemReadByte (ZPAddr)); - Regs.PC += 2; + ALU_OP (ZP, SBC); } @@ -2401,15 +3017,15 @@ static void OPC_6502_E5 (void) static void OPC_6502_E6 (void) /* Opcode $E6: INC zp */ { - unsigned char ZPAddr; - unsigned char Val; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Val = MemReadByte (ZPAddr) + 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 2; + MEM_OP (ZP, INC); +} + + + +static void OPC_6502_E7 (void) +/* Opcode $E7: ISC zp */ +{ + MEM_OP (ZP, ISC); } @@ -2418,24 +3034,31 @@ static void OPC_6502_E8 (void) /* Opcode $E8: INX */ { Cycles = 2; - Regs.XR = (Regs.XR + 1) & 0xFF; - TEST_ZF (Regs.XR); - TEST_SF (Regs.XR); + INC (Regs.XR); Regs.PC += 1; } +/* Aliases of opcode $EA */ +#define OPC_6502_EB OPC_6502_E9 + static void OPC_6502_E9 (void) /* Opcode $E9: SBC #imm */ { - Cycles = 2; - SBC (MemReadByte (Regs.PC+1)); - Regs.PC += 2; + ALU_OP_IMM (SBC); } +/* Aliases of opcode $EA */ +#define OPC_6502_1A OPC_6502_EA +#define OPC_6502_3A OPC_6502_EA +#define OPC_6502_5A OPC_6502_EA +#define OPC_6502_7A OPC_6502_EA +#define OPC_6502_DA OPC_6502_EA +#define OPC_6502_FA OPC_6502_EA + static void OPC_6502_EA (void) /* Opcode $EA: NOP */ { @@ -2485,11 +3108,7 @@ static void OPC_65C02_NOP34 (void) static void OPC_6502_EC (void) /* Opcode $EC: CPX abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - CMP (Regs.XR, MemReadByte (Addr)); - Regs.PC += 3; + ALU_OP (ABS, CPX); } @@ -2497,27 +3116,22 @@ static void OPC_6502_EC (void) static void OPC_6502_ED (void) /* Opcode $ED: SBC abs */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - SBC (MemReadByte (Addr)); - Regs.PC += 3; + ALU_OP (ABS, SBC); } - static void OPC_6502_EE (void) /* Opcode $EE: INC abs */ { - unsigned Addr; - unsigned char Val; - Cycles = 6; - Addr = MemReadWord (Regs.PC+1); - Val = MemReadByte (Addr) + 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 3; + MEM_OP (ABS, INC); +} + + + +static void OPC_6502_EF (void) +/* Opcode $EF: ISC abs */ +{ + MEM_OP (ABS, ISC); } @@ -2533,16 +3147,7 @@ static void OPC_6502_F0 (void) static void OPC_6502_F1 (void) /* Opcode $F1: SBC (zp),y */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); - if (PAGE_CROSS (Addr, Regs.YR)) { - ++Cycles; - } - SBC (MemReadByte (Addr + Regs.YR)); - Regs.PC += 2; + ALU_OP (ZPINDY, SBC); } @@ -2550,13 +3155,15 @@ static void OPC_6502_F1 (void) static void OPC_65SC02_F2 (void) /* Opcode $F2: SBC (zp) */ { - unsigned char ZPAddr; - unsigned Addr; - Cycles = 5; - ZPAddr = MemReadByte (Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); - SBC (MemReadByte (Addr)); - Regs.PC += 2; + ALU_OP (ZPIND, SBC); +} + + + +static void OPC_6502_F3 (void) +/* Opcode $F3: ISC (zp),y */ +{ + MEM_OP (ZPINDY, ISC); } @@ -2564,11 +3171,7 @@ static void OPC_65SC02_F2 (void) static void OPC_6502_F5 (void) /* Opcode $F5: SBC zp,x */ { - unsigned char ZPAddr; - Cycles = 4; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - SBC (MemReadByte (ZPAddr)); - Regs.PC += 2; + ALU_OP (ZPX, SBC); } @@ -2576,15 +3179,15 @@ static void OPC_6502_F5 (void) static void OPC_6502_F6 (void) /* Opcode $F6: INC zp,x */ { - unsigned char ZPAddr; - unsigned char Val; - Cycles = 6; - ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; - Val = MemReadByte (ZPAddr) + 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 2; + MEM_OP (ZPX, INC); +} + + + +static void OPC_6502_F7 (void) +/* Opcode $F7: ISC zp,x */ +{ + MEM_OP (ZPX, ISC); } @@ -2602,14 +3205,7 @@ static void OPC_6502_F8 (void) static void OPC_6502_F9 (void) /* Opcode $F9: SBC abs,y */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - if (PAGE_CROSS (Addr, Regs.YR)) { - ++Cycles; - } - SBC (MemReadByte (Addr + Regs.YR)); - Regs.PC += 3; + ALU_OP (ABSY, SBC); } @@ -2626,17 +3222,18 @@ static void OPC_65SC02_FA (void) +static void OPC_6502_FB (void) +/* Opcode $FB: ISC abs,y */ +{ + MEM_OP (ABSY, ISC); +} + + + static void OPC_6502_FD (void) /* Opcode $FD: SBC abs,x */ { - unsigned Addr; - Cycles = 4; - Addr = MemReadWord (Regs.PC+1); - if (PAGE_CROSS (Addr, Regs.XR)) { - ++Cycles; - } - SBC (MemReadByte (Addr + Regs.XR)); - Regs.PC += 3; + ALU_OP (ABSX, SBC); } @@ -2644,15 +3241,15 @@ static void OPC_6502_FD (void) static void OPC_6502_FE (void) /* Opcode $FE: INC abs,x */ { - unsigned Addr; - unsigned char Val; - Cycles = 7; - Addr = MemReadWord (Regs.PC+1) + Regs.XR; - Val = MemReadByte (Addr) + 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - Regs.PC += 3; + MEM_OP (ABSX, INC); +} + + + +static void OPC_6502_FF (void) +/* Opcode $FF: ISC abs,x */ +{ + MEM_OP (ABSX, ISC); } @@ -2925,6 +3522,268 @@ static const OPFunc OP6502Table[256] = { +/* Opcode handler table for the 6502X */ +static const OPFunc OP6502XTable[256] = { + OPC_6502_00, + OPC_6502_01, + OPC_Illegal, + OPC_6502_03, + OPC_6502_04, + OPC_6502_05, + OPC_6502_06, + OPC_6502_07, + OPC_6502_08, + OPC_6502_09, + OPC_6502_0A, + OPC_6502_0B, + OPC_6502_0C, + OPC_6502_0D, + OPC_6502_0E, + OPC_6502_0F, + OPC_6502_10, + OPC_6502_11, + OPC_Illegal, + OPC_6502_13, + OPC_6502_14, + OPC_6502_15, + OPC_6502_16, + OPC_6502_17, + OPC_6502_18, + OPC_6502_19, + OPC_6502_1A, + OPC_6502_1B, + OPC_6502_1C, + OPC_6502_1D, + OPC_6502_1E, + OPC_6502_1F, + OPC_6502_20, + OPC_6502_21, + OPC_Illegal, + OPC_6502_23, + OPC_6502_24, + OPC_6502_25, + OPC_6502_26, + OPC_6502_27, + OPC_6502_28, + OPC_6502_29, + OPC_6502_2A, + OPC_6502_2B, + OPC_6502_2C, + OPC_6502_2D, + OPC_6502_2E, + OPC_6502_2F, + OPC_6502_30, + OPC_6502_31, + OPC_Illegal, + OPC_6502_33, + OPC_6502_34, + OPC_6502_35, + OPC_6502_36, + OPC_6502_37, + OPC_6502_38, + OPC_6502_39, + OPC_6502_3A, + OPC_6502_3B, + OPC_6502_3C, + OPC_6502_3D, + OPC_6502_3E, + OPC_6502_3F, + OPC_6502_40, + OPC_6502_41, + OPC_Illegal, + OPC_6502_43, + OPC_6502_44, + OPC_6502_45, + OPC_6502_46, + OPC_6502_47, + OPC_6502_48, + OPC_6502_49, + OPC_6502_4A, + OPC_6502_4B, + OPC_6502_4C, + OPC_6502_4D, + OPC_6502_4E, + OPC_6502_4F, + OPC_6502_50, + OPC_6502_51, + OPC_Illegal, + OPC_6502_53, + OPC_6502_54, + OPC_6502_55, + OPC_6502_56, + OPC_6502_57, + OPC_6502_58, + OPC_6502_59, + OPC_6502_5A, + OPC_6502_5B, + OPC_6502_5C, + OPC_6502_5D, + OPC_6502_5E, + OPC_6502_5F, + OPC_6502_60, + OPC_6502_61, + OPC_Illegal, + OPC_6502_63, + OPC_6502_64, + OPC_6502_65, + OPC_6502_66, + OPC_6502_67, + OPC_6502_68, + OPC_6502_69, + OPC_6502_6A, + OPC_6502_6B, + OPC_6502_6C, + OPC_6502_6D, + OPC_6502_6E, + OPC_6502_6F, + OPC_6502_70, + OPC_6502_71, + OPC_Illegal, + OPC_6502_73, + OPC_6502_74, + OPC_6502_75, + OPC_6502_76, + OPC_6502_77, + OPC_6502_78, + OPC_6502_79, + OPC_6502_7A, + OPC_6502_7B, + OPC_6502_7C, + OPC_6502_7D, + OPC_6502_7E, + OPC_6502_7F, + OPC_6502_80, + OPC_6502_81, + OPC_6502_82, + OPC_6502_83, + OPC_6502_84, + OPC_6502_85, + OPC_6502_86, + OPC_6502_87, + OPC_6502_88, + OPC_6502_89, + OPC_6502_8A, + OPC_6502_8B, + OPC_6502_8C, + OPC_6502_8D, + OPC_6502_8E, + OPC_6502_8F, + OPC_6502_90, + OPC_6502_91, + OPC_Illegal, + OPC_6502_93, + OPC_6502_94, + OPC_6502_95, + OPC_6502_96, + OPC_6502_97, + OPC_6502_98, + OPC_6502_99, + OPC_6502_9A, + OPC_6502_9B, + OPC_6502_9C, + OPC_6502_9D, + OPC_6502_9E, + OPC_6502_9F, + OPC_6502_A0, + OPC_6502_A1, + OPC_6502_A2, + OPC_6502_A3, + OPC_6502_A4, + OPC_6502_A5, + OPC_6502_A6, + OPC_6502_A7, + OPC_6502_A8, + OPC_6502_A9, + OPC_6502_AA, + OPC_6502_AB, + OPC_6502_AC, + OPC_6502_AD, + OPC_6502_AE, + OPC_6502_AF, + OPC_6502_B0, + OPC_6502_B1, + OPC_Illegal, + OPC_6502_B3, + OPC_6502_B4, + OPC_6502_B5, + OPC_6502_B6, + OPC_6502_B7, + OPC_6502_B8, + OPC_6502_B9, + OPC_6502_BA, + OPC_6502_BB, + OPC_6502_BC, + OPC_6502_BD, + OPC_6502_BE, + OPC_6502_BF, + OPC_6502_C0, + OPC_6502_C1, + OPC_6502_C2, + OPC_6502_C3, + OPC_6502_C4, + OPC_6502_C5, + OPC_6502_C6, + OPC_6502_C7, + OPC_6502_C8, + OPC_6502_C9, + OPC_6502_CA, + OPC_6502_CB, + OPC_6502_CC, + OPC_6502_CD, + OPC_6502_CE, + OPC_6502_CF, + OPC_6502_D0, + OPC_6502_D1, + OPC_Illegal, + OPC_6502_D3, + OPC_6502_D4, + OPC_6502_D5, + OPC_6502_D6, + OPC_6502_D7, + OPC_6502_D8, + OPC_6502_D9, + OPC_6502_DA, + OPC_6502_DB, + OPC_6502_DC, + OPC_6502_DD, + OPC_6502_DE, + OPC_6502_DF, + OPC_6502_E0, + OPC_6502_E1, + OPC_6502_E2, + OPC_6502_E3, + OPC_6502_E4, + OPC_6502_E5, + OPC_6502_E6, + OPC_6502_E7, + OPC_6502_E8, + OPC_6502_E9, + OPC_6502_EA, + OPC_6502_EB, + OPC_6502_EC, + OPC_6502_ED, + OPC_6502_EE, + OPC_6502_EF, + OPC_6502_F0, + OPC_6502_F1, + OPC_Illegal, + OPC_6502_F3, + OPC_6502_F4, + OPC_6502_F5, + OPC_6502_F6, + OPC_6502_F7, + OPC_6502_F8, + OPC_6502_F9, + OPC_6502_FA, + OPC_6502_FB, + OPC_6502_FC, + OPC_6502_FD, + OPC_6502_FE, + OPC_6502_FF +}; + + + /* Opcode handler table for the 65C02 */ static const OPFunc OP65C02Table[256] = { OPC_6502_00, @@ -2957,7 +3816,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_NOP11, // $1B OPC_65SC02_1C, OPC_6502_1D, - OPC_6502_1E, + OPC_65C02_1E, OPC_Illegal, // $1F: BBR1 currently unsupported OPC_6502_20, OPC_6502_21, @@ -2989,13 +3848,13 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_NOP11, // $3B OPC_65SC02_3C, OPC_6502_3D, - OPC_6502_3E, + OPC_65C02_3E, OPC_Illegal, // $3F: BBR3 currently unsupported OPC_6502_40, OPC_6502_41, OPC_65C02_NOP22, // $42 OPC_65C02_NOP11, // $43 - OPC_65C02_44, // $44 + OPC_6502_44, // $44 OPC_6502_45, OPC_6502_46, OPC_Illegal, // $47: RMB4 currently unsupported @@ -3021,7 +3880,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_NOP11, // $5B OPC_65C02_5C, OPC_6502_5D, - OPC_6502_5E, + OPC_65C02_5E, OPC_Illegal, // $5F: BBR5 currently unsupported OPC_6502_60, OPC_6502_61, @@ -3053,7 +3912,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_NOP11, // $7B OPC_65SC02_7C, OPC_6502_7D, - OPC_6502_7E, + OPC_65C02_7E, OPC_Illegal, // $7F: BBR7 currently unsupported OPC_65SC02_80, OPC_6502_81, @@ -3188,7 +4047,11 @@ static const OPFunc OP65C02Table[256] = { /* Tables with opcode handlers */ -static const OPFunc* Handlers[2] = {OP6502Table, OP65C02Table}; +static const OPFunc* Handlers[3] = { + OP6502Table, + OP65C02Table, + OP6502XTable +}; diff --git a/src/sim65/6502.h b/src/sim65/6502.h index 39b995793..a7a702521 100644 --- a/src/sim65/6502.h +++ b/src/sim65/6502.h @@ -47,7 +47,8 @@ /* Supported CPUs */ typedef enum CPUType { CPU_6502, - CPU_65C02 + CPU_65C02, + CPU_6502X } CPUType; /* Current CPU */ diff --git a/src/sim65/main.c b/src/sim65/main.c index 3c7cdc157..76c912c6b 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -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 */ From 788ae82d30bcf29da0e160cd47532594780fe22b Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Fri, 9 Feb 2024 00:09:16 +0000 Subject: [PATCH 149/707] Fixes to serial driver implementation --- asminc/lynx.inc | 34 +++++++------- libsrc/lynx/crt0.s | 2 +- libsrc/lynx/ser/lynx-comlynx.s | 81 ++++++++++++++++++++-------------- 3 files changed, 67 insertions(+), 50 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index 5ae17f6ef..d65b7f8a9 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -267,22 +267,26 @@ 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 +; 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 diff --git a/libsrc/lynx/crt0.s b/libsrc/lynx/crt0.s index 238a2c99d..030f523e9 100644 --- a/libsrc/lynx/crt0.s +++ b/libsrc/lynx/crt0.s @@ -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. diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 8aa3c838e..85703867b 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -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 #$0C ; TXOPEN|RESETERR + sta SERCTL + lda #$00 ; Disable count and no reload + sta TIM4CTLA + ; Done, return an error code lda #SER_ERR_OK .assert SER_ERR_OK = 0, error @@ -108,7 +113,7 @@ SER_OPEN: stz TxPtrIn stz TxPtrOut - ; clock = 8 * 15625 + ; source period is 1 us lda #%00011000 sta TIM4CTLA ldy #SER_PARAMS::BAUDRATE @@ -118,7 +123,7 @@ SER_OPEN: cmp #SER_BAUD_62500 beq setbaudrate - ldx #2 + ldx #3 cmp #SER_BAUD_31250 beq setbaudrate @@ -194,13 +199,14 @@ SER_OPEN: lda #SER_ERR_BAUD_UNAVAIL ldx #0 ; return value is char rts + setprescaler: stx TIM4CTLA bra baudsuccess setbaudrate: stx TIM4BKUP baudsuccess: - ldx #TxOpenColl|ParEven + ldx #TXOPEN|PAREVEN stx contrl ldy #SER_PARAMS::DATABITS ; Databits lda (ptr1),y @@ -218,15 +224,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 @@ -237,7 +243,7 @@ checkhs: bne invparameter 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 @@ -279,24 +285,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,7 +316,7 @@ PutByte: ; Must return an SER_ERR_xx code in a/x. SER_STATUS: - ldy SerialStat + lda SerialStat ldx #$00 sta (ptr1,x) txa ; Return code = 0 @@ -342,27 +350,32 @@ 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 + ora #OVERRUN|FRAMERR|RXBRK + bit SERCTL ; Compare with 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 + ora #RXINTEN|RESETERR sta SERCTL - lda #$10 - sta INTRST bra @IRQexit + @rx_irq: lda contrl - ora #RxIntEnable|ResetErr + ora #RXINTEN|RESETERR sta SERCTL txa ldx RxPtrIn @@ -370,20 +383,22 @@ SER_IRQ: txa inx -@cont0: cpx RxPtrOut beq @1 stx RxPtrIn - lda #SERIAL_INTERRUPT - sta INTRST bra @IRQexit @1: sta RxPtrIn lda #$80 tsb SerialStat + lda contrl + ora #RXINTEN|RESETERR + sta SERCTL + bra @IRQexit + @tx_irq: - ldx TxPtrOut ; Has all bytes been sent? + ldx TxPtrOut ; Have all bytes been sent? cpx TxPtrIn beq @allSent @@ -393,24 +408,22 @@ 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 lda contrl - ora #RxIntEnable|ResetErr + ora #RXINTEN|RESETERR ; Re-enable receive interrupt sta SERCTL +@IRQexit: lda #SERIAL_INTERRUPT sta INTRST -@IRQexit: clc rts From 014f85f226b38f434722ecc085d621e9d3d730d1 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Fri, 9 Feb 2024 10:42:52 +0000 Subject: [PATCH 150/707] Fixed baud rates --- libsrc/lynx/ser/lynx-comlynx.s | 86 +++++++++++++--------------------- 1 file changed, 33 insertions(+), 53 deletions(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 85703867b..9564bcb4f 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -113,12 +113,12 @@ SER_OPEN: stz TxPtrIn stz TxPtrOut - ; source period is 1 us - 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 @@ -139,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 @@ -147,65 +151,48 @@ SER_OPEN: cmp #SER_BAUD_600 beq setbaudrate - ; clock = 6 * 15625 - ldx #%00011010 - stx TIM4CTLA + ; Source period is 4 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 + beq setbaudrate - ; clock = 6 * 15625 - ldx #%00011110 + ldx #103 cmp #SER_BAUD_150 - beq setprescaler + beq setbaudrate - ; clock = 1 * 15625 - ldx #%00011111 - stx TIM4CTLA - cmp #SER_BAUD_75 - beq baudsuccess + ldx #115 + cmp #SER_BAUD_134_5 + beq setbaudrate ldx #141 cmp #SER_BAUD_110 beq setbaudrate - ; clock = 2 * 15625 - ldx #%00011010 - stx TIM4CTLA - ldx #68 - cmp #SER_BAUD_1800 + ; Source period is 32 us + ldy #%00011101 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_32 + + ldx #51 + cmp #SER_BAUD_75 beq setbaudrate - ; clock = 6 * 15625 - ldx #%00011110 - stx TIM4CTLA - ldx #231 - cmp #SER_BAUD_134_5 + ldx #68 + cmp #SER_BAUD_56_875 + beq setbaudrate + + ldx #77 + cmp #SER_BAUD_50 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 #TXOPEN|PAREVEN stx contrl ldy #SER_PARAMS::DATABITS ; Databits @@ -368,15 +355,9 @@ SER_IRQ: stz RxPtrIn stz RxPtrOut @noBreak: - lda contrl - ora #RXINTEN|RESETERR - sta SERCTL - bra @IRQexit + bra @exit0 @rx_irq: - lda contrl - ora #RXINTEN|RESETERR - sta SERCTL txa ldx RxPtrIn sta RxBuffer,x @@ -392,10 +373,7 @@ SER_IRQ: sta RxPtrIn lda #$80 tsb SerialStat - lda contrl - ora #RXINTEN|RESETERR - sta SERCTL - bra @IRQexit + bra @exit0 @tx_irq: ldx TxPtrOut ; Have all bytes been sent? @@ -418,6 +396,8 @@ SER_IRQ: beq @exit1 bvs @exit1 stz TxDone + +@exit0: lda contrl ora #RXINTEN|RESETERR ; Re-enable receive interrupt sta SERCTL From 65bce9ecdeda7a2214a27fafa4ccbfcd5daa5449 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Fri, 9 Feb 2024 12:54:00 +0000 Subject: [PATCH 151/707] Implemented mark and space checks. --- libsrc/lynx/ser/lynx-comlynx.s | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 9564bcb4f..3b6f18af6 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -151,7 +151,7 @@ SER_OPEN: cmp #SER_BAUD_600 beq setbaudrate - ; Source period is 4 us + ; Source period is 8 us ldy #%00011011 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_8 ldx #51 @@ -341,8 +341,9 @@ SER_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 - bit SERCTL ; Compare with SERCTL + bit SERCTL ; Check error flags in SERCTL beq @rx_irq ; No errors so far @@ -358,6 +359,15 @@ SER_IRQ: bra @exit0 @rx_irq: + tya + bne @2 ; Parity was enabled so no marker bit check needed + + lda contrl + eor SERCTL ; Should match current parity bit + and #PARBIT ; Check for mark or space value + bne @exit0 + +@2: txa ldx RxPtrIn sta RxBuffer,x From 6cf8ee8eb563f50ceef74605a95e202054e2991c Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Sat, 10 Feb 2024 21:15:05 +0000 Subject: [PATCH 152/707] Removed baud rates from 150 and lower. Fixed tab Replaced uploader references to SERIAL_INTERRUPT --- libsrc/lynx/ser/lynx-comlynx.s | 31 ++----------------------------- libsrc/lynx/uploader.s | 6 +++--- 2 files changed, 5 insertions(+), 32 deletions(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 3b6f18af6..486981184 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -158,33 +158,6 @@ SER_OPEN: cmp #SER_BAUD_300 beq setbaudrate - ldx #103 - cmp #SER_BAUD_150 - beq setbaudrate - - ldx #115 - cmp #SER_BAUD_134_5 - beq setbaudrate - - ldx #141 - cmp #SER_BAUD_110 - beq setbaudrate - - ; Source period is 32 us - ldy #%00011101 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_32 - - ldx #51 - cmp #SER_BAUD_75 - beq setbaudrate - - ldx #68 - cmp #SER_BAUD_56_875 - beq setbaudrate - - ldx #77 - cmp #SER_BAUD_50 - beq setbaudrate - lda #SER_ERR_BAUD_UNAVAIL ldx #0 ; return value is char rts @@ -342,8 +315,8 @@ SER_IRQ: lda contrl and #PAREN ; Parity enabled implies SER_PAR_EVEN or SER_PAR_ODD tay - ora #OVERRUN|FRAMERR|RXBRK - bit SERCTL ; Check error flags in SERCTL + ora #OVERRUN|FRAMERR|RXBRK + bit SERCTL ; Check presence of relevant error flags in SERCTL beq @rx_irq ; No errors so far diff --git a/libsrc/lynx/uploader.s b/libsrc/lynx/uploader.s index df3e5df40..5ce21b489 100644 --- a/libsrc/lynx/uploader.s +++ b/libsrc/lynx/uploader.s @@ -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 From acff429eb8788ab6f1b1e40bb8cef0ac7de94930 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Sun, 11 Feb 2024 15:33:22 +0000 Subject: [PATCH 153/707] Added redeye check for SER_HS_SW handshake --- asminc/lynx.inc | 16 +++++++++++++--- libsrc/lynx/ser/lynx-comlynx.s | 12 ++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index d65b7f8a9..0d34e1c7c 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -259,16 +259,26 @@ SND_INTERRUPT = TIMER7_INTERRUPT INTRST = $FD80 INTSET = $FD81 + MAGRDY0 = $FD84 MAGRDY1 = $FD85 AUDIN = $FD86 SYSCTL1 = $FD87 MIKEYHREV = $FD88 MIKEYSREV = $FD89 -IODIR = $FD8A -IODAT = $FD8B -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 diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 486981184..7201264b7 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -200,7 +200,18 @@ 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 #RXINTEN|RESETERR ; Turn on interrupts for receive @@ -209,6 +220,7 @@ checkhs: .assert SER_ERR_OK = 0, error tax rts + invparameter: lda #SER_ERR_INIT_FAILED ldx #0 ; return value is char From 1deb9e52aec938ae338168035c743b04b91e20d0 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Sun, 11 Feb 2024 15:46:23 +0000 Subject: [PATCH 154/707] Replaced last literal value for SERCTL --- libsrc/lynx/ser/lynx-comlynx.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 7201264b7..9b007c6e0 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -74,7 +74,7 @@ SER_UNINSTALL: SER_CLOSE: ; Disable interrupts and stop timer 4 (serial) - lda #$0C ; TXOPEN|RESETERR + lda #TXOPEN|RESETERR sta SERCTL lda #$00 ; Disable count and no reload sta TIM4CTLA From 8b172e05bc4c39b53ee1dd05be082c01fea0d7e0 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Sun, 11 Feb 2024 20:59:08 +0000 Subject: [PATCH 155/707] Applied optimization as per review 42Bastian --- libsrc/lynx/ser/lynx-comlynx.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index 9b007c6e0..aa4d71ad3 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -76,8 +76,7 @@ SER_CLOSE: ; Disable interrupts and stop timer 4 (serial) lda #TXOPEN|RESETERR sta SERCTL - lda #$00 ; Disable count and no reload - sta TIM4CTLA + stz TIM4CTLA ; Disable count and no reload ; Done, return an error code lda #SER_ERR_OK From 7d6f3d24d434953679c176708c67a0abc845eaa0 Mon Sep 17 00:00:00 2001 From: Alex Thissen Date: Sun, 11 Feb 2024 23:12:27 +0000 Subject: [PATCH 156/707] Changed sta (ptr1,x) to sta (ptr1) Reset serial status on ser_close Fixed error for saving serial state --- libsrc/lynx/ser/lynx-comlynx.s | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libsrc/lynx/ser/lynx-comlynx.s b/libsrc/lynx/ser/lynx-comlynx.s index aa4d71ad3..c4ae3d5b6 100644 --- a/libsrc/lynx/ser/lynx-comlynx.s +++ b/libsrc/lynx/ser/lynx-comlynx.s @@ -76,7 +76,8 @@ SER_CLOSE: ; Disable interrupts and stop timer 4 (serial) lda #TXOPEN|RESETERR sta SERCTL - stz TIM4CTLA ; Disable count and no reload + stz TIM4CTLA ; Disable count and no reload + stz SerialStat ; Reset status ; Done, return an error code lda #SER_ERR_OK @@ -241,8 +242,8 @@ GetByte: ldy RxPtrOut lda RxBuffer,y inc RxPtrOut + sta (ptr1) ldx #$00 - sta (ptr1,x) txa ; Return code = 0 rts @@ -288,8 +289,8 @@ PutByte: SER_STATUS: lda SerialStat + sta (ptr1) ldx #$00 - sta (ptr1,x) txa ; Return code = 0 rts @@ -327,7 +328,7 @@ SER_IRQ: and #PAREN ; Parity enabled implies SER_PAR_EVEN or SER_PAR_ODD tay ora #OVERRUN|FRAMERR|RXBRK - bit SERCTL ; Check presence of relevant error flags in SERCTL + and SERCTL ; Check presence of relevant error flags in SERCTL beq @rx_irq ; No errors so far From 8173c850fd5fe0a0038baa3bf8767c920f127174 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Thu, 15 Feb 2024 00:00:46 +0100 Subject: [PATCH 157/707] Fix size of MAIN to end at $1E00. Caused negative size of MAIN in cc65-contrib/quikmans2k8. --- cfg/vic20-asm.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/vic20-asm.cfg b/cfg/vic20-asm.cfg index 286a7f95c..fc9d668e4 100644 --- a/cfg/vic20-asm.cfg +++ b/cfg/vic20-asm.cfg @@ -7,7 +7,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; From 3a7bd539568e25f33c64a88fd6e76a9e015c74f2 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Thu, 15 Feb 2024 01:05:35 +0100 Subject: [PATCH 158/707] Test strtok(). --- test/ref/strtok.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 test/ref/strtok.c diff --git a/test/ref/strtok.c b/test/ref/strtok.c new file mode 100644 index 000000000..15c3a289d --- /dev/null +++ b/test/ref/strtok.c @@ -0,0 +1,43 @@ +// 2024-02-14 Sven Michael Klose + +#include +#include +#include + +void +error (void) +{ + printf ("strtok() test failed!\n"); + exit (-1); +} + +void +test (char * s) +{ + if (strcmp ("test", strtok (s, "/"))) + error (); + if (strcmp ("foo", strtok (NULL, "/"))) + error (); + if (strcmp ("bar", strtok (NULL, "/"))) + error (); + if (strtok (NULL, "/")) + error (); + if (strtok (NULL, "/")) + error (); +} + +int +main (void) +{ + char s1[] = "test/foo/bar"; + char s2[] = "/test/foo/bar"; + char s3[] = "//test/foo/bar"; + char s4[] = "//test/foo/bar//"; + + test (s1); + test (s2); + test (s3); + test (s4); + + return 0; +} From 8d4946b3f451aec4547415ad09419ad90330b2bb Mon Sep 17 00:00:00 2001 From: Stefan Date: Thu, 15 Feb 2024 07:52:42 +0100 Subject: [PATCH 159/707] Fixed segv touch /tmp/xx grc65 /tmp/xx --- src/grc65/main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/grc65/main.c b/src/grc65/main.c index 7d31bfc52..6b3ca04de 100644 --- a/src/grc65/main.c +++ b/src/grc65/main.c @@ -231,10 +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; + } } return -1; From ab0eb4fe58450649c698ebead914a97069dfbe7f Mon Sep 17 00:00:00 2001 From: Stefan Date: Thu, 15 Feb 2024 09:03:46 +0100 Subject: [PATCH 160/707] oops --- src/grc65/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/grc65/main.c b/src/grc65/main.c index 6b3ca04de..5ef9e9645 100644 --- a/src/grc65/main.c +++ b/src/grc65/main.c @@ -236,6 +236,7 @@ static int findToken (const char * const *tokenTbl, const char *token) if (strcmp (tokenTbl[i], token) == 0) { return i; } + } } return -1; From 294b034920ecf67cc436415fa84fd1529463ae04 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Thu, 15 Feb 2024 17:32:44 +0100 Subject: [PATCH 161/707] Add configuration files for expanded VICs. --- cfg/vic20-asm-32k.cfg | 21 +++++++++++++++++++++ cfg/vic20-asm-3k.cfg | 21 +++++++++++++++++++++ cfg/vic20-asm.cfg | 2 ++ 3 files changed, 44 insertions(+) create mode 100644 cfg/vic20-asm-32k.cfg create mode 100644 cfg/vic20-asm-3k.cfg diff --git a/cfg/vic20-asm-32k.cfg b/cfg/vic20-asm-32k.cfg new file mode 100644 index 000000000..622cfb26f --- /dev/null +++ b/cfg/vic20-asm-32k.cfg @@ -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; +} diff --git a/cfg/vic20-asm-3k.cfg b/cfg/vic20-asm-3k.cfg new file mode 100644 index 000000000..1afaf0b30 --- /dev/null +++ b/cfg/vic20-asm-3k.cfg @@ -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; +} diff --git a/cfg/vic20-asm.cfg b/cfg/vic20-asm.cfg index fc9d668e4..5f6c7cc74 100644 --- a/cfg/vic20-asm.cfg +++ b/cfg/vic20-asm.cfg @@ -1,3 +1,5 @@ +# Assembly program configuration for unexpanded VICs. + FEATURES { STARTADDRESS: default = $1001; } From f42e6a26b2b6f5f7df260cec15e21b04c8fee12c Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Sat, 17 Feb 2024 15:47:51 -0800 Subject: [PATCH 162/707] xstack bump to 512 --- libsrc/rp6502/read.c | 2 +- libsrc/rp6502/sysrename.c | 2 +- libsrc/rp6502/write.c | 2 +- libsrc/rp6502/write_xstack.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libsrc/rp6502/read.c b/libsrc/rp6502/read.c index eb96f779c..87a9bbf7d 100644 --- a/libsrc/rp6502/read.c +++ b/libsrc/rp6502/read.c @@ -5,7 +5,7 @@ int __fastcall__ read (int fildes, void* buf, unsigned count) { int total = 0; while (count) { - unsigned blockcount = (count > 256) ? 256 : count; + unsigned blockcount = (count > 512) ? 512 : count; int bytes_read = read_xstack (&((char*)buf)[total], blockcount, fildes); if (bytes_read < 0) { return bytes_read; diff --git a/libsrc/rp6502/sysrename.c b/libsrc/rp6502/sysrename.c index 96eca24cf..46bdd8b31 100644 --- a/libsrc/rp6502/sysrename.c +++ b/libsrc/rp6502/sysrename.c @@ -7,7 +7,7 @@ unsigned char __fastcall__ _sysrename (const char* oldpath, const char* newpath) size_t oldpathlen, newpathlen; oldpathlen = strlen (oldpath); newpathlen = strlen (newpath); - if (oldpathlen + newpathlen > 254) { + if (oldpathlen + newpathlen > 510) { return _mappederrno (EINVAL); } while (oldpathlen) { diff --git a/libsrc/rp6502/write.c b/libsrc/rp6502/write.c index 11241dab5..23877b6e8 100644 --- a/libsrc/rp6502/write.c +++ b/libsrc/rp6502/write.c @@ -5,7 +5,7 @@ int __fastcall__ write (int fildes, const void* buf, unsigned count) { int ax, total = 0; while (count) { - int blockcount = (count > 256) ? 256 : count; + int blockcount = (count > 512) ? 512 : count; ax = write_xstack (&((char*)buf)[total], blockcount, fildes); if (ax < 0) { return ax; diff --git a/libsrc/rp6502/write_xstack.c b/libsrc/rp6502/write_xstack.c index ff979899d..29285a87e 100644 --- a/libsrc/rp6502/write_xstack.c +++ b/libsrc/rp6502/write_xstack.c @@ -4,7 +4,7 @@ int __fastcall__ write_xstack (const void* buf, unsigned count, int fildes) { unsigned i; - if (count > 256) { + if (count > 512) { return _mappederrno (EINVAL); } for (i = count; i;) { From 4d3153e10e185323ca0d89c4d17b43bdffa803ca Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Sat, 17 Feb 2024 16:02:57 -0800 Subject: [PATCH 163/707] add rp6502 xregn --- include/rp6502.h | 2 ++ libsrc/rp6502/xregn.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 libsrc/rp6502/xregn.c diff --git a/include/rp6502.h b/include/rp6502.h index 53028c35a..7deeebc4c 100644 --- a/include/rp6502.h +++ b/include/rp6502.h @@ -117,6 +117,8 @@ long __fastcall__ ria_call_long_errno (unsigned char op); /* C API for the operating system. */ +int __cdecl__ xregn (char device, char channel, unsigned char address, unsigned count, + ...); int __cdecl__ xreg (char device, char channel, unsigned char address, ...); int phi2 (void); int codepage (void); diff --git a/libsrc/rp6502/xregn.c b/libsrc/rp6502/xregn.c new file mode 100644 index 000000000..ec040be20 --- /dev/null +++ b/libsrc/rp6502/xregn.c @@ -0,0 +1,19 @@ +#include +#include + +int __cdecl__ xregn (char device, char channel, unsigned char address, unsigned count, + ...) +{ + va_list args; + va_start (args, count); + RIA.xstack = device; + RIA.xstack = channel; + RIA.xstack = address; + while (count--) { + unsigned v = va_arg (args, unsigned); + RIA.xstack = v >> 8; + RIA.xstack = v; + } + va_end (args); + return ria_call_int_errno (RIA_OP_XREG); +} From 7a12399b39acd656da3d8802dca0ed1ef09d18c3 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Mon, 19 Feb 2024 13:27:42 +0100 Subject: [PATCH 164/707] 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. --- libsrc/apple2/ser/a2.ssc.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/apple2/ser/a2.ssc.s b/libsrc/apple2/ser/a2.ssc.s index c8aa6e9a5..7053b7bb1 100644 --- a/libsrc/apple2/ser/a2.ssc.s +++ b/libsrc/apple2/ser/a2.ssc.s @@ -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 From 3fd78208bab5cd7d8fa601a4a94af3f66ed39ec1 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Mon, 19 Feb 2024 18:27:34 +0100 Subject: [PATCH 165/707] Disable IRQ if opening at 115200 bps --- doc/apple2.sgml | 5 +++++ doc/apple2enh.sgml | 5 +++++ libsrc/apple2/ser/a2.ssc.s | 10 ++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index e6ec870ee..99ff8139e 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -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 Date: Mon, 19 Feb 2024 21:30:26 +0100 Subject: [PATCH 166/707] 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. --- libsrc/apple2/ser/a2.gs.s | 66 +++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/libsrc/apple2/ser/a2.gs.s b/libsrc/apple2/ser/a2.gs.s index 3a2db1926..c53fe7ecb 100644 --- a/libsrc/apple2/ser/a2.gs.s +++ b/libsrc/apple2/ser/a2.gs.s @@ -66,6 +66,8 @@ HSType: .res 1 ; Flow-control type RecvBuf: .res 256 ; Receive buffers: 256 bytes SendBuf: .res 256 ; Send buffers: 256 bytes +ClockSource: .res 1 ; Whether to use BRG or XTAL for clock + .data Opened: .byte $00 ; 1 when opened @@ -106,6 +108,15 @@ TxBitTable: .byte %00000000 ; SER_BITS_5, in WR_TX_CTRL (WR5) .rodata +ClockMultiplier:.byte %01000000 ; Clock x16 (300-57600bps, ref page 5-8) + .byte %10000000 ; Clock x32 (115200bps, ref page 5-8) + +ClockSourceA: .byte %11010000 ; Use baud rate generator (page 5-17) + .byte %10000000 ; Use XTAL (115200bps) + +ClockSourceB: .byte %01010000 ; Use baud rate generator + .byte %00000000 ; Use XTAL (115200bps) + BaudTable: ; bit7 = 1 means setting is invalid ; Otherwise refers to the index in ; Baud(Low/High)Table @@ -127,7 +138,7 @@ BaudTable: ; bit7 = 1 means setting is invalid .byte $05 ; SER_BAUD_19200 .byte $06 ; SER_BAUD_38400 .byte $07 ; SER_BAUD_57600 - .byte $FF ; SER_BAUD_115200 + .byte $00 ; SER_BAUD_115200 .byte $FF ; SER_BAUD_230400 StopTable: .byte %00000100 ; SER_STOP_1, in WR_TX_RX_CTRL (WR4) @@ -180,7 +191,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 +207,13 @@ 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 +MISC_CTRL_RATE_GEN_ON = %00000001 ; STA'd +MISC_CTRL_RATE_GEN_OFF = %00000000 ; STA'd WR_IRQ_CTRL = 15 ; (Ref page 5-20) IRQ_CLEANUP_EIRQ = %00001000 @@ -329,6 +337,16 @@ IIgs: : txa ; Promote char return value rts +getClockSource: + ldy #SER_PARAMS::BAUDRATE + lda (ptr1),y ; Baudrate index - cc65 value + ldy #$01 + cmp #SER_BAUD_115200 + beq :+ + ldy #$00 +: sty ClockSource + rts + ;---------------------------------------------------------------------------- ; SER_OPEN: A pointer to a ser_params structure is passed in ptr1. ; Must return an SER_ERR_xx code in a/x. @@ -364,6 +382,8 @@ SER_OPEN: lda #$00 jsr writeSCCReg + jsr getClockSource ; Should we use BRG or XTAL? + ldy #SER_PARAMS::STOPBITS lda (ptr1),y ; Stop bits tay @@ -377,16 +397,18 @@ SER_OPEN: ora ParityTable,y ; Get value bmi InvParam - ora #TX_RX_CLOCK_MUL + ldy ClockSource ; Setup clock multiplier + ora ClockMultiplier,y ldy #WR_TX_RX_CTRL ; Setup stop & parity bits jsr writeSCCReg + ldy ClockSource cpx #CHANNEL_B bne ClockA ClockB: + lda ClockSourceB,y ldy #WR_CLOCK_CTRL - lda #CLOCK_CTRL_CH_B jsr writeSCCReg lda #INTR_PENDING_RX_EXT_B ; Store which IRQ bits we'll check @@ -394,8 +416,8 @@ ClockB: bra SetBaud ClockA: + lda ClockSourceA,y ldy #WR_CLOCK_CTRL - lda #CLOCK_CTRL_CH_A jsr writeSCCReg lda #INTR_PENDING_RX_EXT_A ; Store which IRQ bits we'll check @@ -411,11 +433,16 @@ SetBaud: InvParam: lda #SER_ERR_INIT_FAILED - ldy #$00 ; Mark port closed - bra SetupOut + ldx #$00 ; Promote char return value + stz Opened ; Mark port closed + cli + rts BaudOK: tay + cpy #SER_BAUD_115200 + beq :+ ; Skip baud rate generator setup: + ; For 115200bps, we use XTAL instead lda BaudLowTable,y ; Get low byte @@ -428,8 +455,13 @@ BaudOK: ldy #WR_BAUDH_CTRL jsr writeSCCReg - ldy #WR_MISC_CTRL ; Time to turn this thing on - lda #MISC_CTRL_RATE_GEN_ON +: lda #MISC_CTRL_RATE_GEN_ON ; Setup BRG according to selected rate + ldy ClockSource + cpy #$00 + beq :+ + lda #MISC_CTRL_RATE_GEN_OFF + +: ldy #WR_MISC_CTRL ; Time to turn this thing on jsr writeSCCReg ldy #SER_PARAMS::DATABITS @@ -486,11 +518,11 @@ StoreFlag: sta SER_FLAG ldy #$01 ; Mark port opened - lda #SER_ERR_OK - -SetupOut: - ldx #$00 ; Promote char return value sty Opened + + lda #SER_ERR_OK + ldx #$00 ; Promote char return value + cli rts From 86317711e0931af0dc735ca7a0715369d0d0310c Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Tue, 20 Feb 2024 07:17:12 +0100 Subject: [PATCH 167/707] IIgs SCC: Rework branches to X-indexed variables and general cleanup/commenting --- libsrc/apple2/ser/a2.gs.s | 244 +++++++++++++++++--------------------- 1 file changed, 110 insertions(+), 134 deletions(-) diff --git a/libsrc/apple2/ser/a2.gs.s b/libsrc/apple2/ser/a2.gs.s index c53fe7ecb..e35c6156b 100644 --- a/libsrc/apple2/ser/a2.gs.s +++ b/libsrc/apple2/ser/a2.gs.s @@ -66,36 +66,16 @@ HSType: .res 1 ; Flow-control type RecvBuf: .res 256 ; Receive buffers: 256 bytes SendBuf: .res 256 ; Send buffers: 256 bytes -ClockSource: .res 1 ; Whether to use BRG or XTAL for clock +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 @@ -108,38 +88,65 @@ TxBitTable: .byte %00000000 ; SER_BITS_5, in WR_TX_CTRL (WR5) .rodata -ClockMultiplier:.byte %01000000 ; Clock x16 (300-57600bps, ref page 5-8) +ClockMultiplier:.byte %01000000 ; Clock x16 (300-57600bps, WR4, ref page 5-8) .byte %10000000 ; Clock x32 (115200bps, ref page 5-8) -ClockSourceA: .byte %11010000 ; Use baud rate generator (page 5-17) - .byte %10000000 ; Use XTAL (115200bps) +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) -ClockSourceB: .byte %01010000 ; Use baud rate generator - .byte %00000000 ; Use XTAL (115200bps) +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 $00 ; 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) @@ -167,6 +174,7 @@ SER_FLAG := $E10104 ; ------------------------------------------------------------------------ ; Channels + CHANNEL_B = 0 CHANNEL_A = 1 @@ -212,8 +220,6 @@ 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 ; STA'd -MISC_CTRL_RATE_GEN_OFF = %00000000 ; STA'd WR_IRQ_CTRL = 15 ; (Ref page 5-20) IRQ_CLEANUP_EIRQ = %00001000 @@ -228,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. @@ -338,13 +339,12 @@ IIgs: rts getClockSource: - ldy #SER_PARAMS::BAUDRATE - lda (ptr1),y ; Baudrate index - cc65 value - ldy #$01 + .assert SER_PARAMS::BAUDRATE = 0, error + lda (ptr1) ; Baudrate index - cc65 value cmp #SER_BAUD_115200 - beq :+ - ldy #$00 -: sty ClockSource + lda #$00 + adc #$00 + sta CurClockSource ; 0 = BRG, 1 = RTxC rts ;---------------------------------------------------------------------------- @@ -378,13 +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 - jsr getClockSource ; Should we use BRG or XTAL? + jsr getClockSource ; Should we use BRG or RTxC? - ldy #SER_PARAMS::STOPBITS + ldy #SER_PARAMS::STOPBITS ; WR4 setup: clock mult., stop & parity lda (ptr1),y ; Stop bits tay lda StopTable,y ; Get value @@ -397,109 +397,92 @@ SER_OPEN: ora ParityTable,y ; Get value bmi InvParam - ldy ClockSource ; Setup clock multiplier + 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 ClockSource + ldy CurClockSource ; WR11 setup: clock source cpx #CHANNEL_B - bne ClockA -ClockB: - lda ClockSourceB,y + beq SetClock + iny ; Shift to get correct ClockSource val + iny ; depending on our channel + +SetClock: + lda ClockSource,y ldy #WR_CLOCK_CTRL - 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: - lda ClockSourceA,y - ldy #WR_CLOCK_CTRL - 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: lda #SER_ERR_INIT_FAILED - ldx #$00 ; Promote char return value - stz Opened ; Mark port closed - cli - rts + ldy #$00 ; Mark port closed + bra SetupOut BaudOK: - tay - cpy #SER_BAUD_115200 - beq :+ ; Skip baud rate generator setup: - ; For 115200bps, we use XTAL instead - - 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 -: lda #MISC_CTRL_RATE_GEN_ON ; Setup BRG according to selected rate - ldy ClockSource - cpy #$00 - beq :+ - lda #MISC_CTRL_RATE_GEN_OFF - -: ldy #WR_MISC_CTRL ; Time to turn this thing on + ldy CurClockSource ; WR14 setup: BRG enabling + lda BrgEnabled,y + ldy #WR_MISC_CTRL ; Time to turn this thing 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 @@ -507,22 +490,15 @@ 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 - sty Opened - lda #SER_ERR_OK - ldx #$00 ; Promote char return value +SetupOut: + ldx #$00 ; Promote char return value + sty Opened cli rts From 23aa562094bdfeca0eb9d2e13b94b5f3208fa575 Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 24 Feb 2024 15:34:38 +0800 Subject: [PATCH 168/707] Fixed potential errors with subtraction evaluation of identifiers at different memory locations. --- src/cc65/expr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index a855e5b3c..f6c681db8 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -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); From 9b2d27d1e1a24a912978f8fa496f921523e3f909 Mon Sep 17 00:00:00 2001 From: acqn Date: Thu, 29 Feb 2024 18:23:04 +0800 Subject: [PATCH 169/707] Fixed the error recovery integer type used for bit-fields. --- src/cc65/declare.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index e1e66ab85..11e6c5227 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -905,6 +905,8 @@ static int ParseFieldWidth (Declarator* D) ** otherwise the width of the field. */ { + ExprDesc Expr; + if (CurTok.Tok != TOK_COLON) { /* No bit-field declaration */ return -1; @@ -918,7 +920,16 @@ static int ParseFieldWidth (Declarator* D) /* Avoid a diagnostic storm by giving the bit-field the widest valid ** signed type, and continuing to parse. */ - D->Type[0].C = T_INT; + D->Type[0].C = T_LONG; + } + + if (IsTypeEnum (D->Type) && IsIncompleteESUType (D->Type)) { + /* If the type is an enum, it must be complete */ + Error ("Bit-field has incomplete type '%s'", + GetFullTypeName (D->Type)); + + /* Avoid a diagnostic storm */ + D->Type[0].C = T_LONG; } /* We currently support integral types up to long */ @@ -927,12 +938,12 @@ static int ParseFieldWidth (Declarator* D) Error ("cc65 currently supports only long-sized and smaller bit-field types"); /* Avoid a diagnostic storm */ - D->Type[0].C = T_INT; + D->Type[0].C = T_LONG; } /* Read the width */ NextToken (); - ExprDesc Expr = NoCodeConstAbsIntExpr (hie1); + Expr = NoCodeConstAbsIntExpr (hie1); if (Expr.IVal < 0) { Error ("Negative width in bit-field"); From 98767741ced8a3d836cfa12748e91d40ba6ac181 Mon Sep 17 00:00:00 2001 From: acqn Date: Thu, 29 Feb 2024 18:24:22 +0800 Subject: [PATCH 170/707] Reorganized stuff in src/cc65/declare.c. --- src/cc65/declare.c | 996 +++++++++++++++++++++++---------------------- 1 file changed, 507 insertions(+), 489 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index e1e66ab85..bae1a3be8 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -71,17 +71,33 @@ -static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags); -/* Parse a type specifier */ +static SymEntry* ParseEnumSpec (const char* Name, unsigned* DSFlags); +/* Parse an enum specifier */ + +static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags); +/* Parse a union specifier */ + +static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags); +/* Parse a struct specifier */ /*****************************************************************************/ -/* Internal functions */ +/* Type specification parser */ /*****************************************************************************/ +static void InitDeclSpec (DeclSpec* Spec) +/* Initialize the DeclSpec struct for use */ +{ + Spec->StorageClass = 0; + Spec->Type[0].C = T_END; + Spec->Flags = 0; +} + + + static unsigned ParseOneStorageClass (void) /* Parse and return a storage class specifier */ { @@ -421,255 +437,284 @@ static void UseDefaultType (DeclSpec* Spec, typespec_t TSFlags) -static void InitDeclSpec (DeclSpec* Spec) -/* Initialize the DeclSpec struct for use */ -{ - Spec->StorageClass = 0; - Spec->Type[0].C = T_END; - Spec->Flags = 0; -} - - - -static void InitDeclarator (Declarator* D) -/* Initialize the Declarator struct for use */ -{ - D->Ident[0] = '\0'; - D->Type[0].C = T_END; - D->Index = 0; - D->Attributes = 0; -} - - - -static void NeedTypeSpace (Declarator* D, unsigned Count) -/* Check if there is enough space for Count type specifiers within D */ -{ - if (D->Index + Count >= MAXTYPELEN) { - /* We must call Fatal() here, since calling Error() will try to - ** continue, and the declaration type is not correctly terminated - ** in case we come here. - */ - Fatal ("Too many type specifiers"); - } -} - - - -static void AddTypeCodeToDeclarator (Declarator* D, TypeCode T) -/* Add a type specifier to the type of a declarator */ -{ - NeedTypeSpace (D, 1); - D->Type[D->Index++].C = T; -} - - - -static void FixQualifiers (Type* DataType) -/* Apply several fixes to qualifiers */ -{ - Type* T; - TypeCode Q; - - /* Using typedefs, it is possible to generate declarations that have - ** type qualifiers attached to an array, not the element type. Go and - ** fix these here. - */ - T = DataType; - Q = T_QUAL_NONE; - while (T->C != T_END) { - if (IsTypeArray (T)) { - /* Extract any type qualifiers */ - Q |= GetQualifier (T); - T->C = GetUnqualRawTypeCode (T); - } else { - /* Add extracted type qualifiers here */ - T->C |= Q; - Q = T_QUAL_NONE; - } - ++T; - } - /* Q must be empty now */ - CHECK (Q == T_QUAL_NONE); - - /* Do some fixes on pointers and functions. */ - T = DataType; - while (T->C != T_END) { - if (IsTypePtr (T)) { - /* Calling convention qualifier on the pointer? */ - if (IsQualCConv (T)) { - /* Pull the convention off of the pointer */ - Q = T[0].C & T_QUAL_CCONV; - T[0].C &= ~T_QUAL_CCONV; - - /* Pointer to a function which doesn't have an explicit convention? */ - if (IsTypeFunc (T + 1)) { - if (IsQualCConv (T + 1)) { - if ((T[1].C & T_QUAL_CCONV) == Q) { - Warning ("Pointer duplicates function's calling convention"); - } else { - Error ("Function's and pointer's calling conventions are different"); - } - } else { - if (Q == T_QUAL_FASTCALL && IsVariadicFunc (T + 1)) { - Error ("Variadic-function pointers cannot be __fastcall__"); - } else { - /* Move the qualifier from the pointer to the function. */ - T[1].C |= Q; - } - } - } else { - Error ("Not pointer to a function; can't use a calling convention"); - } - } - - /* Apply the default far and near qualifiers if none are given */ - Q = (T[0].C & T_QUAL_ADDRSIZE); - if (Q == T_QUAL_NONE) { - /* No address size qualifiers specified */ - if (IsTypeFunc (T+1)) { - /* Pointer to function. Use the qualifier from the function, - ** or the default if the function doesn't have one. - */ - Q = (T[1].C & T_QUAL_ADDRSIZE); - if (Q == T_QUAL_NONE) { - Q = CodeAddrSizeQualifier (); - } - } else { - Q = DataAddrSizeQualifier (); - } - T[0].C |= Q; - } else { - /* We have address size qualifiers. If followed by a function, - ** apply them to the function also. - */ - if (IsTypeFunc (T+1)) { - TypeCode FQ = (T[1].C & T_QUAL_ADDRSIZE); - if (FQ == T_QUAL_NONE) { - T[1].C |= Q; - } else if (FQ != Q) { - Error ("Address size qualifier mismatch"); - T[1].C = (T[1].C & ~T_QUAL_ADDRSIZE) | Q; - } - } - } - - } else if (IsTypeFunc (T)) { - - /* Apply the default far and near qualifiers if none are given */ - if ((T[0].C & T_QUAL_ADDRSIZE) == 0) { - T[0].C |= CodeAddrSizeQualifier (); - } - - } else { - - /* If we have remaining qualifiers, flag them as invalid */ - Q = T[0].C; - - if (Q & T_QUAL_NEAR) { - Error ("Invalid '__near__' qualifier"); - Q &= ~T_QUAL_NEAR; - } - if (Q & T_QUAL_FAR) { - Error ("Invalid '__far__' qualifier"); - Q &= ~T_QUAL_FAR; - } - if (Q & T_QUAL_FASTCALL) { - Error ("Invalid '__fastcall__' qualifier"); - Q &= ~T_QUAL_FASTCALL; - } - if (Q & T_QUAL_CDECL) { - Error ("Invalid '__cdecl__' qualifier"); - Q &= ~T_QUAL_CDECL; - } - - /* Clear the invalid qualifiers */ - T[0].C &= Q; - - } - ++T; - } -} - - - -static void FixFunctionReturnType (Type* T) -/* Check if the data type consists of any functions returning forbidden return -** types and remove qualifiers from the return types if they are not void. +static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags) +/* Parse a type specifier. Store whether one of "signed" or "unsigned" was +** specified, so bit-fields of unspecified signedness can be treated as +** unsigned; without special handling, it would be treated as signed. */ { - while (T->C != T_END) { - if (IsTypeFunc (T)) { - ++T; + ident Ident; + SymEntry* TagEntry; + TypeCode Qualifiers = T_QUAL_NONE; - /* Functions may not return functions or arrays */ - if (IsTypeFunc (T)) { - Error ("Functions are not allowed to return functions"); - } else if (IsTypeArray (T)) { - Error ("Functions are not allowed to return arrays"); + /* Assume we have an explicitly specified type */ + Spec->Flags = (Spec->Flags & ~DS_TYPE_MASK) | DS_EXPLICIT_TYPE; + + /* Read storage specifiers and/or type qualifiers if we have any */ + OptionalSpecifiers (Spec, &Qualifiers, TSFlags); + + /* Look at the data type */ + switch (CurTok.Tok) { + + case TOK_VOID: + NextToken (); + Spec->Type[0].C = T_VOID; + Spec->Type[0].A.U = 0; + Spec->Type[1].C = T_END; + break; + + case TOK_CHAR: + NextToken (); + Spec->Type[0].C = T_CHAR; + Spec->Type[1].C = T_END; + break; + + case TOK_LONG: + NextToken (); + if (CurTok.Tok == TOK_UNSIGNED) { + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; + NextToken (); + OptionalInt (); + Spec->Type[0].C = T_ULONG; + Spec->Type[1].C = T_END; + } else { + OptionalSigned (Spec); + OptionalInt (); + Spec->Type[0].C = T_LONG; + Spec->Type[1].C = T_END; } + break; - /* The return type must not be qualified */ - if ((GetQualifier (T) & T_QUAL_CVR) != T_QUAL_NONE) { - /* We are stricter than the standard here */ - if (GetRawTypeRank (T) == T_RANK_VOID) { - /* A qualified void type is always an error */ - Error ("Function definition has qualified void return type"); - } else { - /* For others, qualifiers are ignored */ - Warning ("Type qualifiers ignored on function return type"); - T[0].C &= ~T_QUAL_CVR; - } + case TOK_SHORT: + NextToken (); + if (CurTok.Tok == TOK_UNSIGNED) { + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; + NextToken (); + OptionalInt (); + Spec->Type[0].C = T_USHORT; + Spec->Type[1].C = T_END; + } else { + OptionalSigned (Spec); + OptionalInt (); + Spec->Type[0].C = T_SHORT; + Spec->Type[1].C = T_END; } - } else { - ++T; - } - } -} + break; + case TOK_INT: + NextToken (); + Spec->Type[0].C = T_INT; + Spec->Type[1].C = T_END; + break; + case TOK_SIGNED: + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; + NextToken (); + switch (CurTok.Tok) { -static void CheckArrayElementType (const Type* T) -/* Check recursively if type consists of arrays of forbidden element types */ -{ - while (T->C != T_END) { - if (IsTypeArray (T)) { - /* If the array is multi-dimensional, keep going until we get the - ** true element type. + case TOK_CHAR: + NextToken (); + Spec->Type[0].C = T_SCHAR; + Spec->Type[1].C = T_END; + break; + + case TOK_SHORT: + NextToken (); + OptionalInt (); + Spec->Type[0].C = T_SHORT; + Spec->Type[1].C = T_END; + break; + + case TOK_LONG: + NextToken (); + OptionalInt (); + Spec->Type[0].C = T_LONG; + Spec->Type[1].C = T_END; + break; + + case TOK_INT: + NextToken (); + /* FALL THROUGH */ + + default: + Spec->Type[0].C = T_INT; + Spec->Type[1].C = T_END; + break; + } + break; + + case TOK_UNSIGNED: + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; + NextToken (); + switch (CurTok.Tok) { + + case TOK_CHAR: + NextToken (); + Spec->Type[0].C = T_UCHAR; + Spec->Type[1].C = T_END; + break; + + case TOK_SHORT: + NextToken (); + OptionalInt (); + Spec->Type[0].C = T_USHORT; + Spec->Type[1].C = T_END; + break; + + case TOK_LONG: + NextToken (); + OptionalInt (); + Spec->Type[0].C = T_ULONG; + Spec->Type[1].C = T_END; + break; + + case TOK_INT: + NextToken (); + /* FALL THROUGH */ + + default: + Spec->Type[0].C = T_UINT; + Spec->Type[1].C = T_END; + break; + } + break; + + case TOK_FLOAT: + NextToken (); + Spec->Type[0].C = T_FLOAT; + Spec->Type[1].C = T_END; + break; + + case TOK_DOUBLE: + NextToken (); + Spec->Type[0].C = T_DOUBLE; + Spec->Type[1].C = T_END; + break; + + case TOK_UNION: + NextToken (); + /* Remember we have an extra type decl */ + Spec->Flags |= DS_EXTRA_TYPE; + /* Check for tag name */ + if (CurTok.Tok == TOK_IDENT) { + strcpy (Ident, CurTok.Ident); + NextToken (); + } else if (CurTok.Tok == TOK_LCURLY) { + AnonName (Ident, "union"); + } else { + Error ("Tag name identifier or '{' expected"); + UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); + break; + } + /* Declare the union in the current scope */ + TagEntry = ParseUnionSpec (Ident, &Spec->Flags); + /* Encode the union entry into the type */ + Spec->Type[0].C = T_UNION; + SetESUTagSym (Spec->Type, TagEntry); + Spec->Type[1].C = T_END; + break; + + case TOK_STRUCT: + NextToken (); + /* Remember we have an extra type decl */ + Spec->Flags |= DS_EXTRA_TYPE; + /* Check for tag name */ + if (CurTok.Tok == TOK_IDENT) { + strcpy (Ident, CurTok.Ident); + NextToken (); + } else if (CurTok.Tok == TOK_LCURLY) { + AnonName (Ident, "struct"); + } else { + Error ("Tag name identifier or '{' expected"); + UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); + break; + } + /* Declare the struct in the current scope */ + TagEntry = ParseStructSpec (Ident, &Spec->Flags); + /* Encode the struct entry into the type */ + Spec->Type[0].C = T_STRUCT; + SetESUTagSym (Spec->Type, TagEntry); + Spec->Type[1].C = T_END; + break; + + case TOK_ENUM: + NextToken (); + /* Remember we have an extra type decl */ + Spec->Flags |= DS_EXTRA_TYPE; + /* Check for tag name */ + if (CurTok.Tok == TOK_IDENT) { + strcpy (Ident, CurTok.Ident); + NextToken (); + } else if (CurTok.Tok == TOK_LCURLY) { + AnonName (Ident, "enum"); + } else { + Error ("Tag name identifier or '{' expected"); + UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); + break; + } + /* Parse the enum decl */ + TagEntry = ParseEnumSpec (Ident, &Spec->Flags); + /* Encode the enum entry into the type */ + Spec->Type[0].C |= T_ENUM; + SetESUTagSym (Spec->Type, TagEntry); + Spec->Type[1].C = T_END; + /* The signedness of enums is determined by the type, so say this is specified to avoid + ** the int -> unsigned int handling for plain int bit-fields in AddBitField. */ - ++T; - if (SizeOf (T) == 0) { - if (IsTypeArray (T) || IsIncompleteESUType (T)) { - /* We cannot have an array of incomplete elements */ - if (!IsTypeArray (T) || GetElementCount (T) == UNSPECIFIED) { - Error ("Array of incomplete element type '%s'", - GetFullTypeName (T)); - return; - } - } else if (!IsTypeVoid (T) || IS_Get (&Standard) != STD_CC65) { - /* We could support certain 0-size element types as an extension */ - Error ("Array of 0-size element type '%s'", - GetFullTypeName (T)); - return; + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; + break; + + case TOK_IDENT: + /* This could be a label */ + if (NextTok.Tok != TOK_COLON || GetLexicalLevel () == LEX_LEVEL_STRUCT) { + TagEntry = FindSym (CurTok.Ident); + if (TagEntry && SymIsTypeDef (TagEntry)) { + /* It's a typedef */ + NextToken (); + TypeCopy (Spec->Type, TagEntry->Type); + /* If it's a typedef, we should actually use whether the signedness was + ** specified on the typedef, but that information has been lost. Treat the + ** signedness as being specified to work around the ICE in #1267. + ** Unforunately, this will cause plain int bit-fields defined via typedefs + ** to be treated as signed rather than unsigned. + */ + Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; + break; + } else if ((TSFlags & TS_MASK_DEFAULT_TYPE) == TS_DEFAULT_TYPE_NONE) { + /* Treat this identifier as an unknown type */ + Error ("Unknown type name '%s'", CurTok.Ident); + TypeCopy (Spec->Type, type_int); + NextToken (); + break; } } else { - /* Elements cannot contain flexible array members themselves */ - if (IsClassStruct (T)) { - SymEntry* TagEntry = GetESUTagSym (T); - if (TagEntry && SymHasFlexibleArrayMember (TagEntry)) { - Error ("Invalid use of struct with flexible array member"); - return; - } - } + /* This is a label. Use the default type flag to end the loop + ** in DeclareLocals. The type code used here doesn't matter as + ** long as it has no qualifiers. + */ + UseDefaultType (Spec, TS_DEFAULT_TYPE_INT); + break; } - } else { - ++T; - } + /* FALL THROUGH */ + + default: + UseDefaultType (Spec, TSFlags); + break; } + + /* There may also be specifiers/qualifiers *after* the initial type */ + OptionalSpecifiers (Spec, &Qualifiers, TSFlags); + Spec->Type[0].C |= Qualifiers; } +/*****************************************************************************/ +/* Enum/struct/union parser */ +/*****************************************************************************/ + + + static SymEntry* ForwardESU (const char* Name, unsigned Flags, unsigned* DSFlags) /* Handle an enum, struct or union forward declaration */ { @@ -731,7 +776,7 @@ static const Type* GetEnumeratorType (long Min, unsigned long Max, int Signed) static SymEntry* ParseEnumSpec (const char* Name, unsigned* DSFlags) -/* Process an enum specifier */ +/* Parse an enum specifier */ { SymTable* FieldTab; long EnumVal; @@ -1505,274 +1550,247 @@ EndOfDecl: -static void ParseTypeSpec (DeclSpec* Spec, typespec_t TSFlags) -/* Parse a type specifier. Store whether one of "signed" or "unsigned" was -** specified, so bit-fields of unspecified signedness can be treated as -** unsigned; without special handling, it would be treated as signed. +/*****************************************************************************/ +/* Declarator parser */ +/*****************************************************************************/ + + + +static void InitDeclarator (Declarator* D) +/* Initialize the Declarator struct for use */ +{ + D->Ident[0] = '\0'; + D->Type[0].C = T_END; + D->Index = 0; + D->Attributes = 0; +} + + + +static void NeedTypeSpace (Declarator* D, unsigned Count) +/* Check if there is enough space for Count type specifiers within D */ +{ + if (D->Index + Count >= MAXTYPELEN) { + /* We must call Fatal() here, since calling Error() will try to + ** continue, and the declaration type is not correctly terminated + ** in case we come here. + */ + Fatal ("Too many type specifiers"); + } +} + + + +static void AddTypeCodeToDeclarator (Declarator* D, TypeCode T) +/* Add a type specifier to the type of a declarator */ +{ + NeedTypeSpace (D, 1); + D->Type[D->Index++].C = T; +} + + + +static void FixQualifiers (Type* DataType) +/* Apply several fixes to qualifiers */ +{ + Type* T; + TypeCode Q; + + /* Using typedefs, it is possible to generate declarations that have + ** type qualifiers attached to an array, not the element type. Go and + ** fix these here. + */ + T = DataType; + Q = T_QUAL_NONE; + while (T->C != T_END) { + if (IsTypeArray (T)) { + /* Extract any type qualifiers */ + Q |= GetQualifier (T); + T->C = GetUnqualRawTypeCode (T); + } else { + /* Add extracted type qualifiers here */ + T->C |= Q; + Q = T_QUAL_NONE; + } + ++T; + } + /* Q must be empty now */ + CHECK (Q == T_QUAL_NONE); + + /* Do some fixes on pointers and functions. */ + T = DataType; + while (T->C != T_END) { + if (IsTypePtr (T)) { + /* Calling convention qualifier on the pointer? */ + if (IsQualCConv (T)) { + /* Pull the convention off of the pointer */ + Q = T[0].C & T_QUAL_CCONV; + T[0].C &= ~T_QUAL_CCONV; + + /* Pointer to a function which doesn't have an explicit convention? */ + if (IsTypeFunc (T + 1)) { + if (IsQualCConv (T + 1)) { + if ((T[1].C & T_QUAL_CCONV) == Q) { + Warning ("Pointer duplicates function's calling convention"); + } else { + Error ("Function's and pointer's calling conventions are different"); + } + } else { + if (Q == T_QUAL_FASTCALL && IsVariadicFunc (T + 1)) { + Error ("Variadic-function pointers cannot be __fastcall__"); + } else { + /* Move the qualifier from the pointer to the function. */ + T[1].C |= Q; + } + } + } else { + Error ("Not pointer to a function; can't use a calling convention"); + } + } + + /* Apply the default far and near qualifiers if none are given */ + Q = (T[0].C & T_QUAL_ADDRSIZE); + if (Q == T_QUAL_NONE) { + /* No address size qualifiers specified */ + if (IsTypeFunc (T+1)) { + /* Pointer to function. Use the qualifier from the function, + ** or the default if the function doesn't have one. + */ + Q = (T[1].C & T_QUAL_ADDRSIZE); + if (Q == T_QUAL_NONE) { + Q = CodeAddrSizeQualifier (); + } + } else { + Q = DataAddrSizeQualifier (); + } + T[0].C |= Q; + } else { + /* We have address size qualifiers. If followed by a function, + ** apply them to the function also. + */ + if (IsTypeFunc (T+1)) { + TypeCode FQ = (T[1].C & T_QUAL_ADDRSIZE); + if (FQ == T_QUAL_NONE) { + T[1].C |= Q; + } else if (FQ != Q) { + Error ("Address size qualifier mismatch"); + T[1].C = (T[1].C & ~T_QUAL_ADDRSIZE) | Q; + } + } + } + + } else if (IsTypeFunc (T)) { + + /* Apply the default far and near qualifiers if none are given */ + if ((T[0].C & T_QUAL_ADDRSIZE) == 0) { + T[0].C |= CodeAddrSizeQualifier (); + } + + } else { + + /* If we have remaining qualifiers, flag them as invalid */ + Q = T[0].C; + + if (Q & T_QUAL_NEAR) { + Error ("Invalid '__near__' qualifier"); + Q &= ~T_QUAL_NEAR; + } + if (Q & T_QUAL_FAR) { + Error ("Invalid '__far__' qualifier"); + Q &= ~T_QUAL_FAR; + } + if (Q & T_QUAL_FASTCALL) { + Error ("Invalid '__fastcall__' qualifier"); + Q &= ~T_QUAL_FASTCALL; + } + if (Q & T_QUAL_CDECL) { + Error ("Invalid '__cdecl__' qualifier"); + Q &= ~T_QUAL_CDECL; + } + + /* Clear the invalid qualifiers */ + T[0].C &= Q; + + } + ++T; + } +} + + + +static void FixFunctionReturnType (Type* T) +/* Check if the data type consists of any functions returning forbidden return +** types and remove qualifiers from the return types if they are not void. */ { - ident Ident; - SymEntry* TagEntry; - TypeCode Qualifiers = T_QUAL_NONE; + while (T->C != T_END) { + if (IsTypeFunc (T)) { + ++T; - /* Assume we have an explicitly specified type */ - Spec->Flags = (Spec->Flags & ~DS_TYPE_MASK) | DS_EXPLICIT_TYPE; - - /* Read storage specifiers and/or type qualifiers if we have any */ - OptionalSpecifiers (Spec, &Qualifiers, TSFlags); - - /* Look at the data type */ - switch (CurTok.Tok) { - - case TOK_VOID: - NextToken (); - Spec->Type[0].C = T_VOID; - Spec->Type[0].A.U = 0; - Spec->Type[1].C = T_END; - break; - - case TOK_CHAR: - NextToken (); - Spec->Type[0].C = T_CHAR; - Spec->Type[1].C = T_END; - break; - - case TOK_LONG: - NextToken (); - if (CurTok.Tok == TOK_UNSIGNED) { - Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; - NextToken (); - OptionalInt (); - Spec->Type[0].C = T_ULONG; - Spec->Type[1].C = T_END; - } else { - OptionalSigned (Spec); - OptionalInt (); - Spec->Type[0].C = T_LONG; - Spec->Type[1].C = T_END; + /* Functions may not return functions or arrays */ + if (IsTypeFunc (T)) { + Error ("Functions are not allowed to return functions"); + } else if (IsTypeArray (T)) { + Error ("Functions are not allowed to return arrays"); } - break; - case TOK_SHORT: - NextToken (); - if (CurTok.Tok == TOK_UNSIGNED) { - Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; - NextToken (); - OptionalInt (); - Spec->Type[0].C = T_USHORT; - Spec->Type[1].C = T_END; - } else { - OptionalSigned (Spec); - OptionalInt (); - Spec->Type[0].C = T_SHORT; - Spec->Type[1].C = T_END; + /* The return type must not be qualified */ + if ((GetQualifier (T) & T_QUAL_CVR) != T_QUAL_NONE) { + /* We are stricter than the standard here */ + if (GetRawTypeRank (T) == T_RANK_VOID) { + /* A qualified void type is always an error */ + Error ("Function definition has qualified void return type"); + } else { + /* For others, qualifiers are ignored */ + Warning ("Type qualifiers ignored on function return type"); + T[0].C &= ~T_QUAL_CVR; + } } - break; + } else { + ++T; + } + } +} - case TOK_INT: - NextToken (); - Spec->Type[0].C = T_INT; - Spec->Type[1].C = T_END; - break; - case TOK_SIGNED: - Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; - NextToken (); - switch (CurTok.Tok) { - case TOK_CHAR: - NextToken (); - Spec->Type[0].C = T_SCHAR; - Spec->Type[1].C = T_END; - break; - - case TOK_SHORT: - NextToken (); - OptionalInt (); - Spec->Type[0].C = T_SHORT; - Spec->Type[1].C = T_END; - break; - - case TOK_LONG: - NextToken (); - OptionalInt (); - Spec->Type[0].C = T_LONG; - Spec->Type[1].C = T_END; - break; - - case TOK_INT: - NextToken (); - /* FALL THROUGH */ - - default: - Spec->Type[0].C = T_INT; - Spec->Type[1].C = T_END; - break; - } - break; - - case TOK_UNSIGNED: - Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; - NextToken (); - switch (CurTok.Tok) { - - case TOK_CHAR: - NextToken (); - Spec->Type[0].C = T_UCHAR; - Spec->Type[1].C = T_END; - break; - - case TOK_SHORT: - NextToken (); - OptionalInt (); - Spec->Type[0].C = T_USHORT; - Spec->Type[1].C = T_END; - break; - - case TOK_LONG: - NextToken (); - OptionalInt (); - Spec->Type[0].C = T_ULONG; - Spec->Type[1].C = T_END; - break; - - case TOK_INT: - NextToken (); - /* FALL THROUGH */ - - default: - Spec->Type[0].C = T_UINT; - Spec->Type[1].C = T_END; - break; - } - break; - - case TOK_FLOAT: - NextToken (); - Spec->Type[0].C = T_FLOAT; - Spec->Type[1].C = T_END; - break; - - case TOK_DOUBLE: - NextToken (); - Spec->Type[0].C = T_DOUBLE; - Spec->Type[1].C = T_END; - break; - - case TOK_UNION: - NextToken (); - /* Remember we have an extra type decl */ - Spec->Flags |= DS_EXTRA_TYPE; - /* Check for tag name */ - if (CurTok.Tok == TOK_IDENT) { - strcpy (Ident, CurTok.Ident); - NextToken (); - } else if (CurTok.Tok == TOK_LCURLY) { - AnonName (Ident, "union"); - } else { - Error ("Tag name identifier or '{' expected"); - UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); - break; - } - /* Declare the union in the current scope */ - TagEntry = ParseUnionSpec (Ident, &Spec->Flags); - /* Encode the union entry into the type */ - Spec->Type[0].C = T_UNION; - SetESUTagSym (Spec->Type, TagEntry); - Spec->Type[1].C = T_END; - break; - - case TOK_STRUCT: - NextToken (); - /* Remember we have an extra type decl */ - Spec->Flags |= DS_EXTRA_TYPE; - /* Check for tag name */ - if (CurTok.Tok == TOK_IDENT) { - strcpy (Ident, CurTok.Ident); - NextToken (); - } else if (CurTok.Tok == TOK_LCURLY) { - AnonName (Ident, "struct"); - } else { - Error ("Tag name identifier or '{' expected"); - UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); - break; - } - /* Declare the struct in the current scope */ - TagEntry = ParseStructSpec (Ident, &Spec->Flags); - /* Encode the struct entry into the type */ - Spec->Type[0].C = T_STRUCT; - SetESUTagSym (Spec->Type, TagEntry); - Spec->Type[1].C = T_END; - break; - - case TOK_ENUM: - NextToken (); - /* Remember we have an extra type decl */ - Spec->Flags |= DS_EXTRA_TYPE; - /* Check for tag name */ - if (CurTok.Tok == TOK_IDENT) { - strcpy (Ident, CurTok.Ident); - NextToken (); - } else if (CurTok.Tok == TOK_LCURLY) { - AnonName (Ident, "enum"); - } else { - Error ("Tag name identifier or '{' expected"); - UseDefaultType (Spec, TS_DEFAULT_TYPE_NONE); - break; - } - /* Parse the enum decl */ - TagEntry = ParseEnumSpec (Ident, &Spec->Flags); - /* Encode the enum entry into the type */ - Spec->Type[0].C |= T_ENUM; - SetESUTagSym (Spec->Type, TagEntry); - Spec->Type[1].C = T_END; - /* The signedness of enums is determined by the type, so say this is specified to avoid - ** the int -> unsigned int handling for plain int bit-fields in AddBitField. +static void CheckArrayElementType (const Type* T) +/* Check recursively if type consists of arrays of forbidden element types */ +{ + while (T->C != T_END) { + if (IsTypeArray (T)) { + /* If the array is multi-dimensional, keep going until we get the + ** true element type. */ - Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; - break; - - case TOK_IDENT: - /* This could be a label */ - if (NextTok.Tok != TOK_COLON || GetLexicalLevel () == LEX_LEVEL_STRUCT) { - TagEntry = FindSym (CurTok.Ident); - if (TagEntry && SymIsTypeDef (TagEntry)) { - /* It's a typedef */ - NextToken (); - TypeCopy (Spec->Type, TagEntry->Type); - /* If it's a typedef, we should actually use whether the signedness was - ** specified on the typedef, but that information has been lost. Treat the - ** signedness as being specified to work around the ICE in #1267. - ** Unforunately, this will cause plain int bit-fields defined via typedefs - ** to be treated as signed rather than unsigned. - */ - Spec->Flags |= DS_EXPLICIT_SIGNEDNESS; - break; - } else if ((TSFlags & TS_MASK_DEFAULT_TYPE) == TS_DEFAULT_TYPE_NONE) { - /* Treat this identifier as an unknown type */ - Error ("Unknown type name '%s'", CurTok.Ident); - TypeCopy (Spec->Type, type_int); - NextToken (); - break; + ++T; + if (SizeOf (T) == 0) { + if (IsTypeArray (T) || IsIncompleteESUType (T)) { + /* We cannot have an array of incomplete elements */ + if (!IsTypeArray (T) || GetElementCount (T) == UNSPECIFIED) { + Error ("Array of incomplete element type '%s'", + GetFullTypeName (T)); + return; + } + } else if (!IsTypeVoid (T) || IS_Get (&Standard) != STD_CC65) { + /* We could support certain 0-size element types as an extension */ + Error ("Array of 0-size element type '%s'", + GetFullTypeName (T)); + return; } } else { - /* This is a label. Use the default type flag to end the loop - ** in DeclareLocals. The type code used here doesn't matter as - ** long as it has no qualifiers. - */ - UseDefaultType (Spec, TS_DEFAULT_TYPE_INT); - break; + /* Elements cannot contain flexible array members themselves */ + if (IsClassStruct (T)) { + SymEntry* TagEntry = GetESUTagSym (T); + if (TagEntry && SymHasFlexibleArrayMember (TagEntry)) { + Error ("Invalid use of struct with flexible array member"); + return; + } + } } - /* FALL THROUGH */ - - default: - UseDefaultType (Spec, TSFlags); - break; + } else { + ++T; + } } - - /* There may also be specifiers/qualifiers *after* the initial type */ - OptionalSpecifiers (Spec, &Qualifiers, TSFlags); - Spec->Type[0].C |= Qualifiers; } From 731f349b24ac065f9c140a4cd0ce3ef123fc3cb7 Mon Sep 17 00:00:00 2001 From: acqn Date: Thu, 29 Feb 2024 18:24:22 +0800 Subject: [PATCH 171/707] Removed ParamTypeCvt(). --- src/cc65/declare.c | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index bae1a3be8..a002862b8 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -1795,33 +1795,6 @@ static void CheckArrayElementType (const Type* T) -static const Type* ParamTypeCvt (Type* T) -/* If T is an array or a function, convert it to a pointer else do nothing. -** Return the resulting type. -*/ -{ - Type* Tmp = 0; - - if (IsTypeArray (T)) { - Tmp = ArrayToPtr (T); - } else if (IsTypeFunc (T)) { - Tmp = NewPointerTo (T); - } - - if (Tmp != 0) { - /* Do several fixes on qualifiers */ - FixQualifiers (Tmp); - - /* Replace the type */ - TypeCopy (T, Tmp); - TypeFree (Tmp); - } - - return T; -} - - - static void ParseOldStyleParamList (FuncDesc* F) /* Parse an old-style (K&R) parameter list */ { @@ -1929,7 +1902,7 @@ static void ParseOldStyleParamDeclList (FuncDesc* F attribute ((unused))) */ if (Param->Flags & SC_DEFTYPE) { /* Found it, change the default type to the one given */ - SymChangeType (Param, ParamTypeCvt (Decl.Type)); + SymChangeType (Param, PtrConversion (Decl.Type)); /* Reset the "default type" flag */ Param->Flags &= ~SC_DEFTYPE; } else { @@ -2042,7 +2015,7 @@ static void ParseAnsiParamList (FuncDesc* F) ParseAttribute (&Decl); /* Create a symbol table entry */ - Param = AddLocalSym (Decl.Ident, ParamTypeCvt (Decl.Type), Decl.StorageClass, 0); + Param = AddLocalSym (Decl.Ident, PtrConversion (Decl.Type), Decl.StorageClass, 0); /* Add attributes if we have any */ SymUseAttr (Param, &Decl); From a887b29ffb8b138dba83b00aff4b5ab4d2288e19 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Tue, 5 Mar 2024 07:04:59 +0100 Subject: [PATCH 172/707] Revert "Test strtok()." This reverts commit 3a7bd539568e25f33c64a88fd6e76a9e015c74f2. --- test/ref/strtok.c | 43 ------------------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 test/ref/strtok.c diff --git a/test/ref/strtok.c b/test/ref/strtok.c deleted file mode 100644 index 15c3a289d..000000000 --- a/test/ref/strtok.c +++ /dev/null @@ -1,43 +0,0 @@ -// 2024-02-14 Sven Michael Klose - -#include -#include -#include - -void -error (void) -{ - printf ("strtok() test failed!\n"); - exit (-1); -} - -void -test (char * s) -{ - if (strcmp ("test", strtok (s, "/"))) - error (); - if (strcmp ("foo", strtok (NULL, "/"))) - error (); - if (strcmp ("bar", strtok (NULL, "/"))) - error (); - if (strtok (NULL, "/")) - error (); - if (strtok (NULL, "/")) - error (); -} - -int -main (void) -{ - char s1[] = "test/foo/bar"; - char s2[] = "/test/foo/bar"; - char s3[] = "//test/foo/bar"; - char s4[] = "//test/foo/bar//"; - - test (s1); - test (s2); - test (s3); - test (s4); - - return 0; -} From b993d88339d509b8d6a5a13a6bd313e7e42a624a Mon Sep 17 00:00:00 2001 From: mrdudz Date: Sun, 17 Mar 2024 17:19:42 +0100 Subject: [PATCH 173/707] second half of #2420 - don't use the loop macro. Fixes -j13 for me --- test/asm/Makefile | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/test/asm/Makefile b/test/asm/Makefile index dea53f6b2..5b3bff3f8 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -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)) From 82165c1a7767043aa9cca856aaa57e7686a77975 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Mon, 18 Mar 2024 18:40:45 +0100 Subject: [PATCH 174/707] Implement strcasestr --- include/string.h | 1 + libsrc/common/strcasestr.c | 36 +++++++++++++++++++++++++++++++++ test/val/strstr-test.c | 41 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 libsrc/common/strcasestr.c create mode 100644 test/val/strstr-test.c diff --git a/include/string.h b/include/string.h index abaf80e7d..b19f44e31 100644 --- a/include/string.h +++ b/include/string.h @@ -81,6 +81,7 @@ void __fastcall__ bzero (void* ptr, size_t n); /* BSD */ char* __fastcall__ strdup (const char* s); /* SYSV/BSD */ int __fastcall__ stricmp (const char* s1, const char* s2); /* DOS/Windows */ int __fastcall__ strcasecmp (const char* s1, const char* s2); /* Same for Unix */ +char* __fastcall__ strcasestr (const char* str, const char* substr); int __fastcall__ strnicmp (const char* s1, const char* s2, size_t count); /* DOS/Windows */ int __fastcall__ strncasecmp (const char* s1, const char* s2, size_t count); /* Same for Unix */ size_t __fastcall__ strnlen (const char* s, size_t maxlen); /* POSIX.1-2008 */ diff --git a/libsrc/common/strcasestr.c b/libsrc/common/strcasestr.c new file mode 100644 index 000000000..693b43a37 --- /dev/null +++ b/libsrc/common/strcasestr.c @@ -0,0 +1,36 @@ +/* +** strcasestr.c +** +** Colin Leroy-Mira, 2024 +*/ + + + +#include +#include +#include + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +char* __fastcall__ strcasestr(const char *str, const char *substr) { + size_t len_a = strlen(str); + size_t len_b = strlen(substr); + const char *end_str; + + if (len_a < len_b) + return NULL; + + len_a -= len_b; + + for (end_str = str + len_a + 1; str < end_str; str++) { + if (!strncasecmp(str, substr, len_b)) + return (char *)str; + } + return NULL; +} diff --git a/test/val/strstr-test.c b/test/val/strstr-test.c new file mode 100644 index 000000000..5c8a147b0 --- /dev/null +++ b/test/val/strstr-test.c @@ -0,0 +1,41 @@ +#include +#include +#include + +int fails = 0; + +#define STRSTR_TEST(needle,expected) \ + if (strstr(haystack, (needle)) != (expected)) { \ + printf("strstr failure: expected %p for \"%s\", " \ + "got %p\n", \ + expected, needle, strstr(haystack, (needle)));\ + fails++; \ + } + +#define STRCASESTR_TEST(needle,expected) \ + if (strcasestr(haystack, (needle)) != (expected)) { \ + printf("strcasestr failure: expected %p for \"%s\", " \ + "got %p\n", \ + expected, needle, strcasestr(haystack, (needle)));\ + fails++; \ + } + +int main (void) +{ + const char *haystack = "This is a string to search in"; + + STRSTR_TEST("This is", haystack + 0); + STRSTR_TEST("a string", haystack + 8); + STRSTR_TEST("This is a string to search in", haystack); + STRSTR_TEST("search in", haystack + 20); + STRSTR_TEST("This is a string to search in with extra chars", NULL); + STRSTR_TEST("nowhere", NULL); + + STRCASESTR_TEST("this is", haystack + 0); + STRCASESTR_TEST("a STRING", haystack + 8); + STRCASESTR_TEST("this is a string TO search in", haystack); + STRCASESTR_TEST("This is a string to search in with extra chars", NULL); + STRCASESTR_TEST("search IN", haystack + 20); + + return fails; +} From b5d259bafb1b3bcf4eb2c1ddc92d14b3c891fd49 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Mon, 18 Mar 2024 19:52:04 +0100 Subject: [PATCH 175/707] Implement strcasestr as part of strstr --- libsrc/common/strcasestr.c | 36 -------------------------- libsrc/common/strstr.s | 53 +++++++++++++++++++++++++------------- libsrc/common/tolower.s | 6 ++--- 3 files changed, 38 insertions(+), 57 deletions(-) delete mode 100644 libsrc/common/strcasestr.c diff --git a/libsrc/common/strcasestr.c b/libsrc/common/strcasestr.c deleted file mode 100644 index 693b43a37..000000000 --- a/libsrc/common/strcasestr.c +++ /dev/null @@ -1,36 +0,0 @@ -/* -** strcasestr.c -** -** Colin Leroy-Mira, 2024 -*/ - - - -#include -#include -#include - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -char* __fastcall__ strcasestr(const char *str, const char *substr) { - size_t len_a = strlen(str); - size_t len_b = strlen(substr); - const char *end_str; - - if (len_a < len_b) - return NULL; - - len_a -= len_b; - - for (end_str = str + len_a + 1; str < end_str; str++) { - if (!strncasecmp(str, substr, len_b)) - return (char *)str; - } - return NULL; -} diff --git a/libsrc/common/strstr.s b/libsrc/common/strstr.s index 84f633245..9cc9c0d33 100644 --- a/libsrc/common/strstr.s +++ b/libsrc/common/strstr.s @@ -4,11 +4,18 @@ ; char* strstr (const char* haystack, const char* needle); ; - .export _strstr - .import popptr1 - .importzp ptr1, ptr2, ptr3, ptr4, tmp1 + .export _strstr, _strcasestr + .import popptr1, _tolower + .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3 _strstr: + ldy #$01 + bne :+ +_strcasestr: + ldy #$00 +: + sty tmp2 ; Set case sensitivity + sta ptr2 ; Save needle stx ptr2+1 sta ptr4 ; Setup temp copy for later @@ -24,10 +31,19 @@ _strstr: ; Search for the beginning of the string (this is not an optimal search ; strategy [in fact, it's pretty dumb], but it's simple to implement). - sta tmp1 ; Save start of needle + ldx tmp2 ; Lowercase if needed + bne :+ + jsr _tolower + +: sta tmp1 ; Save start of needle @L1: lda (ptr1),y ; Get next char from haystack beq @NotFound ; Jump if end - cmp tmp1 ; Start of needle found? + + ldx tmp2 ; Lowercase if needed + bne :+ + jsr _tolower + +: cmp tmp1 ; Start of needle found? beq @L2 ; Jump if so iny ; Next char bne @L1 @@ -43,7 +59,7 @@ _strstr: bcc @L3 inc ptr1+1 -; ptr1 points to the start of needle now. Setup temporary pointers for the +; ptr1 points to the start of needle in haystack now. Setup temporary pointers for the ; search. The low byte of ptr4 is already set. @L3: sta ptr3 @@ -57,7 +73,19 @@ _strstr: @L4: lda (ptr4),y ; Get char from needle beq @Found ; Jump if end of needle (-> found) - cmp (ptr3),y ; Compare with haystack + + ldx tmp2 ; Lowercase if needed + bne :+ + jsr _tolower +: sta tmp3 + + lda (ptr3),y ; Compare with haystack + + ldx tmp2 ; Lowercase if needed + bne :+ + jsr _tolower + +: cmp tmp3 bne @L5 ; Jump if not equal iny ; Next char bne @L4 @@ -82,14 +110,3 @@ _strstr: lda #$00 ; return NULL tax rts - - - - - - - - - - - diff --git a/libsrc/common/tolower.s b/libsrc/common/tolower.s index 828be1cb1..22b030da3 100644 --- a/libsrc/common/tolower.s +++ b/libsrc/common/tolower.s @@ -17,12 +17,12 @@ _tolower: cpx #$00 ; out of range? bne @L2 ; if so, return the argument unchanged - tay ; save char + pha ; save char jsr ctypemaskdirect ; get character classification and #CT_UPPER ; upper case char? beq @L1 ; jump if no - tya ; restore char + pla ; restore char adc #<('a'-'A') ; make lower case char (ctypemaskdirect ensures carry clear) rts -@L1: tya ; restore char +@L1: pla ; restore char @L2: rts From 0c681b42ef96c53c429962a47011673e4f6ed88b Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Tue, 19 Mar 2024 18:07:17 +0100 Subject: [PATCH 176/707] Factorize to save 20 bytes --- libsrc/common/strstr.s | 45 ++++++++++++++++------------------------- libsrc/common/tolower.s | 7 ++++--- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/libsrc/common/strstr.s b/libsrc/common/strstr.s index 9cc9c0d33..d24f1b0c9 100644 --- a/libsrc/common/strstr.s +++ b/libsrc/common/strstr.s @@ -5,16 +5,18 @@ ; .export _strstr, _strcasestr - .import popptr1, _tolower - .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3 + .import popptr1, return0, tolower_a + .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2 + +maybe_lower: ; Lowercase char in A if needed + jmp tolower_a ; patched on entry with either JMP or RTS _strstr: - ldy #$01 + ldy #$60 ; RTS bne :+ _strcasestr: - ldy #$00 -: - sty tmp2 ; Set case sensitivity + ldy #$4C ; JMP absolute +: sty maybe_lower sta ptr2 ; Save needle stx ptr2+1 @@ -31,19 +33,13 @@ _strcasestr: ; Search for the beginning of the string (this is not an optimal search ; strategy [in fact, it's pretty dumb], but it's simple to implement). - ldx tmp2 ; Lowercase if needed - bne :+ - jsr _tolower - -: sta tmp1 ; Save start of needle + jsr maybe_lower ; Lowercase if needed + sta tmp1 ; Save start of needle @L1: lda (ptr1),y ; Get next char from haystack beq @NotFound ; Jump if end - ldx tmp2 ; Lowercase if needed - bne :+ - jsr _tolower - -: cmp tmp1 ; Start of needle found? + jsr maybe_lower ; Lowercase if needed + cmp tmp1 ; Start of needle found? beq @L2 ; Jump if so iny ; Next char bne @L1 @@ -74,18 +70,13 @@ _strcasestr: @L4: lda (ptr4),y ; Get char from needle beq @Found ; Jump if end of needle (-> found) - ldx tmp2 ; Lowercase if needed - bne :+ - jsr _tolower -: sta tmp3 + jsr maybe_lower ; Lowercase if needed + sta tmp2 lda (ptr3),y ; Compare with haystack - ldx tmp2 ; Lowercase if needed - bne :+ - jsr _tolower - -: cmp tmp3 + jsr maybe_lower ; Lowercase if needed + cmp tmp2 bne @L5 ; Jump if not equal iny ; Next char bne @L4 @@ -107,6 +98,4 @@ _strcasestr: ; We reached end of haystack without finding needle @NotFound: - lda #$00 ; return NULL - tax - rts + jmp return0 ; return NULL diff --git a/libsrc/common/tolower.s b/libsrc/common/tolower.s index 22b030da3..4d02e4dfb 100644 --- a/libsrc/common/tolower.s +++ b/libsrc/common/tolower.s @@ -10,13 +10,14 @@ ; int tolower (int c); ; - .export _tolower + .export _tolower, tolower_a .include "ctype.inc" .import ctypemaskdirect _tolower: cpx #$00 ; out of range? - bne @L2 ; if so, return the argument unchanged + bne out ; if so, return the argument unchanged +tolower_a: pha ; save char jsr ctypemaskdirect ; get character classification and #CT_UPPER ; upper case char? @@ -25,4 +26,4 @@ _tolower: adc #<('a'-'A') ; make lower case char (ctypemaskdirect ensures carry clear) rts @L1: pla ; restore char -@L2: rts +out: rts From 71d82ab5d9eb0adf3719955904549ff4ec547a75 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Fri, 22 Mar 2024 17:19:26 +0100 Subject: [PATCH 177/707] Use common naming scheme for tolowerdirect --- libsrc/common/strstr.s | 4 ++-- libsrc/common/tolower.s | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libsrc/common/strstr.s b/libsrc/common/strstr.s index d24f1b0c9..6ab46148c 100644 --- a/libsrc/common/strstr.s +++ b/libsrc/common/strstr.s @@ -5,11 +5,11 @@ ; .export _strstr, _strcasestr - .import popptr1, return0, tolower_a + .import popptr1, return0, tolowerdirect .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2 maybe_lower: ; Lowercase char in A if needed - jmp tolower_a ; patched on entry with either JMP or RTS + jmp tolowerdirect ; patched on entry with either JMP or RTS _strstr: ldy #$60 ; RTS diff --git a/libsrc/common/tolower.s b/libsrc/common/tolower.s index 4d02e4dfb..9c143f1ce 100644 --- a/libsrc/common/tolower.s +++ b/libsrc/common/tolower.s @@ -10,14 +10,14 @@ ; int tolower (int c); ; - .export _tolower, tolower_a + .export _tolower, tolowerdirect .include "ctype.inc" .import ctypemaskdirect _tolower: cpx #$00 ; out of range? bne out ; if so, return the argument unchanged -tolower_a: +tolowerdirect: pha ; save char jsr ctypemaskdirect ; get character classification and #CT_UPPER ; upper case char? From 79585194e655f142e603bd397f86a9aceded5eb0 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Thu, 28 Mar 2024 16:33:20 -0400 Subject: [PATCH 178/707] provide simple examples for using sim65 with C and assembly code --- doc/sim65.sgml | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index c2740bbad..e4b6762d4 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -124,11 +124,28 @@ Exit codes are limited to 8 bits. The standard C library high level file input and output is functional. A sim65 application can be written like a command line application, -providing arguments to ). +Example: + + +#include +int main() +{ + printf("Hello!\n"); + return 5; +} + +// Build and run: +// cc65 -o example.s example.c +// ca65 -o example.o example.s +// ld65 -t sim6502 -o example.prg example.o sim6502.lib +// sim65 example.prg + Creating a Test in Assembly

@@ -141,11 +158,25 @@ and the sim65 library provides two ways to return an 8-bit exit code: Return from -The binary file has a 12 byte header: +Example: + + +.export _main +_main: + lda #5 + rts + +; Build and run: +; ca65 -o example.o example.s +; ld65 -t sim6502 -o example.prg example.o sim6502.lib +; sim65 example.prg + + +Internally, the binary program file has a 12 byte header provided by the library: @@ -182,6 +213,9 @@ These use cc65 calling conventions, and are intended for use with the sim65 targ The sim6502 or sim65c02 targets provide a default configuration, +but if customization is needed, From 89b709c7f87da4594d93f9a45c1a95b0b72b15bc Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Thu, 28 Mar 2024 16:55:55 -0400 Subject: [PATCH 179/707] make it clearer that explicit lib is required, note that exit is from stdlib.h, exit codes are unsigned, tweak "see below" for spacing, clarify that assembly can be used with C tests as well --- doc/sim65.sgml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index e4b6762d4..c70e06412 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -115,12 +115,12 @@ PVExit ($01) Creating a Test in C

-For a C test compiled and linked with ). +a set of built-in paravirtualization functions (see ). Example: @@ -149,9 +149,11 @@ int main() Creating a Test in Assembly

-Assembly tests may similarly be assembled and linked with - @@ -213,8 +215,8 @@ These use cc65 calling conventions, and are intended for use with the sim65 targ The sim6502 or sim65c02 targets provide a default configuration, -but if customization is needed, The From 074ec82126c16a14da2579c6994eec9b7417e119 Mon Sep 17 00:00:00 2001 From: Olli Savia Date: Tue, 2 Apr 2024 19:25:15 +0300 Subject: [PATCH 180/707] Added missing EXEHDR --- cfg/vic20-asm-32k.cfg | 1 + cfg/vic20-asm-3k.cfg | 1 + cfg/vic20-asm.cfg | 1 + 3 files changed, 3 insertions(+) diff --git a/cfg/vic20-asm-32k.cfg b/cfg/vic20-asm-32k.cfg index 622cfb26f..3d0341e71 100644 --- a/cfg/vic20-asm-32k.cfg +++ b/cfg/vic20-asm-32k.cfg @@ -14,6 +14,7 @@ MEMORY { SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; + EXEHDR: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; diff --git a/cfg/vic20-asm-3k.cfg b/cfg/vic20-asm-3k.cfg index 1afaf0b30..6ef06957e 100644 --- a/cfg/vic20-asm-3k.cfg +++ b/cfg/vic20-asm-3k.cfg @@ -14,6 +14,7 @@ MEMORY { SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; + EXEHDR: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; diff --git a/cfg/vic20-asm.cfg b/cfg/vic20-asm.cfg index 5f6c7cc74..531d3f010 100644 --- a/cfg/vic20-asm.cfg +++ b/cfg/vic20-asm.cfg @@ -14,6 +14,7 @@ MEMORY { SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; + EXEHDR: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; From c500cb90860fa0e7a8280cf834ab88d4f375a470 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky Date: Sat, 3 Jun 2023 16:33:18 +0300 Subject: [PATCH 181/707] Add support of unnamed labels with @ (.localchar) prefix. --- src/ca65/main.c | 18 ++++++++++++++++++ src/ca65/scanner.c | 44 ++++++++++++++++++++++++++++++++++---------- src/ca65/token.h | 2 +- src/ca65/ulabel.c | 8 ++++++-- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index 3ec6c84ee..f3100162a 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -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. */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 185100025..146c74958 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -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 (); diff --git a/src/ca65/token.h b/src/ca65/token.h index b8bbb6d6e..8f935f7a1 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -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, /* <> */ diff --git a/src/ca65/ulabel.c b/src/ca65/ulabel.c index 1127c3743..19bec0671 100644 --- a/src/ca65/ulabel.c +++ b/src/ca65/ulabel.c @@ -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) { From 270f3544b53f7ec54ed5556ec90cbf50e6611b28 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky Date: Sat, 23 Sep 2023 19:59:28 +0300 Subject: [PATCH 182/707] Document changes in unnamed labels. --- doc/ca65.sgml | 55 ++++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index c5c6893da..2e63e0961 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -829,49 +829,42 @@ names like "Loop". Here is an example: bne @Loop ; ERROR: Unknown identifier! + Unnamed labels

-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 @: (.LOCALCHAR is respected if it +is set) or sole :. -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 @ (.LOCALCHAR is respected +if it is set) or : with several - or + characters. +The - characters will create a back reference (n'th label backwards), +the + will create a forward reference (n'th label in forward direction). +As an alternative, angle brackets < and > may be used +instead of - and + with the same meaning. + +Example: - : 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 -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. organize named symbols, not unnamed ones, so scopes don't have an effect on unnamed labels. - Using macros to define labels and constants

While there are drawbacks with this approach, it may be handy in a few rare From f789316f862a59250f134015934a16dec5cd74c5 Mon Sep 17 00:00:00 2001 From: Evgeny Vrublevsky Date: Sun, 7 Apr 2024 12:59:38 +0300 Subject: [PATCH 183/707] Add a test for the unnamed labels. --- test/asm/listing/060-ulabel.s | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/asm/listing/060-ulabel.s diff --git a/test/asm/listing/060-ulabel.s b/test/asm/listing/060-ulabel.s new file mode 100644 index 000000000..f2e66da87 --- /dev/null +++ b/test/asm/listing/060-ulabel.s @@ -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 From fa1a426c2968f1429e7129ea592065c2a57b73ce Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Tue, 16 Apr 2024 14:06:45 -0400 Subject: [PATCH 184/707] add -t sim6502 to cc65 and ca65 examples --- doc/sim65.sgml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index c70e06412..ebd73c2cc 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -141,8 +141,8 @@ int main() } // Build and run: -// cc65 -o example.s example.c -// ca65 -o example.o example.s +// cc65 -t sim6502 -o example.s example.c +// ca65 -t sim6502 -o example.o example.s // ld65 -t sim6502 -o example.prg example.o sim6502.lib // sim65 example.prg @@ -173,7 +173,7 @@ _main: rts ; Build and run: -; ca65 -o example.o example.s +; ca65 -t sim6502 -o example.o example.s ; ld65 -t sim6502 -o example.prg example.o sim6502.lib ; sim65 example.prg From 4bc726ebe2d8148b132170a292291e811c5e4d2a Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Tue, 16 Apr 2024 16:41:00 -0400 Subject: [PATCH 185/707] clarify the meaning of the exit code unsigned limitation --- doc/sim65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index ebd73c2cc..5cacf87cd 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -120,7 +120,7 @@ command line arguments to Date: Tue, 16 Apr 2024 16:56:13 -0400 Subject: [PATCH 186/707] give cl65 alternative --- doc/sim65.sgml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 5cacf87cd..962f07254 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -141,6 +141,10 @@ int main() } // Build and run: +// cl65 -t sim6502 -o example.prg example.c +// sim65 example.prg + +// Build and run, separate steps: // cc65 -t sim6502 -o example.s example.c // ca65 -t sim6502 -o example.o example.s // ld65 -t sim6502 -o example.prg example.o sim6502.lib @@ -173,6 +177,10 @@ _main: rts ; Build and run: +; cl65 -t sim6502 -o example.prg example.s +; sim65 example.prg + +; Build and run, separate steps: ; ca65 -t sim6502 -o example.o example.s ; ld65 -t sim6502 -o example.prg example.o sim6502.lib ; sim65 example.prg From a823d900823056c2109c4de362c6cbcfcc512b7d Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Fri, 19 Apr 2024 07:57:47 +0200 Subject: [PATCH 187/707] Separated versions --- libsrc/common/strcasestr.s | 95 ++++++++++++++++++++++++++++++++++++++ libsrc/common/strstr.s | 33 ++++--------- 2 files changed, 103 insertions(+), 25 deletions(-) create mode 100644 libsrc/common/strcasestr.s diff --git a/libsrc/common/strcasestr.s b/libsrc/common/strcasestr.s new file mode 100644 index 000000000..58364f419 --- /dev/null +++ b/libsrc/common/strcasestr.s @@ -0,0 +1,95 @@ +; +; Ullrich von Bassewitz, 11.12.1998 +; +; char* strcasestr (const char* haystack, const char* needle); +; + + .export _strcasestr + .import popptr1, return0, tolowerdirect + .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4 + .include "ctype.inc" + + .segment "LOWCODE" + +_strcasestr: + sta ptr2 ; Save needle + stx ptr2+1 + sta ptr4 ; Setup temp copy for later + + jsr popptr1 ; Get haystack to ptr1 + +; If needle is empty, return haystack + + ; ldy #$00 Y=0 guaranteed by popptr1 + lda (ptr2),y ; Get first byte of needle + beq @Found ; Needle is empty --> we're done + +; Search for the beginning of the string (this is not an optimal search +; strategy [in fact, it's pretty dumb], but it's simple to implement). + + jsr tolowerdirect ; Lowercase + sta tmp1 ; Save start of needle +@L1: lda (ptr1),y ; Get next char from haystack + beq @NotFound ; Jump if end + + jsr tolowerdirect ; Lowercase + cmp tmp1 ; Start of needle found? + beq @L2 ; Jump if so + iny ; Next char + bne @L1 + inc ptr1+1 ; Bump high byte + bne @L1 ; Branch always + +; We found the start of needle in haystack + +@L2: tya ; Get offset + clc + adc ptr1 + sta ptr1 ; Make ptr1 point to start + bcc @L3 + inc ptr1+1 + +; ptr1 points to the start of needle in haystack now. Setup temporary pointers for the +; search. The low byte of ptr4 is already set. + +@L3: sta ptr3 + lda ptr1+1 + sta ptr3+1 + lda ptr2+1 + sta ptr4+1 + ldy #1 ; First char is identical, so start on second + +; Do the compare + +@L4: lda (ptr4),y ; Get char from needle + beq @Found ; Jump if end of needle (-> found) + + jsr tolowerdirect ; Lowercase + sta tmp2 + + lda (ptr3),y ; Compare with haystack + + jsr tolowerdirect ; Lowercase + cmp tmp2 + bne @L5 ; Jump if not equal + iny ; Next char + bne @L4 + inc ptr3+1 + inc ptr4+1 ; Bump hi byte of pointers + bne @L4 ; Next char (branch always) + +; The strings did not compare equal, search next start of needle + +@L5: ldy #1 ; Start after this char + bne @L1 ; Branch always + +; We found the start of needle + +@Found: lda ptr1 + ldx ptr1+1 + rts + +; We reached end of haystack without finding needle + +@NotFound: + jmp return0 ; return NULL diff --git a/libsrc/common/strstr.s b/libsrc/common/strstr.s index 6ab46148c..691e5ba5c 100644 --- a/libsrc/common/strstr.s +++ b/libsrc/common/strstr.s @@ -4,20 +4,11 @@ ; char* strstr (const char* haystack, const char* needle); ; - .export _strstr, _strcasestr - .import popptr1, return0, tolowerdirect - .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2 - -maybe_lower: ; Lowercase char in A if needed - jmp tolowerdirect ; patched on entry with either JMP or RTS + .export _strstr + .import popptr1 + .importzp ptr1, ptr2, ptr3, ptr4, tmp1 _strstr: - ldy #$60 ; RTS - bne :+ -_strcasestr: - ldy #$4C ; JMP absolute -: sty maybe_lower - sta ptr2 ; Save needle stx ptr2+1 sta ptr4 ; Setup temp copy for later @@ -33,12 +24,9 @@ _strcasestr: ; Search for the beginning of the string (this is not an optimal search ; strategy [in fact, it's pretty dumb], but it's simple to implement). - jsr maybe_lower ; Lowercase if needed sta tmp1 ; Save start of needle @L1: lda (ptr1),y ; Get next char from haystack beq @NotFound ; Jump if end - - jsr maybe_lower ; Lowercase if needed cmp tmp1 ; Start of needle found? beq @L2 ; Jump if so iny ; Next char @@ -55,7 +43,7 @@ _strcasestr: bcc @L3 inc ptr1+1 -; ptr1 points to the start of needle in haystack now. Setup temporary pointers for the +; ptr1 points to the start of needle now. Setup temporary pointers for the ; search. The low byte of ptr4 is already set. @L3: sta ptr3 @@ -69,14 +57,7 @@ _strcasestr: @L4: lda (ptr4),y ; Get char from needle beq @Found ; Jump if end of needle (-> found) - - jsr maybe_lower ; Lowercase if needed - sta tmp2 - - lda (ptr3),y ; Compare with haystack - - jsr maybe_lower ; Lowercase if needed - cmp tmp2 + cmp (ptr3),y ; Compare with haystack bne @L5 ; Jump if not equal iny ; Next char bne @L4 @@ -98,4 +79,6 @@ _strcasestr: ; We reached end of haystack without finding needle @NotFound: - jmp return0 ; return NULL + lda #$00 ; return NULL + tax + rts From 793aa48a4943752e4a24731f652ca0ee1b485b81 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Fri, 19 Apr 2024 08:13:41 +0200 Subject: [PATCH 188/707] Add doc --- doc/funcref.sgml | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 81c63a38b..a0a6d7ca8 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -780,6 +780,7 @@ communication, see also testcode/lib/ser-test.c. + @@ -7899,22 +7900,47 @@ be used in presence of a prototype. -strstr

+strcasestr

-/ - The function is only available as fastcall function, so it may only be used in presence of a prototype. , +, + + + + + +strstr

+ + + +/ + +The function is only available as fastcall function, so it may only +be used in presence of a prototype. + +, , Date: Thu, 16 May 2024 18:57:08 +0200 Subject: [PATCH 189/707] fix race condition as proposed in #2420 --- test/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index 22e425c9c..fbdf8c5d1 100644 --- a/test/Makefile +++ b/test/Makefile @@ -14,7 +14,9 @@ WORKDIR = ../testwrk .PHONY: test continue mostlyclean clean -test: mostlyclean continue +test: + @$(MAKE) mostlyclean + @$(MAKE) continue continue: @$(MAKE) -C asm all From 2c4d4d331479454b63e7164afe93e609c5d5ef42 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Thu, 16 May 2024 18:57:29 +0200 Subject: [PATCH 190/707] add -j2 to make test invocations --- .github/workflows/build-on-pull-request.yml | 4 ++-- .github/workflows/snapshot-on-push-master.yml | 2 +- .github/workflows/windows-test-scheduled.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 146964a30..7b762844b 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -35,7 +35,7 @@ jobs: run: make -j2 lib QUIET=1 - name: Run the regression tests. shell: bash - run: make test QUIET=1 + run: make -j2 test QUIET=1 - name: Test that the samples can be built. run: make -C samples platforms - name: Test that the targettest programs can be built. @@ -89,4 +89,4 @@ jobs: - name: Run the regression tests (make test) shell: cmd - run: make test QUIET=1 SHELL=cmd + run: make -j2 test QUIET=1 SHELL=cmd diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index d58bff8ed..42794f10b 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -59,7 +59,7 @@ jobs: run: make -j2 lib QUIET=1 - name: Run the regression tests. shell: bash - run: make test QUIET=1 + run: make -j2 test QUIET=1 - name: Test that the samples can be built. shell: bash run: make -j2 samples diff --git a/.github/workflows/windows-test-scheduled.yml b/.github/workflows/windows-test-scheduled.yml index f72254273..fa22473f4 100644 --- a/.github/workflows/windows-test-scheduled.yml +++ b/.github/workflows/windows-test-scheduled.yml @@ -70,7 +70,7 @@ jobs: - name: Run the regression tests (make test) if: steps.check-sha.outputs.cache-hit != 'true' shell: cmd - run: make test QUIET=1 SHELL=cmd + run: make -j2 test QUIET=1 SHELL=cmd - name: Test that the samples can be built (make samples) if: steps.check-sha.outputs.cache-hit != 'true' From 3ea0ded65d59717d7f7e1454bacbd53baac505de Mon Sep 17 00:00:00 2001 From: xlar54 Date: Wed, 12 Jun 2024 16:23:30 -0500 Subject: [PATCH 191/707] initial --- libsrc/cx16/tgi/cx640p1.s | 664 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 664 insertions(+) create mode 100644 libsrc/cx16/tgi/cx640p1.s diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s new file mode 100644 index 000000000..1fcceecf8 --- /dev/null +++ b/libsrc/cx16/tgi/cx640p1.s @@ -0,0 +1,664 @@ +; +; Graphics driver for the 640 pixels across, 480 pixels down, 2 color mode +; on the Commander X16 +; +; 2024-06-11, Scott Hutter +; Based on code by Greg King +; + + .include "zeropage.inc" + + .include "tgi-kernel.inc" + .include "tgi-error.inc" + + .include "cbm_kernal.inc" + .include "cx16.inc" + + .macpack generic + .macpack module + + +; Macro that copies a word into a pseudo-register + +.mac setReg reg, src + lda src + ldx src+1 + sta gREG::reg + stx gREG::reg+1 +.endmac + + +; ------------------------------------------------------------------------ +; Header. Includes jump table and constants. + + module_header _cx640p1_tgi ; 640 pixels across, 1 pixel per byte + +; First part of the header is a structure that has a signature, +; and defines the capabilities of the driver. + + .byte $74, $67, $69 ; ASCII "tgi" + .byte TGI_API_VERSION ; TGI API version number + .addr $0000 ; Library reference + .word 640 ; X resolution + .word 480 ; Y resolution + .byte 2 ; Number of drawing colors + .byte 0 ; Number of screens available + .byte 8 ; System font X size + .byte 8 ; System font Y size + .word $0100 ; Aspect ratio (based on VGA display) + .byte 0 ; TGI driver flags + +; Next, comes the jump table. Currently, 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 + + +; ------------------------------------------------------------------------ +; Constant + + + +; ------------------------------------------------------------------------ +; 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 + +ADDR = tmp1 ; ADDR+1,2,3 + +TEMP = tmp3 +TEMP2 = tmp4 ; HORLINE +TEMP3 = sreg ; HORLINE + +tempX: +.byte $00, $00 +tempY: +.byte $00, $00 + +ERR2: +.byte $00 +ERR: +.byte $00 +SY: +.byte $00 +SX: +.byte $00 +DY: +.byte $00 +DX: +.byte $00 +CURRENT_Y: +.byte $00, $00 +CURRENT_X: +.byte $00, $00 +; Absolute variables used in the code + +.bss + +; The colors are indicies into a TGI palette. The TGI palette is indicies into +; VERA's palette. Vera's palette is a table of Red, Green, and Blue levels. +; The first 16 RGB elements mimic the Commodore 64's colors. + +SCRBASE: .res 1 ; High byte of screen base +BITMASK: .res 1 ; $00 = clear, $FF = set pixels +OLDCOLOR: .res 1 ; colors before entering gfx mode + +defpalette: .res $0100 +palette: .res $0100 + +bcolor := palette + 0 ; Background color +color: .res 1 ; Stroke and fill index +text_mode: .res 1 ; Old text mode + +.data + +error: .byte TGI_ERR_OK ; Error code + + +; Constants and tables + +.rodata + +; Bit masks for setting pixels +bitMasks1: + .byte %10000000, %01000000, %00100000, %00010000 + .byte %00001000, %00000100, %00000010, %00000001 +bitMasks2: + .byte %01111111, %10111111, %11011111, %11101111 + .byte %11110111, %11111011, %11111101, %11111110 + + +.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: +; Create the default palette. + + ldx #$00 +: txa + sta defpalette,x + inx + bnz :- + + ; 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 called only once; so, any code that is needed +; to initiate variables and so on must go here. Setting the palette is not +; needed because that is called by the graphics kernel later. +; The graphics kernel never will call INIT when a graphics mode already is +; active, so there is no need to protect against that. +; +; Must set an error code: YES + +INIT: stz error ; #TGI_ERR_OK + +; Save the current text mode. + + sec + jsr SCREEN_MODE + sta text_mode + +; Switch into (640 x 480 x 2) graphics mode. + + lda #%00000000 ; DCSEL = 0, VRAM port 1 + sta VERA::CTRL + lda #%00100001 ; Disable sprites, layer 1 enable, VGA + sta VERA::DISP::VIDEO + lda #%00000100 ; Bitmap mode enable + sta VERA::L1::CONFIG + lda #%00000001 ; Tile width 640 + sta VERA::L1::TILE_BASE + rts + +; ------------------------------------------------------------------------ +; DONE: Will be called to switch the graphics device back into text mode. +; The graphics kernel never will call DONE when no graphics mode is active, +; so there is no need to protect against that. +; +; Must set an error code: NO + +DONE: + jsr CINT + lda text_mode + clc + jmp SCREEN_MODE + +; ------------------------------------------------------------------------ +; GETERROR: Return the error code in .A, and clear it. + +GETERROR: + lda error + stz error + rts + +; ------------------------------------------------------------------------ +; CONTROL: Platform-/driver-specific entry point. +; +; Must set an error code: YES + +CONTROL: + lda #TGI_ERR_INV_FUNC + sta error + rts + +; ------------------------------------------------------------------------ +; CLEAR: Clear the screen. +; +; Must set an error code: NO + +CLEAR : + .scope inner + + ; set up DCSEL=2 + lda #(2 << 1) + sta VERA::CTRL + + ; set cache writes + lda #$40 + tsb $9f29 ;VERA_FX_CTRL + + ; set FX cache to all zeroes + lda #(6 << 1) + sta VERA::CTRL + + lda #$00 ; color + ; $00=black, $01=white + beq ahead + lda #$ff +ahead: + sta VERA::DISP::VIDEO + sta VERA::DISP::HSCALE ;$9f2a + sta VERA::DISP::VSCALE ;$9f2b + sta VERA::DISP::FRAME ;$9f2c + + stz VERA::CTRL + ; set address and increment for bitmap area + stz VERA::ADDR + stz VERA::ADDR + 1 + lda #$30 ; increment +4 + sta VERA::ADDR + 2 + + ldy #240 ; number of rows +blank_outer: + ldx #10 ; 10 iterations of 32 = one line of 320 at 8bpp +blank_loop: + + .repeat 8 + stz VERA::DATA0 ; $9f23 each `stz` writes four zeroes to VRAM (cache contents) for a total of 32 pixels when repeated 8x + .endrep + + dex + bne blank_loop + dey + bne blank_outer + + ; set up DCSEL=2 + lda #(2 << 1) + sta VERA::CTRL ; $9f25 + + ; set FX off (cache write bit 1 -> 0) + stz $9f29 ;VERA_FX_CTRL + stz VERA::CTRL + + .endscope + rts + + +; ------------------------------------------------------------------------ +; SETVIEWPAGE: Set the visible page. Called with the new page in .A (0..n-1). +; The page number already is checked to be valid by the graphics kernel. +; +; Must set an error code: NO (will be called only if page OK) + +SETVIEWPAGE: + + ; Fall through. + +; ------------------------------------------------------------------------ +; SETDRAWPAGE: Set the drawable page. Called with the new page in .A (0..n-1). +; The page number already is checked to be valid by the graphics kernel. +; +; Must set an error code: NO (will be called only if page OK) + +SETDRAWPAGE: + 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: + stz error ; #TGI_ERR_OK + ldy #$00 +: lda (ptr1),y + sta palette,y + iny + bnz :- + + lda color ; Get stroke and fill index + + ; Fall through. + +; ------------------------------------------------------------------------ +; SETCOLOR: Set the drawing color (in .A). The new color already is checked +; to be in a valid range (0..maxcolor). +; +; Must set an error code: NO (will be called only if color OK) + +SETCOLOR: + tax + beq @L1 + lda #$FF +@L1: sta BITMASK + rts + +; ------------------------------------------------------------------------ +; GETPALETTE: Return the current palette in .XA. 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 + rts + +; ------------------------------------------------------------------------ +; GETDEFPALETTE: Return the default palette for the driver in .XA. 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 changable) palette. +; +; Must set an error code: NO (all drivers must have a default palette) + +GETDEFPALETTE: + lda #defpalette + rts + +; ------------------------------------------------------------------------ +; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing +; color. The co-ordinates passed to this function never are outside the +; visible screen area, so there is no need for clipping inside this function. +; +; Must set an error code: NO + +SETPIXEL: + jsr CALC + + stx TEMP + + lda ADDR + ldy ADDR+1 + ldx #$00 + + sta VERA::ADDR + sty VERA::ADDR + 1 + stx VERA::ADDR + 2 + + ldx TEMP + + lda BITMASK + beq @ahead + + ; if COLOR = 1, white is line color + ; Set the bit in the byte at VERA_DATA0 + lda VERA::DATA0 ; Load the byte at memory address + ora bitMasks1,X ; OR with the bit mask + ;lda 0 + sta VERA::DATA0 ; Store back the modified byte + rts + + @ahead: + ; if COLOR = 0, black is line color + lda VERA::DATA0 ; Load the byte at memory address + and bitMasks2,X ; OR with the bit mask + sta VERA::DATA0 ; Store back the modified byte + rts + +; ------------------------------------------------------------------------ +; GETPIXEL: Read the color value of a pixel, and return it in .XA. The +; co-ordinates passed to this function never are outside the visible screen +; area, so there is no need for clipping inside this function. + +GETPIXEL: + jsr CALC + + stx TEMP + + lda ADDR + ldy ADDR+1 + ldx #$00 + + sta VERA::ADDR + sty VERA::ADDR + 1 + stx VERA::ADDR + 2 + + ldx TEMP + lda VERA::DATA0 ; Load the byte at memory address + and bitMasks1,X + + bne @ahead + + ldx #$00 + lda #$00 + rts + + @ahead: + ldx #$00 + lda #$01 + 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 co-ordinates 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 + +BAR: + ; Initialize tempY with Y1 + LDA Y1 + STA tempY + LDA Y1+1 + STA tempY+1 + +@outer_loop: + ; Compare tempY with Y2 + LDA tempY+1 + CMP Y2+1 + BCC @outer_continue ; If tempY high byte < Y2 high byte, continue + BNE @outer_end ; If tempY high byte > Y2 high byte, end + LDA tempY + CMP Y2 + BCC @outer_continue ; If tempY low byte < Y2 low byte, continue + BEQ @outer_end ; If tempY low byte = Y2 low byte, end + +@outer_continue: + ; Initialize tempX with X1 + LDA X1 + STA tempX + LDA X1+1 + STA tempX+1 + +@inner_loop: + ; Compare tempX with X2 + LDA tempX+1 + CMP X2+1 + BCC @inner_continue ; If tempX high byte < X2 high byte, continue + BNE @inner_end ; If tempX high byte > X2 high byte, end + LDA tempX + CMP X2 + BCC @inner_continue ; If tempX low byte < X2 low byte, continue + +@inner_end: + ; Increment tempY + INC tempY + BNE @outer_loop ; If no overflow, continue outer loop + INC tempY+1 ; If overflow, increment high byte + +@inner_continue: + ; Call setpixel(tempX, tempY) + LDA X1 + PHA + LDA X1+1 + PHA + LDA Y1 + PHA + LDA Y1+1 + PHA + + LDA tempX + LDX tempX+1 + STA X1 + STX X1+1 + + LDA tempY + LDX tempY+1 + STA Y1 + STX Y1+1 + + JSR SETPIXEL + + PLA + STA Y1+1 + PLA + STA Y1 + PLA + STA X1+1 + PLA + STA X1 + + ; Increment tempX + INC tempX + BNE @inner_loop_check ; If no overflow, continue + INC tempX+1 ; If overflow, increment high byte + +@inner_loop_check: + ; Compare tempX with X2 again after increment + LDA tempX+1 + CMP X2+1 + BCC @inner_continue ; If tempX high byte < X2 high byte, continue + BNE @outer_increment ; If tempX high byte > X2 high byte, increment tempY + LDA tempX + CMP X2 + BCC @inner_continue ; If tempX low byte < X2 low byte, continue + +@outer_increment: + ; Increment tempY + INC tempY + BNE @outer_loop ; If no overflow, continue outer loop + INC tempY+1 ; If overflow, increment high byte + +@outer_end: + ; End of outer loop, continue with program + JMP @done + +@done: + ; Continue with your program + +; ------------------------------------------------------------------------ +; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y +; directions are passed in .X and .Y, the text direction is passed in .A. +; +; Must set an error code: NO + +TEXTSTYLE: + 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: + jsr Point + + ldy #$00 +@next: lda (ptr3),y + bze @end + phy + jsr GRAPH_PUT_CHAR + ply + iny + bnz @next +@end: rts + +; ------------------------------------------------------------------------ +; Point: Set the arguments for the first point of a Kernal graphics function. + +Point: setReg r0, X1 + setReg r1, Y1 + rts + + +; ------------------------------------------------------------------------ +; Calculate all variables to plot the pixel at X1/Y1. +;------------------------ +;< X1,Y1 - pixel +;> ADDR - address of card +;> X - bit number (X1 & 7) +CALC: + lda Y1+1 + sta ADDR+1 + lda Y1 + asl + rol ADDR+1 + asl + rol ADDR+1 ; Y*4 + clc + adc Y1 + sta ADDR + lda Y1+1 + adc ADDR+1 + sta ADDR+1 ; Y*4+Y=Y*5 + lda ADDR + asl + rol ADDR+1 + asl + rol ADDR+1 + asl + rol ADDR+1 + asl + rol ADDR+1 + sta ADDR ; Y*5*16=Y*80 + lda X1+1 + sta TEMP + lda X1 + lsr TEMP + ror + lsr TEMP + ror + lsr TEMP + ror + clc + adc ADDR + sta ADDR + lda ADDR+1 ; ADDR = Y*80+x/8 + adc TEMP + sta ADDR+1 + lda ADDR+1 + lda X1 + and #7 + tax + rts + + +.include "../../tgi/tgidrv_line.inc" \ No newline at end of file From 2c4aca43dfa5d44bc6f0546fd3b402773de3750e Mon Sep 17 00:00:00 2001 From: xlar54 Date: Wed, 12 Jun 2024 16:40:23 -0500 Subject: [PATCH 192/707] fixed some text alignment --- libsrc/cx16/tgi/cx640p1.s | 149 +++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 75 deletions(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 1fcceecf8..8f3777b16 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -472,105 +472,104 @@ GETPIXEL: ; Must set an error code: NO BAR: - ; Initialize tempY with Y1 - LDA Y1 - STA tempY - LDA Y1+1 - STA tempY+1 + ; Initialize tempY with Y1 + lda Y1 + sta tempY + lda Y1+1 + sta tempY+1 @outer_loop: - ; Compare tempY with Y2 - LDA tempY+1 - CMP Y2+1 - BCC @outer_continue ; If tempY high byte < Y2 high byte, continue - BNE @outer_end ; If tempY high byte > Y2 high byte, end - LDA tempY - CMP Y2 - BCC @outer_continue ; If tempY low byte < Y2 low byte, continue - BEQ @outer_end ; If tempY low byte = Y2 low byte, end + ; Compare tempY with Y2 + lda tempY+1 + cmp Y2+1 + bcc @outer_continue ; If tempY high byte < Y2 high byte, continue + bne @outer_end ; If tempY high byte > Y2 high byte, end + lda tempY + cmp Y2 + bcc @outer_continue ; If tempY low byte < Y2 low byte, continue + beq @outer_end ; If tempY low byte = Y2 low byte, end @outer_continue: - ; Initialize tempX with X1 - LDA X1 - STA tempX - LDA X1+1 - STA tempX+1 + ; Initialize tempX with X1 + lda X1 + sta tempX + lda X1+1 + sta tempX+1 @inner_loop: - ; Compare tempX with X2 - LDA tempX+1 - CMP X2+1 - BCC @inner_continue ; If tempX high byte < X2 high byte, continue - BNE @inner_end ; If tempX high byte > X2 high byte, end - LDA tempX - CMP X2 - BCC @inner_continue ; If tempX low byte < X2 low byte, continue + ; Compare tempX with X2 + lda tempX+1 + cmp X2+1 + bcc @inner_continue ; If tempX high byte < X2 high byte, continue + bne @inner_end ; If tempX high byte > X2 high byte, end + lda tempX + cmp X2 + bcc @inner_continue ; If tempX low byte < X2 low byte, continue @inner_end: - ; Increment tempY - INC tempY - BNE @outer_loop ; If no overflow, continue outer loop - INC tempY+1 ; If overflow, increment high byte + ; Increment tempY + inc tempY + bne @outer_loop ; If no overflow, continue outer loop + inc tempY+1 ; If overflow, increment high byte @inner_continue: - ; Call setpixel(tempX, tempY) - LDA X1 - PHA - LDA X1+1 - PHA - LDA Y1 - PHA - LDA Y1+1 - PHA + ; Call setpixel(tempX, tempY) + lda X1 + pha + lda X1+1 + pha + lda Y1 + pha + lda Y1+1 + pha - LDA tempX - LDX tempX+1 - STA X1 - STX X1+1 + lda tempX + ldx tempX+1 + sta X1 + stx X1+1 - LDA tempY - LDX tempY+1 - STA Y1 - STX Y1+1 + lda tempY + ldx tempY+1 + sta Y1 + stx Y1+1 - JSR SETPIXEL + jsr SETPIXEL - PLA - STA Y1+1 - PLA - STA Y1 - PLA - STA X1+1 - PLA - STA X1 + pla + sta Y1+1 + pla + sta Y1 + pla + sta X1+1 + pla + sta X1 ; Increment tempX - INC tempX - BNE @inner_loop_check ; If no overflow, continue - INC tempX+1 ; If overflow, increment high byte + inc tempX + bne @inner_loop_check ; If no overflow, continue + inc tempX+1 ; If overflow, increment high byte @inner_loop_check: - ; Compare tempX with X2 again after increment - LDA tempX+1 - CMP X2+1 - BCC @inner_continue ; If tempX high byte < X2 high byte, continue - BNE @outer_increment ; If tempX high byte > X2 high byte, increment tempY - LDA tempX - CMP X2 - BCC @inner_continue ; If tempX low byte < X2 low byte, continue + ; Compare tempX with X2 again after increment + lda tempX+1 + cmp X2+1 + bcc @inner_continue ; If tempX high byte < X2 high byte, continue + bne @outer_increment ; If tempX high byte > X2 high byte, increment tempY + lda tempX + cmp X2 + bcc @inner_continue ; If tempX low byte < X2 low byte, continue @outer_increment: - ; Increment tempY - INC tempY - BNE @outer_loop ; If no overflow, continue outer loop - INC tempY+1 ; If overflow, increment high byte + ; Increment tempY + inc tempY + bne @outer_loop ; If no overflow, continue outer loop + inc tempY+1 ; If overflow, increment high byte @outer_end: - ; End of outer loop, continue with program - JMP @done + jmp @done @done: - ; Continue with your program + rts ; ------------------------------------------------------------------------ ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y From 91cdc0d70542244a3874d5ba3e36917e130465a6 Mon Sep 17 00:00:00 2001 From: xlar54 Date: Wed, 12 Jun 2024 16:45:24 -0500 Subject: [PATCH 193/707] removed unneeded code --- libsrc/cx16/tgi/cx640p1.s | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 8f3777b16..110edba4a 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -18,20 +18,10 @@ .macpack module -; Macro that copies a word into a pseudo-register - -.mac setReg reg, src - lda src - ldx src+1 - sta gREG::reg - stx gREG::reg+1 -.endmac - - ; ------------------------------------------------------------------------ ; Header. Includes jump table and constants. - module_header _cx640p1_tgi ; 640 pixels across, 1 pixel per byte + module_header _cx640p1_tgi ; 640 pixels across, 1 pixel per bit ; First part of the header is a structure that has a signature, ; and defines the capabilities of the driver. @@ -588,23 +578,6 @@ TEXTSTYLE: ; Must set an error code: NO OUTTEXT: - jsr Point - - ldy #$00 -@next: lda (ptr3),y - bze @end - phy - jsr GRAPH_PUT_CHAR - ply - iny - bnz @next -@end: rts - -; ------------------------------------------------------------------------ -; Point: Set the arguments for the first point of a Kernal graphics function. - -Point: setReg r0, X1 - setReg r1, Y1 rts From 5976e3b85d0f8614c97090fa836661fa51f9030a Mon Sep 17 00:00:00 2001 From: Olli Savia Date: Thu, 13 Jun 2024 16:22:42 +0300 Subject: [PATCH 194/707] Add sample assembly program for Commodore machines --- samples/cbm/Makefile | 19 +++++++++++++++---- samples/cbm/hello.s | 15 +++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 samples/cbm/hello.s diff --git a/samples/cbm/Makefile b/samples/cbm/Makefile index 03387a061..71ab93a41 100644 --- a/samples/cbm/Makefile +++ b/samples/cbm/Makefile @@ -80,17 +80,19 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) C1541 ?= c1541 endif -DISK_c64 = samples.d64 +DISK_$(SYS) = samples.d64 EXELIST_c64 = \ fire \ plasma \ - nachtm + nachtm \ + hello EXELIST_c128 = \ fire \ plasma \ - nachtm + nachtm \ + hello EXELIST_cbm510 = \ fire \ @@ -110,7 +112,7 @@ EXELIST_pet = \ notavailable EXELIST_vic20 = \ - notavailable + hello ifneq ($(EXELIST_$(SYS)),) samples: $(EXELIST_$(SYS)) @@ -135,6 +137,15 @@ plasma: plasma.c $(CL) -t $(SYS) -O -o plasma -m plasma.map plasma.c nachtm: nachtm.c $(CL) -t $(SYS) -O -o nachtm -m nachtm.map nachtm.c +hello: hello.s + # Use separate assembler ... + $(AS) -t $(SYS) hello.s + # ... and linker commands ... + $(LD) -C $(SYS)-asm.cfg -o hello -m hello.map -u __EXEHDR__ hello.o $(SYS).lib + @$(DEL) hello.o 2>$(NULLDEV) + # ... or compile & link utility +# $(CL) -C $(SYS)-asm.cfg -o hello -m hello.map -u __EXEHDR__ hello.s + # -------------------------------------------------------------------------- # Rule to make a CBM disk with all samples. Needs the c1541 program that comes diff --git a/samples/cbm/hello.s b/samples/cbm/hello.s new file mode 100644 index 000000000..689dcc06b --- /dev/null +++ b/samples/cbm/hello.s @@ -0,0 +1,15 @@ +; +; Sample assembly program for Commodore machines +; + + .include "cbm_kernal.inc" + + ldx #$00 +: lda text,x + beq out + jsr CHROUT + inx + bne :- +out: rts + +text: .asciiz "hello world!" From ff5091202f3022751912762567a3838bb9c3509c Mon Sep 17 00:00:00 2001 From: xlar54 Date: Thu, 13 Jun 2024 21:00:40 -0500 Subject: [PATCH 195/707] docs --- doc/cx16.sgml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/cx16.sgml b/doc/cx16.sgml index 78a51206b..a718e52fa 100644 --- a/doc/cx16.sgml +++ b/doc/cx16.sgml @@ -243,6 +243,12 @@ point to

+ + + This driver features a resolution of 640 across and 480 down with 2 colors, + black and white. +

+ Extended memory drivers

From d24a8d7e61623089e54c1a18c1b73a0dac4eeeae Mon Sep 17 00:00:00 2001 From: xlar54 Date: Thu, 13 Jun 2024 21:09:02 -0500 Subject: [PATCH 196/707] fixed newline --- libsrc/cx16/tgi/cx640p1.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 110edba4a..4d6e267a1 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -633,4 +633,4 @@ CALC: rts -.include "../../tgi/tgidrv_line.inc" \ No newline at end of file +.include "../../tgi/tgidrv_line.inc" From b7f4c1746030c046b819231aab8cfffa072373f3 Mon Sep 17 00:00:00 2001 From: xlar54 Date: Thu, 13 Jun 2024 21:23:50 -0500 Subject: [PATCH 197/707] dangling spaces --- libsrc/cx16/tgi/cx640p1.s | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 4d6e267a1..5fc05c22e 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -2,7 +2,7 @@ ; Graphics driver for the 640 pixels across, 480 pixels down, 2 color mode ; on the Commander X16 ; -; 2024-06-11, Scott Hutter +; 2024-06-11, Scott Hutter ; Based on code by Greg King ; @@ -239,7 +239,7 @@ CONTROL: ; ; Must set an error code: NO -CLEAR : +CLEAR: .scope inner ; set up DCSEL=2 @@ -273,13 +273,13 @@ ahead: ldy #240 ; number of rows blank_outer: - ldx #10 ; 10 iterations of 32 = one line of 320 at 8bpp + ldx #10 ; 10 iterations of 32 = one line of 640 blank_loop: - .repeat 8 + .repeat 8 stz VERA::DATA0 ; $9f23 each `stz` writes four zeroes to VRAM (cache contents) for a total of 32 pixels when repeated 8x .endrep - + dex bne blank_loop dey @@ -295,7 +295,7 @@ blank_loop: .endscope rts - + ; ------------------------------------------------------------------------ ; SETVIEWPAGE: Set the visible page. Called with the new page in .A (0..n-1). From 0837f9c25f20c7bf3376dba255145a6e9cf18b46 Mon Sep 17 00:00:00 2001 From: xlar54 Date: Thu, 13 Jun 2024 21:29:37 -0500 Subject: [PATCH 198/707] spaces --- libsrc/cx16/tgi/cx640p1.s | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 5fc05c22e..4f806677c 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -394,7 +394,7 @@ SETPIXEL: stx VERA::ADDR + 2 ldx TEMP - + lda BITMASK beq @ahead @@ -402,7 +402,6 @@ SETPIXEL: ; Set the bit in the byte at VERA_DATA0 lda VERA::DATA0 ; Load the byte at memory address ora bitMasks1,X ; OR with the bit mask - ;lda 0 sta VERA::DATA0 ; Store back the modified byte rts @@ -441,7 +440,7 @@ GETPIXEL: lda #$00 rts - @ahead: + @ahead: ldx #$00 lda #$01 rts From 60f9081ea4e5bad7adac0571e61a194b557837ca Mon Sep 17 00:00:00 2001 From: xlar54 Date: Thu, 13 Jun 2024 21:40:51 -0500 Subject: [PATCH 199/707] some comment alignment --- libsrc/cx16/tgi/cx640p1.s | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 4f806677c..9af091c9b 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -113,20 +113,20 @@ CURRENT_X: ; VERA's palette. Vera's palette is a table of Red, Green, and Blue levels. ; The first 16 RGB elements mimic the Commodore 64's colors. -SCRBASE: .res 1 ; High byte of screen base -BITMASK: .res 1 ; $00 = clear, $FF = set pixels -OLDCOLOR: .res 1 ; colors before entering gfx mode +SCRBASE: .res 1 ; High byte of screen base +BITMASK: .res 1 ; $00 = clear, $FF = set pixels +OLDCOLOR: .res 1 ; colors before entering gfx mode defpalette: .res $0100 palette: .res $0100 -bcolor := palette + 0 ; Background color -color: .res 1 ; Stroke and fill index -text_mode: .res 1 ; Old text mode +bcolor := palette + 0 ; Background color +color: .res 1 ; Stroke and fill index +text_mode: .res 1 ; Old text mode .data -error: .byte TGI_ERR_OK ; Error code +error: .byte TGI_ERR_OK ; Error code ; Constants and tables @@ -193,13 +193,13 @@ INIT: stz error ; #TGI_ERR_OK ; Switch into (640 x 480 x 2) graphics mode. - lda #%00000000 ; DCSEL = 0, VRAM port 1 + lda #%00000000 ; DCSEL = 0, VRAM port 1 sta VERA::CTRL - lda #%00100001 ; Disable sprites, layer 1 enable, VGA + lda #%00100001 ; Disable sprites, layer 1 enable, VGA sta VERA::DISP::VIDEO - lda #%00000100 ; Bitmap mode enable + lda #%00000100 ; Bitmap mode enable sta VERA::L1::CONFIG - lda #%00000001 ; Tile width 640 + lda #%00000001 ; Tile width 640 sta VERA::L1::TILE_BASE rts @@ -248,7 +248,7 @@ CLEAR: ; set cache writes lda #$40 - tsb $9f29 ;VERA_FX_CTRL + tsb $9F29 ;VERA_FX_CTRL ; set FX cache to all zeroes lda #(6 << 1) @@ -260,24 +260,24 @@ CLEAR: lda #$ff ahead: sta VERA::DISP::VIDEO - sta VERA::DISP::HSCALE ;$9f2a - sta VERA::DISP::VSCALE ;$9f2b - sta VERA::DISP::FRAME ;$9f2c + sta VERA::DISP::HSCALE + sta VERA::DISP::VSCALE + sta VERA::DISP::FRAME stz VERA::CTRL ; set address and increment for bitmap area stz VERA::ADDR stz VERA::ADDR + 1 - lda #$30 ; increment +4 + lda #$30 ; increment +4 sta VERA::ADDR + 2 - ldy #240 ; number of rows + ldy #$F0 blank_outer: - ldx #10 ; 10 iterations of 32 = one line of 640 + ldx #$0A blank_loop: .repeat 8 - stz VERA::DATA0 ; $9f23 each `stz` writes four zeroes to VRAM (cache contents) for a total of 32 pixels when repeated 8x + stz VERA::DATA0 .endrep dex @@ -287,10 +287,10 @@ blank_loop: ; set up DCSEL=2 lda #(2 << 1) - sta VERA::CTRL ; $9f25 + sta VERA::CTRL ; set FX off (cache write bit 1 -> 0) - stz $9f29 ;VERA_FX_CTRL + stz $9F29 ;VERA_FX_CTRL stz VERA::CTRL .endscope From 550f94b773d8561589229d10d71f86ea3cf2c25a Mon Sep 17 00:00:00 2001 From: xlar54 Date: Thu, 13 Jun 2024 23:13:05 -0500 Subject: [PATCH 200/707] make setpalette return error --- libsrc/cx16/tgi/cx640p1.s | 64 ++++++++++++++------------------------- 1 file changed, 23 insertions(+), 41 deletions(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 9af091c9b..12b732613 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -84,27 +84,7 @@ TEMP = tmp3 TEMP2 = tmp4 ; HORLINE TEMP3 = sreg ; HORLINE -tempX: -.byte $00, $00 -tempY: -.byte $00, $00 -ERR2: -.byte $00 -ERR: -.byte $00 -SY: -.byte $00 -SX: -.byte $00 -DY: -.byte $00 -DX: -.byte $00 -CURRENT_Y: -.byte $00, $00 -CURRENT_X: -.byte $00, $00 ; Absolute variables used in the code .bss @@ -124,9 +104,20 @@ bcolor := palette + 0 ; Background color color: .res 1 ; Stroke and fill index text_mode: .res 1 ; Old text mode +tempX: .res 2 +tempY: .res 2 +ERR2: .res 1 +ERR: .res 1 +SY: .res 1 +SX: .res 1 +DY: .res 1 +DX: .res 1 +CURRENT_Y: .res 2 +CURRENT_X: .res 2 + .data -error: .byte TGI_ERR_OK ; Error code +ERROR: .byte TGI_ERR_OK ; Error code ; Constants and tables @@ -183,7 +174,7 @@ UNINSTALL: ; ; Must set an error code: YES -INIT: stz error ; #TGI_ERR_OK +INIT: stz ERROR ; #TGI_ERR_OK ; Save the current text mode. @@ -220,8 +211,8 @@ DONE: ; GETERROR: Return the error code in .A, and clear it. GETERROR: - lda error - stz error + lda ERROR + stz ERROR rts ; ------------------------------------------------------------------------ @@ -231,7 +222,7 @@ GETERROR: CONTROL: lda #TGI_ERR_INV_FUNC - sta error + sta ERROR rts ; ------------------------------------------------------------------------ @@ -254,10 +245,8 @@ CLEAR: lda #(6 << 1) sta VERA::CTRL - lda #$00 ; color - ; $00=black, $01=white - beq ahead - lda #$ff + lda #$00 + ahead: sta VERA::DISP::VIDEO sta VERA::DISP::HSCALE @@ -324,16 +313,9 @@ SETDRAWPAGE: ; Must set an error code: YES SETPALETTE: - stz error ; #TGI_ERR_OK - ldy #$00 -: lda (ptr1),y - sta palette,y - iny - bnz :- - - lda color ; Get stroke and fill index - - ; Fall through. + lda #TGI_ERR_INV_FUNC + sta ERROR + rts ; ------------------------------------------------------------------------ ; SETCOLOR: Set the drawing color (in .A). The new color already is checked @@ -398,7 +380,7 @@ SETPIXEL: lda BITMASK beq @ahead - ; if COLOR = 1, white is line color + ; if BITMASK = $00, white is line color ; Set the bit in the byte at VERA_DATA0 lda VERA::DATA0 ; Load the byte at memory address ora bitMasks1,X ; OR with the bit mask @@ -406,7 +388,7 @@ SETPIXEL: rts @ahead: - ; if COLOR = 0, black is line color + ; if BITMASK = $FF, black is line color lda VERA::DATA0 ; Load the byte at memory address and bitMasks2,X ; OR with the bit mask sta VERA::DATA0 ; Store back the modified byte From a1ca451e69ce9865c51741561662bb937717f2a6 Mon Sep 17 00:00:00 2001 From: Olli Savia Date: Sun, 16 Jun 2024 09:35:44 +0300 Subject: [PATCH 201/707] Renamed: hello.s -> hello-asm.s --- samples/cbm/Makefile | 10 +++++----- samples/cbm/{hello.s => hello-asm.s} | 0 2 files changed, 5 insertions(+), 5 deletions(-) rename samples/cbm/{hello.s => hello-asm.s} (100%) diff --git a/samples/cbm/Makefile b/samples/cbm/Makefile index 71ab93a41..fe9d349bc 100644 --- a/samples/cbm/Makefile +++ b/samples/cbm/Makefile @@ -137,14 +137,14 @@ plasma: plasma.c $(CL) -t $(SYS) -O -o plasma -m plasma.map plasma.c nachtm: nachtm.c $(CL) -t $(SYS) -O -o nachtm -m nachtm.map nachtm.c -hello: hello.s +hello: hello-asm.s # Use separate assembler ... - $(AS) -t $(SYS) hello.s + $(AS) -t $(SYS) hello-asm.s # ... and linker commands ... - $(LD) -C $(SYS)-asm.cfg -o hello -m hello.map -u __EXEHDR__ hello.o $(SYS).lib - @$(DEL) hello.o 2>$(NULLDEV) + $(LD) -C $(SYS)-asm.cfg -o hello -m hello-asm.map -u __EXEHDR__ hello-asm.o $(SYS).lib + @$(DEL) hello-asm.o 2>$(NULLDEV) # ... or compile & link utility -# $(CL) -C $(SYS)-asm.cfg -o hello -m hello.map -u __EXEHDR__ hello.s +# $(CL) -C $(SYS)-asm.cfg -o hello -m hello-asm.map -u __EXEHDR__ hello-asm.s # -------------------------------------------------------------------------- diff --git a/samples/cbm/hello.s b/samples/cbm/hello-asm.s similarity index 100% rename from samples/cbm/hello.s rename to samples/cbm/hello-asm.s From 64cfb322ccc2eb37ac6decdf49ec1cb7993a829f Mon Sep 17 00:00:00 2001 From: Olli Savia Date: Sun, 16 Jun 2024 19:14:24 +0300 Subject: [PATCH 202/707] Added asm configs for C16 & Plus/4 --- cfg/c16-asm.cfg | 20 ++++++++++++++++++++ cfg/plus4-asm.cfg | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 cfg/c16-asm.cfg create mode 100644 cfg/plus4-asm.cfg diff --git a/cfg/c16-asm.cfg b/cfg/c16-asm.cfg new file mode 100644 index 000000000..8cb839304 --- /dev/null +++ b/cfg/c16-asm.cfg @@ -0,0 +1,20 @@ +FEATURES { + STARTADDRESS: default = $1001; +} +SYMBOLS { + __LOADADDR__: type = import; +} +MEMORY { + ZP: file = "", start = $0002, size = $001A; + LOADADDR: file = %O, start = %S - 2, size = $0002; + MAIN: file = %O, start = %S, size = $3000 - %S; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + LOADADDR: load = LOADADDR, type = ro; + EXEHDR: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro, optional = yes; + DATA: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, define = yes; +} diff --git a/cfg/plus4-asm.cfg b/cfg/plus4-asm.cfg new file mode 100644 index 000000000..df47ba06e --- /dev/null +++ b/cfg/plus4-asm.cfg @@ -0,0 +1,20 @@ +FEATURES { + STARTADDRESS: default = $1001; +} +SYMBOLS { + __LOADADDR__: type = import; +} +MEMORY { + ZP: file = "", start = $0002, size = $001A; + LOADADDR: file = %O, start = %S - 2, size = $0002; + MAIN: file = %O, start = %S, size = $FD00 - %S; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + LOADADDR: load = LOADADDR, type = ro; + EXEHDR: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = ro; + RODATA: load = MAIN, type = ro, optional = yes; + DATA: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, define = yes; +} From 4989ce485c6f122415d68cef0591c9f7214c3de4 Mon Sep 17 00:00:00 2001 From: Olli Savia Date: Sun, 16 Jun 2024 19:15:54 +0300 Subject: [PATCH 203/707] Build hello-asm.s on C16 & Plus/4 --- samples/cbm/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/cbm/Makefile b/samples/cbm/Makefile index fe9d349bc..4b89722d2 100644 --- a/samples/cbm/Makefile +++ b/samples/cbm/Makefile @@ -103,10 +103,11 @@ EXELIST_cbm610 = \ nachtm EXELIST_plus4 = \ - plasma + plasma \ + hello EXELIST_c16 = \ - notavailable + hello EXELIST_pet = \ notavailable From 5caed9a15f14c00a920f0ac7c08b8dc41118a7c6 Mon Sep 17 00:00:00 2001 From: xlar54 Date: Sun, 16 Jun 2024 14:46:00 -0500 Subject: [PATCH 204/707] fixed setpalette --- libsrc/cx16/tgi/cx640p1.s | 87 ++++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 14 deletions(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 12b732613..9a154dfcf 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -31,7 +31,7 @@ .addr $0000 ; Library reference .word 640 ; X resolution .word 480 ; Y resolution - .byte 2 ; Number of drawing colors + .byte 2 ; Number of drawing colors .byte 0 ; Number of screens available .byte 8 ; System font X size .byte 8 ; System font Y size @@ -95,12 +95,9 @@ TEMP3 = sreg ; HORLINE SCRBASE: .res 1 ; High byte of screen base BITMASK: .res 1 ; $00 = clear, $FF = set pixels -OLDCOLOR: .res 1 ; colors before entering gfx mode -defpalette: .res $0100 -palette: .res $0100 +palette: .res 2 -bcolor := palette + 0 ; Background color color: .res 1 ; Stroke and fill index text_mode: .res 1 ; Old text mode @@ -124,6 +121,24 @@ ERROR: .byte TGI_ERR_OK ; Error code .rodata +defpalette: +col_black: .byte %00000000, %00000000 +col_white: .byte %11111111, %00001111 +col_red: .byte %00000000, %00001000 +col_cyan: .byte %11111110, %00001010 +col_purple: .byte %01001100, %00001100 +col_green: .byte %11000101, %00000000 +col_blue: .byte %00001010, %00000000 +col_yellow: .byte %11100111, %00001110 +col_orange: .byte %10000101, %00001101 +col_brown: .byte %01000000, %00000110 +col_lred: .byte %01110111, %00001111 +col_gray1: .byte %00110011, %00000011 +col_gray2: .byte %01110111, %00000111 +col_lgreen: .byte %11110110, %00001010 +col_lblue: .byte %10001111, %00000000 +col_gray3: .byte %10111011, %00001011 + ; Bit masks for setting pixels bitMasks1: .byte %10000000, %01000000, %00100000, %00010000 @@ -144,12 +159,10 @@ bitMasks2: INSTALL: ; Create the default palette. - - ldx #$00 -: txa - sta defpalette,x - inx - bnz :- + lda #$00 + sta palette + lda #$01 + sta palette+1 ; Fall through. @@ -182,7 +195,7 @@ INIT: stz ERROR ; #TGI_ERR_OK jsr SCREEN_MODE sta text_mode -; Switch into (640 x 480 x 2) graphics mode. +; Switch into (640 x 480 x 2 bpp) graphics mode. lda #%00000000 ; DCSEL = 0, VRAM port 1 sta VERA::CTRL @@ -313,8 +326,53 @@ SETDRAWPAGE: ; Must set an error code: YES SETPALETTE: - lda #TGI_ERR_INV_FUNC - sta ERROR + stz ERROR ; #TGI_ERR_OK + ldy #$01 ; Palette size of 2 colors +@L1: lda (ptr1),y ; Copy the palette + sta palette,y + dey + bpl @L1 + + ; set background color from palette color 0 + lda #$00 + sta VERA::ADDR + lda #$FA + sta VERA::ADDR+1 + lda #$01 + sta VERA::ADDR+2 ; write color RAM @ $1FA00 + + lda palette + asl + tay + lda defpalette,y + sta VERA::DATA0 + + inc VERA::ADDR ; $1FA01 + + lda palette + asl + tay + iny ; second byte of color + lda defpalette,y + sta VERA::DATA0 + + ; set foreground color from palette color 1 + inc VERA::ADDR ; $1FA02 + + lda palette+1 + asl + tay + lda defpalette,y + sta VERA::DATA0 + + inc VERA::ADDR ; $1FA03 + + lda palette+1 + asl + tay + iny ; second byte of color + lda defpalette,y + sta VERA::DATA0 rts ; ------------------------------------------------------------------------ @@ -328,6 +386,7 @@ SETCOLOR: beq @L1 lda #$FF @L1: sta BITMASK + stx color rts ; ------------------------------------------------------------------------ From 6dbf5f528ac4f4b8bb2692c156d039f98fa4860f Mon Sep 17 00:00:00 2001 From: xlar54 Date: Sun, 16 Jun 2024 14:51:53 -0500 Subject: [PATCH 205/707] argh dangling spaces --- libsrc/cx16/tgi/cx640p1.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 9a154dfcf..dde4024e5 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -361,7 +361,7 @@ SETPALETTE: lda palette+1 asl - tay + tay lda defpalette,y sta VERA::DATA0 From 6098ac278821d290b58a966f881de1d94a21534b Mon Sep 17 00:00:00 2001 From: xlar54 Date: Sun, 16 Jun 2024 16:06:38 -0500 Subject: [PATCH 206/707] fix for getdefpalette --- libsrc/cx16/tgi/cx640p1.s | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index dde4024e5..034bbb086 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -96,6 +96,7 @@ TEMP3 = sreg ; HORLINE SCRBASE: .res 1 ; High byte of screen base BITMASK: .res 1 ; $00 = clear, $FF = set pixels +defpalette: .res 2 palette: .res 2 color: .res 1 ; Stroke and fill index @@ -121,7 +122,7 @@ ERROR: .byte TGI_ERR_OK ; Error code .rodata -defpalette: +veracolors: col_black: .byte %00000000, %00000000 col_white: .byte %11111111, %00001111 col_red: .byte %00000000, %00001000 @@ -160,9 +161,9 @@ bitMasks2: INSTALL: ; Create the default palette. lda #$00 - sta palette + sta defpalette lda #$01 - sta palette+1 + sta defpalette+1 ; Fall through. @@ -344,7 +345,7 @@ SETPALETTE: lda palette asl tay - lda defpalette,y + lda veracolors,y sta VERA::DATA0 inc VERA::ADDR ; $1FA01 @@ -353,7 +354,7 @@ SETPALETTE: asl tay iny ; second byte of color - lda defpalette,y + lda veracolors,y sta VERA::DATA0 ; set foreground color from palette color 1 @@ -362,7 +363,7 @@ SETPALETTE: lda palette+1 asl tay - lda defpalette,y + lda veracolors,y sta VERA::DATA0 inc VERA::ADDR ; $1FA03 @@ -371,7 +372,7 @@ SETPALETTE: asl tay iny ; second byte of color - lda defpalette,y + lda veracolors,y sta VERA::DATA0 rts From 3b494ad6f2353e0aa9bc142af47371e406fb449b Mon Sep 17 00:00:00 2001 From: xlar54 Date: Wed, 19 Jun 2024 23:50:54 -0500 Subject: [PATCH 207/707] alignment fixes --- libsrc/cx16/tgi/cx640p1.s | 104 +++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 034bbb086..93d5cb698 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -31,7 +31,7 @@ .addr $0000 ; Library reference .word 640 ; X resolution .word 480 ; Y resolution - .byte 2 ; Number of drawing colors + .byte 2 ; Number of drawing colors .byte 0 ; Number of screens available .byte 8 ; System font X size .byte 8 ; System font Y size @@ -198,14 +198,14 @@ INIT: stz ERROR ; #TGI_ERR_OK ; Switch into (640 x 480 x 2 bpp) graphics mode. - lda #%00000000 ; DCSEL = 0, VRAM port 1 - sta VERA::CTRL - lda #%00100001 ; Disable sprites, layer 1 enable, VGA - sta VERA::DISP::VIDEO - lda #%00000100 ; Bitmap mode enable - sta VERA::L1::CONFIG - lda #%00000001 ; Tile width 640 - sta VERA::L1::TILE_BASE + lda #%00000000 ; DCSEL = 0, VRAM port 1 + sta VERA::CTRL + lda #%00100001 ; Disable sprites, layer 1 enable, VGA + sta VERA::DISP::VIDEO + lda #%00000100 ; Bitmap mode enable + sta VERA::L1::CONFIG + lda #%00000001 ; Tile width 640 + sta VERA::L1::TILE_BASE rts ; ------------------------------------------------------------------------ @@ -245,59 +245,57 @@ CONTROL: ; Must set an error code: NO CLEAR: - .scope inner + .scope inner - ; set up DCSEL=2 - lda #(2 << 1) - sta VERA::CTRL + ; set up DCSEL=2 + lda #(2 << 1) + sta VERA::CTRL - ; set cache writes - lda #$40 - tsb $9F29 ;VERA_FX_CTRL + ; set cache writes + lda #$40 + tsb VERA::DISP::VIDEO ; VERA_FX_CTRL when DCSEL=2 - ; set FX cache to all zeroes - lda #(6 << 1) - sta VERA::CTRL + ; set FX cache to all zeroes + lda #(6 << 1) + sta VERA::CTRL - lda #$00 + lda #$00 + sta VERA::DISP::VIDEO + sta VERA::DISP::HSCALE + sta VERA::DISP::VSCALE + sta VERA::DISP::FRAME -ahead: - sta VERA::DISP::VIDEO - sta VERA::DISP::HSCALE - sta VERA::DISP::VSCALE - sta VERA::DISP::FRAME + stz VERA::CTRL + ; set address and increment for bitmap area + stz VERA::ADDR + stz VERA::ADDR + 1 + lda #$30 ; increment +4 + sta VERA::ADDR + 2 - stz VERA::CTRL - ; set address and increment for bitmap area - stz VERA::ADDR - stz VERA::ADDR + 1 - lda #$30 ; increment +4 - sta VERA::ADDR + 2 + ldy #$F0 +@blank_outer: + ldx #$0A +@blank_loop: - ldy #$F0 -blank_outer: - ldx #$0A -blank_loop: + .repeat 8 + stz VERA::DATA0 + .endrep - .repeat 8 - stz VERA::DATA0 - .endrep + dex + bne @blank_loop + dey + bne @blank_outer - dex - bne blank_loop - dey - bne blank_outer + ; set up DCSEL=2 + lda #(2 << 1) + sta VERA::CTRL - ; set up DCSEL=2 - lda #(2 << 1) - sta VERA::CTRL + ; set FX off (cache write bit 1 -> 0) + stz $9F29 ;VERA_FX_CTRL + stz VERA::CTRL - ; set FX off (cache write bit 1 -> 0) - stz $9F29 ;VERA_FX_CTRL - stz VERA::CTRL - - .endscope - rts + .endscope + rts ; ------------------------------------------------------------------------ @@ -447,7 +445,7 @@ SETPIXEL: sta VERA::DATA0 ; Store back the modified byte rts - @ahead: +@ahead: ; if BITMASK = $FF, black is line color lda VERA::DATA0 ; Load the byte at memory address and bitMasks2,X ; OR with the bit mask @@ -482,7 +480,7 @@ GETPIXEL: lda #$00 rts - @ahead: +@ahead: ldx #$00 lda #$01 rts From 3d5fd0489e131106044c34f51efb32929092cc81 Mon Sep 17 00:00:00 2001 From: xlar54 Date: Wed, 19 Jun 2024 23:52:25 -0500 Subject: [PATCH 208/707] replaced constant --- libsrc/cx16/tgi/cx640p1.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 93d5cb698..287160f6b 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -291,7 +291,7 @@ CLEAR: sta VERA::CTRL ; set FX off (cache write bit 1 -> 0) - stz $9F29 ;VERA_FX_CTRL + stz VERA::DISP::VIDEO ; VERA_FX_CTRL when DCSEL=2 stz VERA::CTRL .endscope From 871bafa5b33ca8a13b891f8cd66b282ae8d90cc9 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Sun, 7 Jul 2024 00:48:15 +0200 Subject: [PATCH 209/707] Keep gcc-14 from aborting with errors due to new defaults. Adds -Wno-error=implicit-int -Wno-error=int-conversion to CFLAGS. Tested with gcc-12.4 and gcc-14.1. --- test/ref/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ref/Makefile b/test/ref/Makefile index 5c189c6cb..e82c6de37 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -50,7 +50,7 @@ ISEQUAL = ..$S..$Stestwrk$Sisequal$(EXE) # will have to change that, and create said special cases here. # see discussion in https://github.com/cc65/cc65/issues/2277 CC = gcc -CFLAGS = -std=gnu17 -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow +CFLAGS = -std=gnu17 -O2 -Wall -W -Wextra -funsigned-char -fwrapv -fno-strict-overflow -Wno-error=implicit-int -Wno-error=int-conversion .PHONY: all clean From cdb2d49e3a5737c4b4d2ad33bc512aaa4e8aec2a Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Sun, 7 Jul 2024 01:02:32 +0200 Subject: [PATCH 210/707] Test strtok(). --- test/ref/strtok.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 test/ref/strtok.c diff --git a/test/ref/strtok.c b/test/ref/strtok.c new file mode 100644 index 000000000..15c3a289d --- /dev/null +++ b/test/ref/strtok.c @@ -0,0 +1,43 @@ +// 2024-02-14 Sven Michael Klose + +#include +#include +#include + +void +error (void) +{ + printf ("strtok() test failed!\n"); + exit (-1); +} + +void +test (char * s) +{ + if (strcmp ("test", strtok (s, "/"))) + error (); + if (strcmp ("foo", strtok (NULL, "/"))) + error (); + if (strcmp ("bar", strtok (NULL, "/"))) + error (); + if (strtok (NULL, "/")) + error (); + if (strtok (NULL, "/")) + error (); +} + +int +main (void) +{ + char s1[] = "test/foo/bar"; + char s2[] = "/test/foo/bar"; + char s3[] = "//test/foo/bar"; + char s4[] = "//test/foo/bar//"; + + test (s1); + test (s2); + test (s3); + test (s4); + + return 0; +} From 581b79e0b9097592ab32bb00edce33c06d72917b Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Sun, 7 Jul 2024 14:04:49 +0200 Subject: [PATCH 211/707] Add stpcpy(). Like strcpy() but returning pointer to ending zero of copied string. --- include/string.h | 1 + libsrc/common/stpcpy.c | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 libsrc/common/stpcpy.c diff --git a/include/string.h b/include/string.h index b19f44e31..06c97d464 100644 --- a/include/string.h +++ b/include/string.h @@ -52,6 +52,7 @@ char* __fastcall__ strchr (const char* s, int c); int __fastcall__ strcmp (const char* s1, const char* s2); int __fastcall__ strcoll (const char* s1, const char* s2); char* __fastcall__ strcpy (char* dest, const char* src); +char* __fastcall__ stpcpy (char* dest, const char* src); size_t __fastcall__ strcspn (const char* s1, const char* s2); char* __fastcall__ strerror (int errcode); size_t __fastcall__ strlen (const char* s); diff --git a/libsrc/common/stpcpy.c b/libsrc/common/stpcpy.c new file mode 100644 index 000000000..153a3e361 --- /dev/null +++ b/libsrc/common/stpcpy.c @@ -0,0 +1,8 @@ +#include + +char * __fastcall__ +stpcpy (char * dst, const char * src) +{ + strcpy (dst, src); + return dst + strlen (src); +} From af3ac423733637c74400818d5281b3d3ec643df4 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Sun, 7 Jul 2024 19:48:44 +0200 Subject: [PATCH 212/707] Move stpcpy() to non-standard section. --- include/string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/string.h b/include/string.h index 06c97d464..3b7ece1d9 100644 --- a/include/string.h +++ b/include/string.h @@ -52,7 +52,6 @@ char* __fastcall__ strchr (const char* s, int c); int __fastcall__ strcmp (const char* s1, const char* s2); int __fastcall__ strcoll (const char* s1, const char* s2); char* __fastcall__ strcpy (char* dest, const char* src); -char* __fastcall__ stpcpy (char* dest, const char* src); size_t __fastcall__ strcspn (const char* s1, const char* s2); char* __fastcall__ strerror (int errcode); size_t __fastcall__ strlen (const char* s); @@ -91,6 +90,7 @@ char* __fastcall__ strlower (char* s); char* __fastcall__ strupr (char* s); char* __fastcall__ strupper (char* s); char* __fastcall__ strqtok (char* s1, const char* s2); +char* __fastcall__ stpcpy (char* dest, const char* src); #endif const char* __fastcall__ __stroserror (unsigned char errcode); From 816bcabe5aeb2b1dd3d884f2f1a091599b41a536 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Sun, 14 Jul 2024 23:12:59 +0200 Subject: [PATCH 213/707] Move strtok() test to correct section. --- test/{ref => val}/strtok.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{ref => val}/strtok.c (100%) diff --git a/test/ref/strtok.c b/test/val/strtok.c similarity index 100% rename from test/ref/strtok.c rename to test/val/strtok.c From 9558ebad624ed7c03eb7ddee12445482d1749a19 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Mon, 15 Jul 2024 17:35:28 +0200 Subject: [PATCH 214/707] Add test for stpcpy(). --- test/val/stpcpy.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 test/val/stpcpy.c diff --git a/test/val/stpcpy.c b/test/val/stpcpy.c new file mode 100644 index 000000000..8bdbfb926 --- /dev/null +++ b/test/val/stpcpy.c @@ -0,0 +1,44 @@ +// 2024-07-15 Sven Michael Klose + +#include +#include +#include +#include + +#define STR_SHORT "Hello, World!" +#define STR_LONG "This is a longer test string for stpcpy." + +int +main () +{ + char dest[50]; + const char *src_empty; + const char *src_short; + const char *src_long; + char *end; + + src_empty = ""; + end = stpcpy (dest, src_empty); + assert(!strcmp (dest, src_empty)); + assert(!*end); + assert(end == dest); + printf ("Test 1 passed.\n"); + + src_short = STR_SHORT; + end = stpcpy (dest, src_short); + assert(!strcmp (dest, src_short)); + assert(!*end); + assert(end == &dest[sizeof (STR_SHORT) - 1]); + printf ("Test 2 passed.\n"); + + src_long = STR_LONG; + end = stpcpy (dest, src_long); + assert(!strcmp (dest, src_long)); + assert(!*end); + assert(end == &dest[sizeof (STR_LONG) - 1]); + printf ("Test 3 passed.\n"); + + printf ("All tests passed.\n"); + return EXIT_SUCCESS; +} + From 677cd8ff4e2cd699375498baa93487fc756a43e6 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Mon, 15 Jul 2024 17:54:43 +0200 Subject: [PATCH 215/707] Use standard library's exit() code constants. --- test/val/strtok.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/val/strtok.c b/test/val/strtok.c index 15c3a289d..4d63bfb2a 100644 --- a/test/val/strtok.c +++ b/test/val/strtok.c @@ -1,5 +1,3 @@ -// 2024-02-14 Sven Michael Klose - #include #include #include @@ -8,7 +6,7 @@ void error (void) { printf ("strtok() test failed!\n"); - exit (-1); + exit (EXIT_FAILURE); } void @@ -39,5 +37,5 @@ main (void) test (s3); test (s4); - return 0; + return EXIT_SUCCESS; } From aed94d2dae9755a77040fec396d84edc883892ef Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Tue, 16 Jul 2024 01:33:48 +0200 Subject: [PATCH 216/707] Fix code style. Have type, function name and argument declaration on a single line. --- libsrc/common/stpcpy.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsrc/common/stpcpy.c b/libsrc/common/stpcpy.c index 153a3e361..12af47f2f 100644 --- a/libsrc/common/stpcpy.c +++ b/libsrc/common/stpcpy.c @@ -1,7 +1,6 @@ #include -char * __fastcall__ -stpcpy (char * dst, const char * src) +char * __fastcall__ stpcpy (char * dst, const char * src) { strcpy (dst, src); return dst + strlen (src); From d3e0f7b3921e6f96c1b7efe594ef0d57c00ae114 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Thu, 18 Jul 2024 10:00:16 +0200 Subject: [PATCH 217/707] Make document human-readable and split out name clashes section. In hope to reduce the pull request comment ping-pong. --- Contributing.md | 459 +++++++++++++++++++++++------------------- libsrc/NameClashes.md | 380 ++++++++++++++++++++++++++++++++++ 2 files changed, 637 insertions(+), 202 deletions(-) create mode 100644 libsrc/NameClashes.md diff --git a/Contributing.md b/Contributing.md index 1fde873f2..2ea50a183 100644 --- a/Contributing.md +++ b/Contributing.md @@ -1,188 +1,308 @@ -This document contains all kinds of information that you should know if you want to contribute to the cc65 project. Before you start, please read all of it. If something is not clear to you, please ask - this document is an ongoing effort and may well be incomplete. +Contributing to cc65 +==================== -Also, before you put a lot of work into implementing something you want to contribute, please get in touch with one of the developers and ask if what you are going to do is actually wanted and has a chance of being merged. Perhaps someone else is already working on it, or perhaps what you have in mind is not how we'd expect it to be - talking to us before you start might save you a lot of work in those cases. +This document contains all kinds of information that you +should know if you want to contribute to the cc65 project. +Before you start, please read all of it. If something is not +clear to you, please ask - this document is an ongoing effort +and may well be incomplete. -(''Note:'' The word "must" indicates a requirement. The word "should" indicates a recomendation.) +Also, before you put a lot of work into implementing +something you want to contribute, please get in touch with +one of the developers and ask if what you are going to do is +actually wanted and has a chance of being merged. Perhaps +someone else is already working on it, or perhaps what you +have in mind is not how we'd expect it to be - talking to us +before you start might save you a lot of work in those cases. -*this is work in progress and is constantly updated - if in doubt, please ask* +(''Note:'' The word "must" indicates a requirement. The word + "should" indicates a recomendation.) -# generally +*this is work in progress and is constantly updated - if in +doubt, please ask* -* You must obey these rules when contributing new code or documentation to cc65. We are well aware that not all existing code may respect all rules outlined here - but this is no reason for you not to respect them. -* One commit/patch/PR per issue. Do not mix several things unless they are very closely related. -* Sometimes when you make a PR, it may break completely unrelated tests. However, any PR is expected to merge cleanly with no failures. That means in practise that you are expected to fix/update the failing tests if required - for example this might be needed if you make changes to the compiler that changes the format of error- or warning messages. In that case you might have to update some reference files in the testbench. Obviously still check if that is actually the right thing to do ;) +# Generally + +* You must obey these rules when contributing new code or + documentation to cc65. We are well aware that not all + existing code may respect all rules outlined here - but this + is no reason for you not to respect them. +* One commit/patch/PR per issue. Do not mix several things + unless they are very closely related. +* Sometimes when you make a PR, it may break completely + unrelated tests. However, any PR is expected to merge + cleanly with no failures. That means in practise that you + are expected to fix/update the failing tests if required - + for example this might be needed if you make changes to the + compiler that changes the format of error- or warning + messages. In that case you might have to update some + reference files in the testbench. Obviously still check if + that is actually the right thing to do. ;) # Codestyle rules -## All Sources +## All sources ### Line endings -All files must only contain Unix style 'LF' line endings. Please configure your editors accordingly. +All files must only contain Unix style 'LF' line endings. +Please configure your editors accordingly. ### TABs and spaces -This is an ongoing controversial topic - everyone knows that. However, the following is how we do it :) +This is an ongoing controversial topic - everyone knows +that. However, the following is how we do it :) * TAB characters must be expanded to spaces. -* 4 spaces per indention level (rather than 8) are preferred, especially if there are many different levels. +* 4 spaces per indention level (rather than 8) are + preferred, especially if there are many different levels. * No extra spaces at the end of lines. -* All text files must end with new-line characters. Don't leave the last line "dangling". +* All text files must end with new-line characters. Don't + leave the last line "dangling". -The (bash) scripts used to check the above rules can be found in ```.github/check```. You can also run all checks using ```make check```. +The (bash) scripts used to check the above rules can be +found in ```.github/check```. You can also run all checks +using ```make check```. -### Identifiers and Symbol names +### Identifiers and symbol names -The C Standard defines certain identifiers and symbol names, which we can not use -in our code. Since it is not always obvious which parts of the library code will -actually end up in a linked program, the following applies to ALL of the library. +The C Standard defines certain identifiers and symbol names, +which we can not use in our code. Since it is not always +obvious which parts of the library code will actually end up +in a linked program, the following applies to ALL of the +library. -Any non standard identifier/symbol/function that is exported from source files, -or appears in header files: +Any non standard identifier/symbol/function that is exported +from source files, or appears in header files: -* must not be in the "_symbol" form in C, or "__symbol" form in assembly. -* must start with (at least) two (C Code) or three (assembly code) underscores, unless the symbol appears in a non standard header file. +* must not be in the "_symbol" form in C, or "__symbol" form + in assembly, +* must start with (at least) two (C Code) or three (assembly + code) underscores, unless the symbol appears in a non + standard header file. -This is likely more than the standard dictates us to do - but it is certainly -standard compliant - and easy to remember. +This is likely more than the standard dictates us to do - +but it is certainly standard compliant - and easy to +remember. -Also see the discussion in https://github.com/cc65/cc65/issues/1796 +Also see the discussion in +https://github.com/cc65/cc65/issues/1796 -### misc +### Miscellaneous -* 80 characters is the desired maximum width of files. But, it isn't a "strong" rule; sometimes, you will want to type longer lines, in order to keep the parts of expressions or comments together on the same line. +* 80 characters is the desired maximum width of files. But, + it isn't a "strong" rule; sometimes, you will want to type + longer lines, in order to keep the parts of expressions or + comments together on the same line. * You should avoid typing non-ASCII characters. -* If you change "normal" source code into comments, then you must add a comment about why that code is a comment. -* When you want to create a comment from several lines of code, you should use preprocessor lines, instead of ```/* */``` or "```;```". Example: -

+* If you change "normal" source code into comments, then you
+  must add a comment about why that code is a comment.
+* When you want to create a comment from several lines of
+  code, you should use preprocessor lines, instead of ```/*
+  */``` or "```;```".  Example:
+
+~~~C
 #if 0
-    one ();
-    two ();
-    three = two () + one ();
+  one (); two ();
+  three = two () + one ();
 #endif
-
+~~~ + * You should type upper case characters for hex values. -* When you type zero-page addresses in hexadecimal, you should type two hex characters (after the hex prefix). When you type non-zero-page addresses in hex, you should type four hex characters. -* When you type lists of addresses, it is a good idea to sort them in ascending numerical order. That makes it easier for readers to build mental pictures of where things are in an address space. And, it is easier to see how big the variables and buffers are. Example: -
+* When you type zero-page addresses in hexadecimal, you
+  should type two hex characters (after the hex prefix).
+  When you type non-zero-page addresses in hex, you should
+  type four hex characters.
+* When you type lists of addresses, it is a good idea to
+  sort them in ascending numerical order.  That makes it
+  easier for readers to build mental pictures of where things
+  are in an address space.  And, it is easier to see how big
+  the variables and buffers are.  Example:
+
+~~~asm
 xCoord := $0703
-yCoord := $0705        ; (this address implies that xCoord is 16 bits)
-cmdbuf := $0706        ; (this address implies that yCoord is 8 bits)
-cmdlen := $0786        ; (this address implies that cmdbuf is 128 bytes)
+yCoord := $0705 ; (this address implies that xCoord is 16 bits)
+cmdbuf := $0706 ; (this address implies that yCoord is 8 bits)
+cmdlen := $0786 ; (this address implies that cmdbuf is 128 bytes)
 color  := $0787
-
+~~~ -## C Sources +## C sources -The following is still very incomplete - if in doubt please look at existing sourcefiles and adapt to the existing style +The following is still very incomplete - if in doubt please +look at existing sourcefiles and adapt to the existing style. -* Your files should generally obey the C89 standard, with a few C99 things (this is a bit similar to what cc65 itself supports). The exceptions are: - * use stdint.h for variables that require a certain bit size - * In printf-style functions use the PRIX64 (and similar) macros to deal with 64bit values (from inttypes.h) -This list is not necessarily complete - if in doubt, please ask. +Your files should generally obey the C89 standard, with a +few C99 things (this is a bit similar to what cc65 itself +supports). The exceptions are: + +* Use stdint.h for variables that require a certain bit size +* In printf-style functions use the PRIX64 (and similar) + macros to deal with 64bit values (from inttypes.h) This + list is not necessarily complete - if in doubt, please ask. * We generally have a "no warnings" policy - * Warnings must not be hidden by using typecasts - fix the code instead +* Warnings must not be hidden by using typecasts - fix the + code instead * The normal indentation width should be four spaces. -* You must use ANSI C comments (```/* */```); you must not use C++ comments (```//```). -* When you add functions to an existing file, you should separate them by the same number of blank lines that separate the functions that already are in that file. -* All function declarations must be followed by a comment block that tells at least briefly what the function does, what the parameters are, and what is returned. This comment must sit between the declaration and the function body, like this: -
-int foo(int bar)
-/* Add 1 to bar, takes bar and returns the result */
+* You must use ANSI C comments (```/* */```); you must not
+  use C++ comments (```//```).
+* When you add functions to an existing file, you should
+  separate them by the same number of blank lines that
+  separate the functions that already are in that file.
+* All function declarations must be followed by a comment
+  block that tells at least briefly what the function does,
+  what the parameters are, and what is returned. This comment
+  must sit between the declaration and the function body, like
+  this:
+
+~~~C
+int foo(int bar) /* Add 1 to bar, takes bar and returns the result */
 {
     return bar + 1;
 }
-
-* When a function's argument list wraps around to a next line, you should indent that next line by either the normal width or enough spaces to align it with the arguments on the previous line. -* All declarations in a block must be at the beginning of that block. -* You should put a blank line between a list of local variable declarations and the first line of code. -* Always use curly braces even for single statements after ```if```, and the single statement should go into a new line. -* Use "cuddling" braces, ie the opening brace goes in the same line as the ```if```: -
+~~~
+
+* When a function's argument list wraps around to a next
+  line, you should indent that next line by either the
+  normal width or enough spaces to align it with the arguments
+  on the previous line.
+* All declarations in a block must be at the beginning of
+  that block.
+* You should put a blank line between a list of local
+  variable declarations and the first line of code.
+* Always use curly braces even for single statements after
+  ```if```, and the single statement should go into a new
+  line.
+* Use "cuddling" braces, ie the opening brace goes in the
+  same line as the ```if```:
+
+~~~C
 if (foo > 42) {
     bar = 23;
 }
-
-* Should the ```if``` statement be followed by an empty conditional block, there should be a comment telling why this is the case -
-if (check()) {
-    /* nothing happened, do nothing */
-}
-
-* You must separate function names and parameter/argument lists by one space. -* When declaring/defining pointers, you must put the asterisk (```*```) next to the data type, with a space between it and the variable's name. Examples: -
-    int* namedPtr[5];
-    char* nextLine (FILE* f);
-
+~~~ + +* Should the ```if``` statement be followed by an empty + conditional block, there should be a comment telling why + this is the case: + +~~~C +if (check()) { /* nothing happened, do nothing */ } +~~~ + +* You must separate function names and parameter/argument + lists by one space. +* When declaring/defining pointers, you must put the + asterisk (```*```) next to the data type, with a space + between it and the variable's name. Examples: + +~~~C +int* namedPtr[5]; +char* nextLine (FILE* f); +~~~ ### Header files -Headers that belong to the standard library (libc) must conform with the C standard. That means: -* all non standard functions, or functions that only exist in a certain standard, should be in #ifdefs - * the same is true for macros or typedefs -
-#if __CC65_STD__ == __CC65_STD_C99__
-/* stuff that only exists in C99 here */
-#endif
-#if __CC65_STD__ == __CC65_STD_CC65__
-/* non standard stuff here */
-#endif
-
-You can refer to Annex B of the ISO C99 standard ([here](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) is the draft). +Headers that belong to the standard library (libc) must +conform with the C standard. That means: -## Assembly Sources +* All non standard functions, or functions that only exist + in a certain standard, should be in #ifdefs +* The same is true for macros or typedefs. + You can refer to Annex B of the ISO C99 standard + ([here](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) + is the draft). Example: -* Op-code mnemonics must have lower-case letters. The names of instruction macroes may have upper-case letters. -* Op-codes must use their official and commonly used mnemonics, ie bcc and bcs and not bgt and blt -* Hexadecimal number constants should be used except where decimal or binary numbers make much more sense in that constant's context. +~~~C +#if __CC65_STD__ == __CC65_STD_C99__ /* stuff that only exists in C99 here */ +#endif +#if __CC65_STD__ == __CC65_STD_CC65__ /* non standard stuff here */ +#endif +~~~ + +## Assembly sources + +* Opcode mnemonics must have lower-case letters. The names + of instruction macroes may have upper-case letters. +* Opcodes must use their official and commonly used + mnemonics, ie 'bcc' and 'bcs' and not 'bgt' and 'blt'. +* Hexadecimal number constants should be used except where + decimal or binary numbers make much more sense in that + constant's context. * Hexadecimal letters should be upper-case. -* When you set two registers or two memory locations to an immediate 16-bit zero, you should use the expressions ```#<$0000``` and ```#>$0000``` (they make it obvious where you are putting the lower and upper bytes). -* If a function is declared to return a char-sized value, it actually must return an integer-sized value. (When cc65 promotes a returned value, it sometimes assumes that the value already is an integer.) This must be done in one of the following ways: -
+* When you set two registers or two memory locations to an
+  immediate 16-bit zero, you should use the expressions
+  ```#<$0000``` and ```#>$0000``` (they make it obvious where
+  you are putting the lower and upper bytes).
+* If a function is declared to return a char-sized value, it
+  actually must return an integer-sized value.  (When cc65
+  promotes a returned value, it sometimes assumes that the value
+  already is an integer.)
+  This must be done in one of the following ways:
+
+~~~asm
     lda #RETURN_VALUE
     ldx #0 ; Promote char return value
-
-or, if the value is 0, you can use: -
+
+    ; If the value is 0, you can use:
     lda #RETURN_VALUE
     .assert RETURN_VALUE = 0
     tax
-
-sometimes jumping to return0 could save a byte: -
+
+    ; Sometimes jumping to 'return 0' could save a byte:
     .assert RETURN_VALUE = 0
     jmp return 0
-
-* Functions, that are intended for a platform's system library, should be optimized as much as possible. -* Sometimes, there must be a trade-off between size and speed. If you think that a library function won't be used often, then you should make it small. Otherwise, you should make it fast. -* Comments that are put on the right side of instructions must be aligned (start in the same character columns). -* Assembly source fields (label, operation, operand, comment) should start ''after'' character columns that are multiples of eight (such as 1, 9, 17, 33, and 41). +~~~ + +* Functions, that are intended for a platform's system + library, should be optimized as much as possible. +* Sometimes, there must be a trade-off between size and + speed. If you think that a library function won't be used + often, then you should make it small. Otherwise, you should + make it fast. +* Comments that are put on the right side of instructions + must be aligned (start in the same character columns). +* Assembly source fields (label, operation, operand, + comment) should start ''after'' character columns that are + multiples of eight (such as 1, 9, 17, 33, and 41). -## LinuxDoc Sources +## LinuxDoc sources * TAB characters must be expanded to spaces. -* All text files must end with new-line characters. Don't leave the last line "dangling". +* All text files must end with new-line characters. Don't + leave the last line "dangling". * 80 characters is the desired maximum width of files. * You should avoid typing non-ASCII characters. * You should put blank lines between LinuxDoc sections: - * Three blank lines between `````` sections. - * Two blank lines between `````` sections. - * One blank line between other sections. +* Three blank lines between `````` sections. +* Two blank lines between `````` sections. +* One blank line between other sections. # Library implementation rules -* By default the toolchain must output a "standard" binary for the platform, no emulator formats, no extra headers used by tools. If the resulting binaries can not be run as is on emulators or eg flash cartridges, the process of converting them to something that can be used with these should be documented in the user manual. -* Generally every function should live in a seperate source file - unless the functions are so closely related that splitting makes no sense. -* Source files should not contain commented out code - if they do, there should be a comment that explains why that commented out code exists. +* By default the toolchain must output a "standard" binary + for the platform, no emulator formats, no extra headers + used by tools. If the resulting binaries can not be run as + is on emulators or eg flash cartridges, the process of + converting them to something that can be used with these + should be documented in the user manual. +* Generally every function should live in a seperate source + file - unless the functions are so closely related that + splitting makes no sense. +* Source files should not contain commented out code - if + they do, there should be a comment that explains why that + commented out code exists. # Makefile rules -* Makefiles must generally work on both *nix (ba)sh and windows cmd.exe. -* Makefiles must not use external tools that are not provided by the cc65 toolchain itself. +* Makefiles must generally work on both *nix (ba)sh and + windows cmd.exe. +* Makefiles must not use external tools that are not + provided by the cc65 toolchain itself. -The only exception to the above are actions that are exclusive to the github actions - those may rely on bash and/or linux tools. +The only exception to the above are actions that are exclusive +to the github actions - those may rely on bash and/or linux tools. # Documentation rules @@ -192,107 +312,42 @@ The only exception to the above are actions that are exclusive to the github act ## Wiki -* The Wiki is strictly for additional information that does not fit into the regular user manual (LinuxDoc). The wiki must not duplicate any information that is present in the user manual +* The Wiki is strictly for additional information that does + not fit into the regular user manual (LinuxDoc). The wiki + must not duplicate any information that is present in the + user manual. -# Roadmap / TODOs / open Ends +# Roadmap / TODOs / open ends ## Documentation -* the printf family of function does not completely implement all printf modifiers and does not behave as expected in some cases - all this should be documented in detail +* The printf() family of functions does not completely + implement all printf() modifiers and does not behave as + expected in some cases - all this should be documented in + detail. ## Compiler -* We need a way that makes it possible to feed arbitrary assembler code into the optimzer, so we can have proper tests for it +* We need a way that makes it possible to feed arbitrary + assembler code into the optimzer, so we can have proper + tests for it. ### Floating point support -The first step is implementing the datatype "float" as IEEE 754 floats. Help welcomed! +The first step is implementing the datatype "float" as IEEE +754 floats. Help welcomed! -* WIP compiler/library changes are here: https://github.com/cc65/cc65/pull/1777 +* WIP compiler/library changes are here: + https://github.com/cc65/cc65/pull/1777 ## Library -### name clashes in the library - -see "Identifiers and Symbol names" above - not all identifiers have been checked -and renamed yet. The following is a list of those that still might need to be -fixed: - -``` -common - -__argc libsrc/runtime/callmain.s libsrc/cbm610/mainargs.s libsrc/cx16/mainargs.s libsrc/plus4/mainargs.s libsrc/lynx/mainargs.s libsrc/c16/mainargs.s libsrc/geos-common/system/mainargs.s libsrc/sim6502/mainargs.s libsrc/c128/mainargs.s libsrc/vic20/mainargs.s libsrc/nes/mainargs.s libsrc/atari/getargs.s libsrc/apple2/mainargs.s libsrc/cbm510/mainargs.s libsrc/telestrat/mainargs.s libsrc/c64/mainargs.s libsrc/pet/mainargs.s libsrc/atmos/mainargs.s -__argv libsrc/runtime/callmain.s libsrc/cbm610/mainargs.s libsrc/cx16/mainargs.s libsrc/plus4/mainargs.s libsrc/lynx/mainargs.s libsrc/c16/mainargs.s libsrc/geos-common/system/mainargs.s libsrc/sim6502/mainargs.s libsrc/c128/mainargs.s libsrc/vic20/mainargs.s libsrc/nes/mainargs.s libsrc/atari/getargs.s libsrc/apple2/mainargs.s libsrc/cbm510/mainargs.s libsrc/telestrat/mainargs.s libsrc/c64/mainargs.s libsrc/pet/mainargs.s libsrc/atmos/mainargs.s -__cos libsrc/common/sincos.s -__ctypeidx libsrc/common/ctype.s libsrc/common/ctypemask.s libsrc/geos-common/system/ctype.s libsrc/atari/ctype.s libsrc/cbm/ctype.s libsrc/atmos/ctype.s asminc/ctype_common.inc -__cwd libsrc/common/getcwd.s libsrc/common/_cwd.s libsrc/atari/initcwd.s libsrc/apple2/initcwd.s libsrc/apple2/initcwd.s libsrc/telestrat/initcwd.s libsrc/cbm/initcwd.s -__cwd_buf_size libsrc/common/_cwd.s -__envcount libsrc/common/searchenv.s libsrc/common/_environ.s libsrc/common/putenv.s libsrc/common/getenv.s -__environ libsrc/common/searchenv.s libsrc/common/_environ.s libsrc/common/putenv.s libsrc/common/getenv.s -__envsize libsrc/common/_environ.s libsrc/common/putenv.s -__fdesc libsrc/common/_fdesc.s libsrc/common/fopen.s -__filetab libsrc/common/_fdesc.s libsrc/common/_file.s asminc/_file.inc -__fopen libsrc/common/fopen.s libsrc/common/_fopen.s -__printf libsrc/common/vsnprintf.s libsrc/common/_printf.s libsrc/common/vfprintf.s libsrc/conio/vcprintf.s libsrc/pce/_printf.s -__scanf libsrc/common/_scanf.inc libsrc/common/vsscanf.s libsrc/conio/vcscanf.s -__sin libsrc/common/sincos.s -__sys libsrc/common/_sys.s libsrc/apple2/_sys.s -__sys_oserrlist libsrc/common/stroserr.s libsrc/geos-common/system/oserrlist.s libsrc/atari/oserrlist.s libsrc/apple2/oserrlist.s libsrc/cbm/oserrlist.s libsrc/atmos/oserrlist.s -__syschdir libsrc/common/chdir.s libsrc/atari/syschdir.s libsrc/apple2/syschdir.s libsrc/telestrat/syschdir.s libsrc/cbm/syschdir.s -__sysmkdir libsrc/common/mkdir.s libsrc/atari/sysmkdir.s libsrc/apple2/sysmkdir.s libsrc/telestrat/sysmkdir.s -__sysremove libsrc/common/remove.s libsrc/geos-common/file/sysremove.s libsrc/atari/sysremove.s libsrc/atari/sysrmdir.s libsrc/apple2/sysremove.s libsrc/apple2/sysrmdir.s libsrc/telestrat/sysremove.s libsrc/cbm/sysremove.s -__sysrename libsrc/common/rename.s libsrc/geos-common/file/sysrename.s libsrc/atari/sysrename.s libsrc/apple2/sysrename.s libsrc/cbm/sysrename.s -__sysrmdir libsrc/common/rmdir.s libsrc/atari/sysrmdir.s libsrc/apple2/sysrmdir.s -__sysuname libsrc/common/uname.s libsrc/cbm610/sysuname.s libsrc/cx16/sysuname.s libsrc/plus4/sysuname.s libsrc/lynx/sysuname.s libsrc/c16/sysuname.s libsrc/geos-common/system/sysuname.s libsrc/c128/sysuname.s libsrc/creativision/sysuname.s libsrc/vic20/sysuname.s libsrc/nes/sysuname.s libsrc/atari/sysuname.s libsrc/apple2/sysuname.s libsrc/cbm510/sysuname.s libsrc/telestrat/sysuname.s libsrc/c64/sysuname.s libsrc/pet/sysuname.s libsrc/atari5200/sysuname.s libsrc/atmos/sysuname.s - -apple2 - -__auxtype libsrc/apple2/open.s -__datetime libsrc/apple2/open.s -__dos_type libsrc/apple2/dioopen.s libsrc/apple2/curdevice.s libsrc/apple2/mainargs.s libsrc/apple2/settime.s libsrc/apple2/getdevice.s libsrc/apple2/dosdetect.s libsrc/apple2/irq.s libsrc/apple2/open.s libsrc/apple2/mli.s libsrc/apple2/getres.s -__filetype libsrc/apple2/open.s libsrc/apple2/exehdr.s - - -atari - -__defdev libsrc/atari/posixdirent.s libsrc/atari/ucase_fn.s libsrc/atari/getdefdev.s -__dos_type libsrc/atari/getargs.s libsrc/atari/exec.s libsrc/atari/settime.s libsrc/atari/syschdir.s libsrc/atari/dosdetect.s libsrc/atari/is_cmdline_dos.s libsrc/atari/sysrmdir.s libsrc/atari/gettime.s libsrc/atari/lseek.s libsrc/atari/getres.s libsrc/atari/getdefdev.s -__do_oserror libsrc/atari/posixdirent.s libsrc/atari/do_oserr.s libsrc/atari/serref.s libsrc/atari/read.s libsrc/atari/write.s libsrc/atari/close.s -__getcolor libsrc/atari/setcolor.s -__getdefdev libsrc/atari/getdefdev.s -__graphics libsrc/atari/graphics.s -__inviocb libsrc/atari/serref.s libsrc/atari/ser/atrrdev.s libsrc/atari/inviocb.s libsrc/atari/read.s libsrc/atari/write.s libsrc/atari/lseek.s libsrc/atari/close.s -__is_cmdline_dos libsrc/atari/is_cmdline_dos.s libsrc/atari/doesclrscr.s -__rest_vecs libsrc/atari/savevec.s -__rwsetup libsrc/atari/rwcommon.s libsrc/atari/read.s libsrc/atari/write.s -__save_vecs libsrc/atari/savevec.s -__scroll libsrc/atari/scroll.s -__setcolor libsrc/atari/setcolor.s -__setcolor_low libsrc/atari/setcolor.s -__sio_call libsrc/atari/diowritev.s libsrc/atari/diopncls.s libsrc/atari/siocall.s libsrc/atari/diowrite.s libsrc/atari/dioread.s - - -cbm - -__cbm_filetype libsrc/cbm/cbm_filetype.s asminc/cbm_filetype.in -__dirread libsrc/cbm/dir.inc libsrc/cbm/dir.s -__dirread1 libsrc/cbm/dir.inc libsrc/cbm/dir.s - - -lynx - -__iodat libsrc/lynx/lynx-cart.s libsrc/lynx/bootldr.s libsrc/lynx/extzp.s libsrc/lynx/crt0.s libsrc/lynx/extzp.inc -__iodir libsrc/lynx/extzp.s libsrc/lynx/crt0.s libsrc/lynx/extzp.inc -__sprsys libsrc/lynx/tgi/lynx-160-102-16.s libsrc/lynx/extzp.s libsrc/lynx/crt0.s libsrc/lynx/extzp.inc -__viddma libsrc/lynx/tgi/lynx-160-102-16.s libsrc/lynx/extzp.s libsrc/lynx/crt0.s libsrc/lynx/extzp.inc - - -pce - -__nmi libsrc/pce/irq.s libsrc/pce/crt0.s -``` +Some name clashes need to be resolved. Please see the +[detailed list of name clashes](libsrc/NameClashes.md). ## Test suite -* specific tests to check the optimizer (rather than the codegenerator) are needed. -* we need more specific tests to check standard conformance of the library headers +* Specific tests to check the optimizer (rather than the code + generator) are needed. +* We need more specific tests to check standard conformance + of the library headers. diff --git a/libsrc/NameClashes.md b/libsrc/NameClashes.md new file mode 100644 index 000000000..ef2105602 --- /dev/null +++ b/libsrc/NameClashes.md @@ -0,0 +1,380 @@ +List of cc65 library name clashes +================================= + +The following is a list of identifiers that might need +to be fixed, sorted by directory and identifier: + +# common + +## \_\_argc + +* libsrc/runtime/callmain.s +* libsrc/cbm610/mainargs.s +* libsrc/cx16/mainargs.s +* libsrc/plus4/mainargs.s +* libsrc/lynx/mainargs.s +* libsrc/c16/mainargs.s +* libsrc/geos-common/system/mainargs.s +* libsrc/sim6502/mainargs.s +* libsrc/c128/mainargs.s +* libsrc/vic20/mainargs.s +* libsrc/nes/mainargs.s +* libsrc/atari/getargs.s +* libsrc/apple2/mainargs.s +* libsrc/cbm510/mainargs.s +* libsrc/telestrat/mainargs.s +* libsrc/c64/mainargs.s +* libsrc/pet/mainargs.s +* libsrc/atmos/mainargs.s + +## \_\_argv + +* libsrc/runtime/callmain.s +* libsrc/cbm610/mainargs.s +* libsrc/cx16/mainargs.s +* libsrc/plus4/mainargs.s +* libsrc/lynx/mainargs.s +* libsrc/c16/mainargs.s +* libsrc/geos-common/system/mainargs.s +* libsrc/sim6502/mainargs.s +* libsrc/c128/mainargs.s +* libsrc/vic20/mainargs.s +* libsrc/nes/mainargs.s +* libsrc/atari/getargs.s +* libsrc/apple2/mainargs.s +* libsrc/cbm510/mainargs.s +* libsrc/telestrat/mainargs.s +* libsrc/c64/mainargs.s +* libsrc/pet/mainargs.s +* libsrc/atmos/mainargs.s + +## \_\_cos + +* libsrc/common/sincos.s + +## \_\_ctypeidx + +* libsrc/common/ctype.s +* libsrc/common/ctypemask.s +* libsrc/geos-common/system/ctype.s +* libsrc/atari/ctype.s +* libsrc/cbm/ctype.s +* libsrc/atmos/ctype.s +* asminc/ctype\_common.inc + +## \_\_cwd + +* libsrc/common/getcwd.s +* libsrc/common/_cwd.s +* libsrc/atari/initcwd.s +* libsrc/apple2/initcwd.s +* libsrc/apple2/initcwd.s +* libsrc/telestrat/initcwd.s +* libsrc/cbm/initcwd.s + +## \_\_cwd\_buf\_size + +* libsrc/common/_cwd.s + +## \_\_envcount + +* libsrc/common/searchenv.s +* libsrc/common/_environ.s +* libsrc/common/putenv.s +* libsrc/common/getenv.s + +## \_\_environ + +* libsrc/common/searchenv.s +* libsrc/common/_environ.s +* libsrc/common/putenv.s +* libsrc/common/getenv.s + +## \_\_envsize + +* libsrc/common/_environ.s +* libsrc/common/putenv.s + +## \_\_fdesc + +* libsrc/common/_fdesc.s +* libsrc/common/fopen.s + +## \_\_filetab + +* libsrc/common/_fdesc.s +* libsrc/common/_file.s +* asminc/_file.inc + +## \_\_fopen + +* libsrc/common/fopen.s +* libsrc/common/_fopen.s + +## \_\_printf + +* libsrc/common/vsnprintf.s +* libsrc/common/_printf.s +* libsrc/common/vfprintf.s +* libsrc/conio/vcprintf.s +* libsrc/pce/_printf.s + +## \_\_scanf + +* libsrc/common/_scanf.inc +* libsrc/common/vsscanf.s +* libsrc/conio/vcscanf.s + +## \_\_sin + +* libsrc/common/sincos.s + +## \_\_sys + +* libsrc/common/_sys.s +* libsrc/apple2/_sys.s + +## \_\_sys\_oserrlist + +* libsrc/common/stroserr.s +* libsrc/geos-common/system/oserrlist.s +* libsrc/atari/oserrlist.s +* libsrc/apple2/oserrlist.s +* libsrc/cbm/oserrlist.s +* libsrc/atmos/oserrlist.s + +## \_\_syschdir + +* libsrc/common/chdir.s +* libsrc/atari/syschdir.s +* libsrc/apple2/syschdir.s +* libsrc/telestrat/syschdir.s +* libsrc/cbm/syschdir.s + +## \_\_sysmkdir + +* libsrc/common/mkdir.s +* libsrc/atari/sysmkdir.s +* libsrc/apple2/sysmkdir.s +* libsrc/telestrat/sysmkdir.s + +## \_\_sysremove + +* libsrc/common/remove.s +* libsrc/geos-common/file/sysremove.s +* libsrc/atari/sysremove.s +* libsrc/atari/sysrmdir.s +* libsrc/apple2/sysremove.s +* libsrc/apple2/sysrmdir.s +* libsrc/telestrat/sysremove.s +* libsrc/cbm/sysremove.s + +## \_\_sysrename + +* libsrc/common/rename.s +* libsrc/geos-common/file/sysrename.s +* libsrc/atari/sysrename.s +* libsrc/apple2/sysrename.s +* libsrc/cbm/sysrename.s + +## \_\_sysrmdir + +* libsrc/common/rmdir.s +* libsrc/atari/sysrmdir.s +* libsrc/apple2/sysrmdir.s + +\_\_sysuname + +* libsrc/common/uname.s +* libsrc/cbm610/sysuname.s +* libsrc/cx16/sysuname.s +* libsrc/plus4/sysuname.s +* libsrc/lynx/sysuname.s +* libsrc/c16/sysuname.s +* libsrc/geos-common/system/sysuname.s +* libsrc/c128/sysuname.s +* libsrc/creativision/sysuname.s +* libsrc/vic20/sysuname.s +* libsrc/nes/sysuname.s +* libsrc/atari/sysuname.s +* libsrc/apple2/sysuname.s +* libsrc/cbm510/sysuname.s +* libsrc/telestrat/sysuname.s +* libsrc/c64/sysuname.s +* libsrc/pet/sysuname.s +* libsrc/atari5200/sysuname.s +* libsrc/atmos/sysuname.s + +# apple2 + +## \_\_auxtype + +* libsrc/apple2/open.s + +## \_\_datetime + +* libsrc/apple2/open.s + +## \_\_dos\_type + +* libsrc/apple2/dioopen.s +* libsrc/apple2/curdevice.s +* libsrc/apple2/mainargs.s +* libsrc/apple2/settime.s +* libsrc/apple2/getdevice.s +* libsrc/apple2/dosdetect.s +* libsrc/apple2/irq.s +* libsrc/apple2/open.s +* libsrc/apple2/mli.s +* libsrc/apple2/getres.s + +## \_\_filetype + +* libsrc/apple2/open.s +* libsrc/apple2/exehdr.s + +## atari + +## \_\_defdev + +* libsrc/atari/posixdirent.s +* libsrc/atari/ucase\_fn.s +* libsrc/atari/getdefdev.s + +## \_\_dos\_type + +* libsrc/atari/getargs.s +* libsrc/atari/exec.s +* libsrc/atari/settime.s +* libsrc/atari/syschdir.s +* libsrc/atari/dosdetect.s +* libsrc/atari/is\_cmdline\_dos.s +* libsrc/atari/sysrmdir.s +* libsrc/atari/gettime.s +* libsrc/atari/lseek.s +* libsrc/atari/getres.s +* libsrc/atari/getdefdev.s + +## \_\_do\_oserror + +* libsrc/atari/posixdirent.s +* libsrc/atari/do\_oserr.s +* libsrc/atari/serref.s +* libsrc/atari/read.s +* libsrc/atari/write.s +* libsrc/atari/close.s + +## \_\_getcolor + +* libsrc/atari/setcolor.s + +## \_\_getdefdev + +* libsrc/atari/getdefdev.s + +## \_\_graphics + +* libsrc/atari/graphics.s + +## \_\_inviocb + +* libsrc/atari/serref.s +* libsrc/atari/ser/atrrdev.s +* libsrc/atari/inviocb.s +* libsrc/atari/read.s +* libsrc/atari/write.s +* libsrc/atari/lseek.s +* libsrc/atari/close.s + +## \_\_is\_cmdline\_dos + +* libsrc/atari/is\_cmdline\_dos.s +* libsrc/atari/doesclrscr.s + +## \_\_rest\_vecs + +* libsrc/atari/savevec.s + +## \_\_rwsetup + +* libsrc/atari/rwcommon.s +* libsrc/atari/read.s +* libsrc/atari/write.s + +## \_\_save\_vecs + +* libsrc/atari/savevec.s + +## \_\_scroll + +* libsrc/atari/scroll.s + +## \_\_setcolor + +* libsrc/atari/setcolor.s + +## \_\_setcolor\_low + +* libsrc/atari/setcolor.s + +## \_\_sio\_call + +* libsrc/atari/diowritev.s +* libsrc/atari/diopncls.s +* libsrc/atari/siocall.s +* libsrc/atari/diowrite.s +* libsrc/atari/dioread.s + +# cbm + +## \_\_cbm\_filetype + +* libsrc/cbm/cbm\_filetype.s +* asminc/cbm\_filetype.in + +## \_\_dirread + +* libsrc/cbm/dir.inc +* libsrc/cbm/dir.s + +## \_\_dirread1 + +* libsrc/cbm/dir.inc +* libsrc/cbm/dir.s + +# lynx + +## \_\_iodat + +* libsrc/lynx/lynx-cart.s +* libsrc/lynx/bootldr.s +* libsrc/lynx/extzp.s +* libsrc/lynx/crt0.s +* libsrc/lynx/extzp.inc + +## \_\_iodir + +* libsrc/lynx/extzp.s +* libsrc/lynx/crt0.s +* libsrc/lynx/extzp.inc + +## \_\_sprsys + +* libsrc/lynx/tgi/lynx-160-102-16.s +* libsrc/lynx/extzp.s +* libsrc/lynx/crt0.s +* libsrc/lynx/extzp.inc + +## \_\_viddma + +* libsrc/lynx/tgi/lynx-160-102-16.s +* libsrc/lynx/extzp.s +* libsrc/lynx/crt0.s +* libsrc/lynx/extzp.inc + +# pce + +## \_\_nmi + +* libsrc/pce/irq.s +* libsrc/pce/crt0.s From d5fecbf10b4711bf5ea15c5431fbc1e3bfcef115 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Thu, 18 Jul 2024 11:24:36 +0200 Subject: [PATCH 218/707] Add project origin and people and table of supported targets. Vital information that shouldn't require following links. --- README.md | 88 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index dce9a07bc..b9d81c35b 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,62 @@ -# About cc65 +The cc65 cross-compiler suite +============================= -cc65 is a complete cross development package for 65(C)02 systems, including -a powerful macro assembler, a C compiler, linker, archiver and several -other tools. cc65 has C and runtime library support for many of the old 6502 machines. -For details look at the [Website](https://cc65.github.io). +cc65 is a complete cross-development package for 65(C)02 systems, +including a powerful macro assembler, a C compiler, linker, archiver, +simulator and several other tools. cc65 has C and runtime library +support for many of the old 6502 machines. For details look at +the [cc65 web site](https://cc65.github.io): + +| Company / People | Machine / Environment | +|-------------------------|-------------------------------------| +| Apple | Apple II | +| | Apple IIe | +| Atari | Atari 400/800 | +| | Atari 2600 | +| | Atari 5200 | +| | Atari 7800 | +| | Atari XL | +| | Lynx | +| Oric | Atmos | +| | Telestrat | +| Acorn | BBC series | +| Commodore | C128 | +| | C16 | +| | C64 | +| | CBM 510/610 | +| | PET | +| | Plus/4 | +| | VIC-20 | +| VTech | CreatiVision | +| Commander X16 Community | Commander X16 | +| Bit Corporation | Gamate | +| Berkeley Softworks | GEOS (Apple/CBM) | +| LUnix Team | LUnix (C64) | +| Nintendo | Nintendo Entertainment System (NES) | +| Ohio Scientific | OSI C1P | +| MOS Technology, Inc. | KIM-1 | +| NEC | PC Engine (PCE) | +| Dr. Jozo Dujmović | Picocomputer (RP6502) | +| Watara | Watura/QuickShot Supervision | +| Synertek | SYM-1 | + +A generic configuration to adapt cc65 to new targets is also around. ## People -Project founders: +cc65 is originally based on the "Small C" compiler by Ron Cain and +enhanced by James E. Hendrix. -* John R. Dunning: [original implementation](https://public.websites.umich.edu/~archive/atari/8bit/Languages/Cc65/) of the C compiler and runtime library, Atari hosted +### Project founders + +* John R. Dunning: [original implementation](https://public.websites.umich.edu/~archive/atari/8bit/Languages/Cc65/) + of the C compiler and runtime library, Atari hosted. * Ullrich von Bassewitz: - * move the code to modern systems - * rewrite most parts of the compiler - * complete rewrite of the runtime library + * moved Dunning's code to modern systems, + * rewrote most parts of the compiler, + * rewrote all of the runtime library. -Core team members: +### Core team members * [Christian Groessler](https://github.com/groessler): Atari, Atari5200, and CreatiVision library Maintainer * [dqh](https://github.com/dqh-au): GHA help @@ -23,7 +64,7 @@ Core team members: * [groepaz](https://github.com/mrdudz): CBM library, Project Maintainer * [Oliver Schmidt](https://github.com/oliverschmidt): Apple II library Maintainer -External contributors: +### External contributors * [acqn](https://github.com/acqn): various compiler fixes * [jedeoric](https://github.com/jedeoric): Telestrat target @@ -36,28 +77,31 @@ External contributors: *(The above list is incomplete, if you feel left out - please speak up or add yourself in a PR)* -For a complete list look at the [full team list](https://github.com/orgs/cc65/teams) or the list of [all contributors](https://github.com/cc65/cc65/graphs/contributors) +For a complete list look at the [full team list](https://github.com/orgs/cc65/teams) +or the list of [all contributors](https://github.com/cc65/cc65/graphs/contributors). # Contact -For general discussion, questions, etc subscribe to the [mailing list](https://cc65.github.io/mailing-lists.html) or use the [github discussions](https://github.com/cc65/cc65/discussions). +For general discussion, questions, etc subscribe to the +[mailing list](https://cc65.github.io/mailing-lists.html) +or use the [github discussions](https://github.com/cc65/cc65/discussions). -Some of us may also be around on IRC [#cc65](https://web.libera.chat/#cc65) on libera.chat +Some of us may also be around on IRC [#cc65](https://web.libera.chat/#cc65) on libera.chat. # Documentation -* The main [Documentation](https://cc65.github.io/doc) for users and developers - -* Info on [Contributing](Contributing.md) to the CC65 project. Please read this before working on something you want to contribute, and before reporting bugs. - -* The [Wiki](https://github.com/cc65/wiki/wiki) contains some extra info that does not fit into the regular documentation. +* The main [Documentation](https://cc65.github.io/doc) for users and + developers. +* Info on [Contributing](Contributing.md) to the CC65 project. Please + read this before working on something you want to contribute, and + before reporting bugs. +* The [Wiki](https://github.com/cc65/wiki/wiki) contains some extra info + that does not fit into the regular documentation. # Downloads * [Windows 64bit Snapshot](https://sourceforge.net/projects/cc65/files/cc65-snapshot-win64.zip) - * [Windows 32bit Snapshot](https://sourceforge.net/projects/cc65/files/cc65-snapshot-win32.zip) - * [Linux Snapshot DEB and RPM](https://software.opensuse.org/download.html?project=home%3Astrik&package=cc65) [![Snapshot Build](https://github.com/cc65/cc65/actions/workflows/snapshot-on-push-master.yml/badge.svg?branch=master)](https://github.com/cc65/cc65/actions/workflows/snapshot-on-push-master.yml) From 19899022afaa817185d8aa4bbb349a8609706a66 Mon Sep 17 00:00:00 2001 From: karri Date: Sat, 20 Jul 2024 13:14:22 +0300 Subject: [PATCH 219/707] Add support for different joysticks --- libsrc/atari7800/joy/atari7800-stdjoy.s | 103 ++++++++++++++++-------- 1 file changed, 69 insertions(+), 34 deletions(-) diff --git a/libsrc/atari7800/joy/atari7800-stdjoy.s b/libsrc/atari7800/joy/atari7800-stdjoy.s index 59f656ada..c24e87e29 100644 --- a/libsrc/atari7800/joy/atari7800-stdjoy.s +++ b/libsrc/atari7800/joy/atari7800-stdjoy.s @@ -53,13 +53,20 @@ JOY_COUNT = 2 ; Number of joysticks we support ; Must return an JOY_ERR_xx code in a/x. ; +PB2 = $04 ; Joystick 0 +PB4 = $10 ; Joystick 1 + INSTALL: ; Assume 7800 2-button controller, can change ; to 2600 1-button later - lda #$14 - sta CTLSWB ; enable 2-button 7800 controller 1: set pin 6 to output + lda #(PB2 | PB4) + ; enable 2-button 7800 controllers on both ports + ; by setting PB2 and PB4 to output + sta CTLSWB + ; enable 2-button 7800 controllers by setting + ; the outputs to 0; (INPT4 and INPT5) high ldy #$00 - sty SWCHB ; enable 2-button 7800 controller 2: pull pin 6 (INPT4) high + sty SWCHB reset: lda #JOY_ERR_OK @@ -88,6 +95,28 @@ COUNT: ; ------------------------------------------------------------------------ ; READ: Read a particular joystick passed in A for 2 fire buttons. +readdualbuttons0: + ldy #0 ; ........ + bit INPT0 ; Check for right button + bpl L1 + ldy #2 ; ......2. +L1: bit INPT1 ; Check for left button + bpl L2 + iny ; ......21 +L2: tya + rts + +readdualbuttons1: + ldy #0 ; ........ + bit INPT2 ; Check for right button + bpl L1 + ldy #2 ; ......2. +L3: bit INPT3 ; Check for left button + bpl L2 + iny ; ......21 +L4: tya + rts + readbuttons: ; Y has joystick of interest 0/1 ; return value: @@ -97,42 +126,48 @@ readbuttons: ; $03: both buttons ; preserves X tya - beq L5 + beq readbuttons0 +readbuttons1: ; Joystick 1 processing - ; 7800 joystick 1 buttons - ldy #0 ; ........ - bit INPT2 ; Check for right button - bpl L1 - ldy #2 ; ......2. -L1: bit INPT3 ;Check for left button - bpl L2 - iny ; ......21 -L2: tya - bne L4 ; 7800 mode joystick worked - ; 2600 Joystick 1 + ; Start by checking for single button 2600 joystick bit INPT5 - bmi L4 -L3: iny ; .......1 - lda #0 ; Fallback to 2600 joystick mode - sta CTLSWB -L4: tya ; ......21 + bpl singlebtn1detected + jmp readdualbuttons1 +singlebtn1detected: + ; Single button joystick detected but could be dual + jsr readdualbuttons1 + bne L5 ; It was a dual button press + ; It was a single button press + bit INPT5 + bmi L5 + iny ; .......1 + lda #PB4 ; Joystick 1 is a single button unit + clc + adc SWCHB + sta SWCHB ; Cut power from the dual button circuit +L5: tya ; ......21 rts -L5: ; Joystick 0 processing - ; 7800 joystick 0 buttons - ldy #0 ; ........ - bit INPT0 ; Check for right button - bpl L6 - ldy #2 ; ......2. -L6: bit INPT1 ;Check for left button - bpl L7 - iny ; ......21 -L7: tya - bne L4 ; 7800 mode joystick worked - ; 2600 Joystick 0 +readbuttons0: + ; Joystick 0 processing + ; Start by checking for single button 2600 joystick bit INPT4 - bmi L4 - bpl L3 + bpl singlebtn0detected + jmp readdualbuttons0 +singlebtn0detected: + ; Single button joystick detected but could be dual + jsr readdualbuttons0 + bne L6 ; It was a dual button press + ; It was a single button press + bit INPT4 + bmi L6 + iny ; .......1 + lda #PB2 ; Joystick 0 is a single button unit + clc + adc SWCHB + sta SWCHB ; Cut power from the dual button circuit +L6: tya ; ......21 + rts READ: tay ; Store joystick 0/1 in Y From 8a1e060b137d0121f1be89ea7a79b0389f7ab123 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose Date: Mon, 22 Jul 2024 23:51:16 +0200 Subject: [PATCH 220/707] Fix function comment example. Must be on its own line. --- Contributing.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Contributing.md b/Contributing.md index 2ea50a183..5b53e0467 100644 --- a/Contributing.md +++ b/Contributing.md @@ -156,7 +156,8 @@ supports). The exceptions are: this: ~~~C -int foo(int bar) /* Add 1 to bar, takes bar and returns the result */ +int foo(int bar) +/* Add 1 to bar, takes bar and returns the result */ { return bar + 1; } From feb50268236efd2bf563352aa98e1eaa8b978eb9 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Wed, 7 Aug 2024 18:27:09 +0200 Subject: [PATCH 221/707] Added option to disable the force-to-uppercase behavior of the apple2 target. (#2474) * Added option to disable the force-to-uppercase behavior of the apple2 target. * Fixed dangling spaces. --- doc/apple2.sgml | 1 + doc/funcref.sgml | 1 + include/apple2.h | 10 ++++++++++ libsrc/apple2/allow_lowercase.s | 23 +++++++++++++++++++++++ libsrc/apple2/cputc.s | 5 ++++- libsrc/apple2/uppercasemask.s | 9 +++++++++ libsrc/apple2/write.s | 5 ++++- 7 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 libsrc/apple2/allow_lowercase.s create mode 100644 libsrc/apple2/uppercasemask.s diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 99ff8139e..c0255c4f7 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -330,6 +330,7 @@ usage. _dos_type _filetype _datetime +allow_lowercase beep get_ostype gmtime_dt diff --git a/doc/funcref.sgml b/doc/funcref.sgml index a0a6d7ca8..130646538 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -95,6 +95,7 @@ function. _dos_type +allow_lowercase diff --git a/include/apple2.h b/include/apple2.h index 875c10661..1a840be6e 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -232,6 +232,16 @@ struct tm* __fastcall__ gmtime_dt (const struct datetime* dt); time_t __fastcall__ mktime_dt (const struct datetime* dt); /* Converts a ProDOS date/time structure to a time_t UNIX timestamp */ +#if !defined(__APPLE2ENH__) +unsigned char __fastcall__ allow_lowercase (unsigned char onoff); +/* If onoff is 0, lowercase characters printed to the screen via STDIO and +** CONIO are forced to uppercase. If onoff is 1, lowercase characters are +** printed to the screen untouched. By default lowercase characters are +** forced to uppercase because a stock Apple ][+ doesn't support lowercase +** display. The function returns the old lowercase setting. +*/ +#endif + /* End of apple2.h */ diff --git a/libsrc/apple2/allow_lowercase.s b/libsrc/apple2/allow_lowercase.s new file mode 100644 index 000000000..648276b4c --- /dev/null +++ b/libsrc/apple2/allow_lowercase.s @@ -0,0 +1,23 @@ +; +; Oliver Schmidt, 2024-08-06 +; +; unsigned char __fastcall__ allow_lowercase (unsigned char onoff); +; + + .export _allow_lowercase + .import uppercasemask, return0, return1 + +_allow_lowercase: + tax + lda values,x + ldx uppercasemask + sta uppercasemask + cpx #$FF + beq :+ + jmp return0 +: jmp return1 + + .rodata + +values: .byte $DF ; Force uppercase + .byte $FF ; Keep lowercase diff --git a/libsrc/apple2/cputc.s b/libsrc/apple2/cputc.s index 035b1c047..0a27abacd 100644 --- a/libsrc/apple2/cputc.s +++ b/libsrc/apple2/cputc.s @@ -11,6 +11,9 @@ .export _cputcxy, _cputc .export cputdirect, newline, putchar, putchardirect .import gotoxy, VTABZ + .ifndef __APPLE2ENH__ + .import uppercasemask + .endif .include "apple2.inc" @@ -43,7 +46,7 @@ _cputc: .ifndef __APPLE2ENH__ cmp #$E0 ; Test for lowercase bcc cputdirect - and #$DF ; Convert to uppercase + and uppercasemask .endif cputdirect: diff --git a/libsrc/apple2/uppercasemask.s b/libsrc/apple2/uppercasemask.s new file mode 100644 index 000000000..8b993bb1e --- /dev/null +++ b/libsrc/apple2/uppercasemask.s @@ -0,0 +1,9 @@ +; +; Oliver Schmidt, 2024-08-06 +; + + .export uppercasemask + + .data + +uppercasemask: .byte $DF ; Convert to uppercase diff --git a/libsrc/apple2/write.s b/libsrc/apple2/write.s index 7b50d0705..5fb51cca6 100644 --- a/libsrc/apple2/write.s +++ b/libsrc/apple2/write.s @@ -7,6 +7,9 @@ .export _write .import rwprolog, rwcommon, rwepilog .import COUT + .ifndef __APPLE2ENH__ + .import uppercasemask + .endif .include "zeropage.inc" .include "errno.inc" @@ -84,7 +87,7 @@ next: lda (ptr1),y .ifndef __APPLE2ENH__ cmp #$E0 ; Test for lowercase bcc output - and #$DF ; Convert to uppercase + and uppercasemask .endif output: jsr COUT ; Preserves X and Y From 0126b34d209d11e58a381346409e9cd4540d55f2 Mon Sep 17 00:00:00 2001 From: Stefan Date: Sat, 10 Aug 2024 14:53:29 +0200 Subject: [PATCH 222/707] Fixed README.md Oric was not a company. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b9d81c35b..755a0d60d 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,14 @@ the [cc65 web site](https://cc65.github.io): | Company / People | Machine / Environment | |-------------------------|-------------------------------------| | Apple | Apple II | -| | Apple IIe | +| | Apple IIe enhanced | | Atari | Atari 400/800 | | | Atari 2600 | | | Atari 5200 | | | Atari 7800 | | | Atari XL | | | Lynx | -| Oric | Atmos | +| Tangerine | Atmos | | | Telestrat | | Acorn | BBC series | | Commodore | C128 | From bf2b5224786df9294fbb632b863240650870ae9a Mon Sep 17 00:00:00 2001 From: Stefan Date: Sat, 10 Aug 2024 15:12:34 +0200 Subject: [PATCH 223/707] Added company name and warning --- doc/atmos.sgml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/atmos.sgml b/doc/atmos.sgml index cef7770e4..e330d9517 100644 --- a/doc/atmos.sgml +++ b/doc/atmos.sgml @@ -1,15 +1,15 @@
-Oric Atmos-specific information for cc65 +<title>Tangerine Oric Atmos-specific information for cc65 <author> <url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> -<url url="mailto:polluks@sdf.lonestar.org" name="Stefan A. Haubenthal">,<newline> +<url url="mailto:polluks@sdf.org" name="Stefan A. Haubenthal">,<newline> <url url="mailto:greg.king5@verizon.net" name="Greg King"> <abstract> -An overview over the Atmos runtime system as it is implemented for the cc65 C -compiler. +An overview over the Oric Atmos runtime system as it is implemented for the cc65 +C compiler. This target is not Oric-1 compatible. </abstract> <!-- Table of contents --> From 86611f1c9cc899db784ed508339dce58a901fbb3 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 10 Aug 2024 15:29:50 +0200 Subject: [PATCH 224/707] Some clarification --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 755a0d60d..e3f1ab30f 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ the [cc65 web site](https://cc65.github.io): | | Atari 7800 | | | Atari XL | | | Lynx | -| Tangerine | Atmos | -| | Telestrat | +| Tangerine | Oric Atmos | +| Eureka | Oric Telestrat | | Acorn | BBC series | | Commodore | C128 | | | C16 | From 3f618d7de96ce32e41544d8a1e7e67f010168cf9 Mon Sep 17 00:00:00 2001 From: Sven Michael Klose <pixel@hugbox.org> Date: Sun, 18 Aug 2024 21:57:06 +0200 Subject: [PATCH 225/707] Add Plus/4 wrapper for KERNAL's GETIN. --- libsrc/plus4/kgetin.s | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 libsrc/plus4/kgetin.s diff --git a/libsrc/plus4/kgetin.s b/libsrc/plus4/kgetin.s new file mode 100644 index 000000000..14919f750 --- /dev/null +++ b/libsrc/plus4/kgetin.s @@ -0,0 +1,14 @@ +.export GETIN + +.include "plus4.inc" + +KERNAL_GETIN := $FFE4 + +.segment "LOWCODE" ; Stay out of ROM area. + +.proc GETIN + sta ENABLE_ROM + jsr KERNAL_GETIN + sta ENABLE_RAM + rts +.endproc From 622793e343b6241c00f5a13ce7b74a3a2f93b544 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Sat, 24 Aug 2024 17:03:27 +0200 Subject: [PATCH 226/707] Apple II: Move _exit out of STARTUP segment --- libsrc/apple2/callmain.s | 75 ++++++++++++++++++++++++++++++++++++++++ libsrc/apple2/crt0.s | 44 +++-------------------- 2 files changed, 79 insertions(+), 40 deletions(-) create mode 100644 libsrc/apple2/callmain.s diff --git a/libsrc/apple2/callmain.s b/libsrc/apple2/callmain.s new file mode 100644 index 000000000..71a8b5611 --- /dev/null +++ b/libsrc/apple2/callmain.s @@ -0,0 +1,75 @@ +; +; Ullrich von Bassewitz, 2003-03-07 +; +; Push arguments and call main() +; + + + .export callmain, _exit + .export __argc, __argv + + .import _main, pushax, done, donelib + .import zpsave, rvsave, reset + + .include "zeropage.inc" + .include "apple2.inc" + + +;--------------------------------------------------------------------------- +; Setup the stack for main(), then jump to it + +callmain: + lda __argc + ldx __argc+1 + jsr pushax ; Push argc + + lda __argv + ldx __argv+1 + jsr pushax ; Push argv + + ldy #4 ; Argument size + jsr _main + + ; Avoid a re-entrance of donelib. This is also the exit() entry. +_exit: ldx #<exit + lda #>exit + jsr reset ; Setup RESET vector + + ; Switch in LC bank 2 for R/O in case it was switched out by a RESET. + bit $C080 + + ; Call the module destructors. + jsr donelib + + ; Switch in ROM. + bit $C082 + + ; Restore the original RESET vector. +exit: ldx #$02 +: lda rvsave,x + sta SOFTEV,x + dex + bpl :- + + ; Copy back the zero-page stuff. + ldx #zpspace-1 +: lda zpsave,x + sta sp,x + dex + bpl :- + + ; ProDOS TechRefMan, chapter 5.2.1: + ; "System programs should set the stack pointer to $FF at the + ; warm-start entry point." + ldx #$FF + txs ; Re-init stack pointer + + ; We're done + jmp done + +;--------------------------------------------------------------------------- +; Data + +.data +__argc: .word 0 +__argv: .addr 0 diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index c129cdbf8..42e26c27b 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -4,10 +4,11 @@ ; Startup code for cc65 (Apple2 version) ; - .export _exit, done, return + .export done, return + .export zpsave, rvsave, reset .export __STARTUP__ : absolute = 1 ; Mark as startup - .import initlib, donelib + .import initlib, _exit .import zerobss, callmain .import __ONCE_LOAD__, __ONCE_SIZE__ ; Linker generated .import __LC_START__, __LC_LAST__ ; Linker generated @@ -33,44 +34,7 @@ jsr zerobss ; Push the command-line arguments; and, call main(). - jsr callmain - - ; Avoid a re-entrance of donelib. This is also the exit() entry. -_exit: ldx #<exit - lda #>exit - jsr reset ; Setup RESET vector - - ; Switch in LC bank 2 for R/O in case it was switched out by a RESET. - bit $C080 - - ; Call the module destructors. - jsr donelib - - ; Switch in ROM. - bit $C082 - - ; Restore the original RESET vector. -exit: ldx #$02 -: lda rvsave,x - sta SOFTEV,x - dex - bpl :- - - ; Copy back the zero-page stuff. - ldx #zpspace-1 -: lda zpsave,x - sta sp,x - dex - bpl :- - - ; ProDOS TechRefMan, chapter 5.2.1: - ; "System programs should set the stack pointer to $FF at the - ; warm-start entry point." - ldx #$FF - txs ; Re-init stack pointer - - ; We're done - jmp done + jmp callmain ; ------------------------------------------------------------------------ From 58b1c219965754f9a9367d1e75637d54998c8365 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 1 Sep 2024 10:22:40 +0200 Subject: [PATCH 227/707] Removed #pragma names that have been obsolete for over a decade. --- src/cc65/pragma.c | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index b9394494b..31cfe3b73 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -68,28 +68,20 @@ typedef enum { PRAGMA_ALIGN, PRAGMA_ALLOW_EAGER_INLINE, PRAGMA_BSS_NAME, - PRAGMA_BSSSEG, /* obsolete */ PRAGMA_CHARMAP, PRAGMA_CHECK_STACK, - PRAGMA_CHECKSTACK, /* obsolete */ PRAGMA_CODE_NAME, - PRAGMA_CODESEG, /* obsolete */ PRAGMA_CODESIZE, PRAGMA_DATA_NAME, - PRAGMA_DATASEG, /* obsolete */ PRAGMA_INLINE_STDFUNCS, PRAGMA_LOCAL_STRINGS, PRAGMA_MESSAGE, PRAGMA_OPTIMIZE, PRAGMA_REGISTER_VARS, PRAGMA_REGVARADDR, - PRAGMA_REGVARS, /* obsolete */ PRAGMA_RODATA_NAME, - PRAGMA_RODATASEG, /* obsolete */ PRAGMA_SIGNED_CHARS, - PRAGMA_SIGNEDCHARS, /* obsolete */ PRAGMA_STATIC_LOCALS, - PRAGMA_STATICLOCALS, /* obsolete */ PRAGMA_WARN, PRAGMA_WRAPPED_CALL, PRAGMA_WRITABLE_STRINGS, @@ -105,28 +97,20 @@ static const struct Pragma { { "align", PRAGMA_ALIGN }, { "allow-eager-inline", PRAGMA_ALLOW_EAGER_INLINE }, { "bss-name", PRAGMA_BSS_NAME }, - { "bssseg", PRAGMA_BSSSEG }, /* obsolete */ { "charmap", PRAGMA_CHARMAP }, { "check-stack", PRAGMA_CHECK_STACK }, - { "checkstack", PRAGMA_CHECKSTACK }, /* obsolete */ { "code-name", PRAGMA_CODE_NAME }, - { "codeseg", PRAGMA_CODESEG }, /* obsolete */ { "codesize", PRAGMA_CODESIZE }, { "data-name", PRAGMA_DATA_NAME }, - { "dataseg", PRAGMA_DATASEG }, /* obsolete */ { "inline-stdfuncs", PRAGMA_INLINE_STDFUNCS }, { "local-strings", PRAGMA_LOCAL_STRINGS }, { "message", PRAGMA_MESSAGE }, { "optimize", PRAGMA_OPTIMIZE }, { "register-vars", PRAGMA_REGISTER_VARS }, { "regvaraddr", PRAGMA_REGVARADDR }, - { "regvars", PRAGMA_REGVARS }, /* obsolete */ { "rodata-name", PRAGMA_RODATA_NAME }, - { "rodataseg", PRAGMA_RODATASEG }, /* obsolete */ { "signed-chars", PRAGMA_SIGNED_CHARS }, - { "signedchars", PRAGMA_SIGNEDCHARS }, /* obsolete */ { "static-locals", PRAGMA_STATIC_LOCALS }, - { "staticlocals", PRAGMA_STATICLOCALS }, /* obsolete */ { "warn", PRAGMA_WARN }, { "wrapped-call", PRAGMA_WRAPPED_CALL }, { "writable-strings", PRAGMA_WRITABLE_STRINGS }, @@ -402,22 +386,18 @@ static void ApplySegNamePragma (pragma_t Token, int PushPop, const char* Name, u switch (Token) { case PRAGMA_CODE_NAME: - case PRAGMA_CODESEG: Seg = SEG_CODE; break; case PRAGMA_RODATA_NAME: - case PRAGMA_RODATASEG: Seg = SEG_RODATA; break; case PRAGMA_DATA_NAME: - case PRAGMA_DATASEG: Seg = SEG_DATA; break; case PRAGMA_BSS_NAME: - case PRAGMA_BSSSEG: Seg = SEG_BSS; break; @@ -933,9 +913,6 @@ static void ParsePragmaString (void) FlagPragma (PES_STMT, Pragma, &B, &EagerlyInlineFuncs); break; - case PRAGMA_BSSSEG: - Warning ("#pragma bssseg is obsolete, please use #pragma bss-name instead"); - /* FALLTHROUGH */ case PRAGMA_BSS_NAME: /* TODO: PES_STMT or even PES_EXPR (PES_DECL) maybe? */ SegNamePragma (PES_FUNC, PRAGMA_BSS_NAME, &B); @@ -945,17 +922,11 @@ static void ParsePragmaString (void) CharMapPragma (PES_IMM, &B); break; - case PRAGMA_CHECKSTACK: - Warning ("#pragma checkstack is obsolete, please use #pragma check-stack instead"); - /* FALLTHROUGH */ case PRAGMA_CHECK_STACK: /* TODO: PES_SCOPE maybe? */ FlagPragma (PES_FUNC, Pragma, &B, &CheckStack); break; - case PRAGMA_CODESEG: - Warning ("#pragma codeseg is obsolete, please use #pragma code-name instead"); - /* FALLTHROUGH */ case PRAGMA_CODE_NAME: /* PES_FUNC is the only sensible option so far */ SegNamePragma (PES_FUNC, PRAGMA_CODE_NAME, &B); @@ -966,9 +937,6 @@ static void ParsePragmaString (void) IntPragma (PES_STMT, Pragma, &B, &CodeSizeFactor, 10, 1000); break; - case PRAGMA_DATASEG: - Warning ("#pragma dataseg is obsolete, please use #pragma data-name instead"); - /* FALLTHROUGH */ case PRAGMA_DATA_NAME: /* TODO: PES_STMT or even PES_EXPR (PES_DECL) maybe? */ SegNamePragma (PES_FUNC, PRAGMA_DATA_NAME, &B); @@ -999,33 +967,21 @@ static void ParsePragmaString (void) FlagPragma (PES_FUNC, Pragma, &B, &AllowRegVarAddr); break; - case PRAGMA_REGVARS: - Warning ("#pragma regvars is obsolete, please use #pragma register-vars instead"); - /* FALLTHROUGH */ case PRAGMA_REGISTER_VARS: /* TODO: PES_STMT or even PES_EXPR (PES_DECL) maybe? */ FlagPragma (PES_FUNC, Pragma, &B, &EnableRegVars); break; - case PRAGMA_RODATASEG: - Warning ("#pragma rodataseg is obsolete, please use #pragma rodata-name instead"); - /* FALLTHROUGH */ case PRAGMA_RODATA_NAME: /* TODO: PES_STMT or even PES_EXPR maybe? */ SegNamePragma (PES_FUNC, PRAGMA_RODATA_NAME, &B); break; - case PRAGMA_SIGNEDCHARS: - Warning ("#pragma signedchars is obsolete, please use #pragma signed-chars instead"); - /* FALLTHROUGH */ case PRAGMA_SIGNED_CHARS: /* TODO: PES_STMT or even PES_EXPR maybe? */ FlagPragma (PES_FUNC, Pragma, &B, &SignedChars); break; - case PRAGMA_STATICLOCALS: - Warning ("#pragma staticlocals is obsolete, please use #pragma static-locals instead"); - /* FALLTHROUGH */ case PRAGMA_STATIC_LOCALS: /* TODO: PES_STMT or even PES_EXPR (PES_DECL) maybe? */ FlagPragma (PES_FUNC, Pragma, &B, &StaticLocals); From ba263d13a7c7e99b07e080e68184bc6df17a7146 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 1 Sep 2024 10:22:57 +0200 Subject: [PATCH 228/707] Allow alternative #pragma names using underscores. --- src/cc65/pragma.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 31cfe3b73..ee71b42d8 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -86,36 +86,49 @@ typedef enum { PRAGMA_WRAPPED_CALL, PRAGMA_WRITABLE_STRINGS, PRAGMA_ZPSYM, - PRAGMA_COUNT } pragma_t; /* Pragma table */ static const struct Pragma { const char* Key; /* Keyword */ pragma_t Tok; /* Token */ -} Pragmas[PRAGMA_COUNT] = { +} Pragmas[] = { { "align", PRAGMA_ALIGN }, { "allow-eager-inline", PRAGMA_ALLOW_EAGER_INLINE }, + { "allow_eager_inline", PRAGMA_ALLOW_EAGER_INLINE }, { "bss-name", PRAGMA_BSS_NAME }, + { "bss_name", PRAGMA_BSS_NAME }, { "charmap", PRAGMA_CHARMAP }, { "check-stack", PRAGMA_CHECK_STACK }, + { "check_stack", PRAGMA_CHECK_STACK }, { "code-name", PRAGMA_CODE_NAME }, + { "code_name", PRAGMA_CODE_NAME }, { "codesize", PRAGMA_CODESIZE }, { "data-name", PRAGMA_DATA_NAME }, + { "data_name", PRAGMA_DATA_NAME }, { "inline-stdfuncs", PRAGMA_INLINE_STDFUNCS }, + { "inline_stdfuncs", PRAGMA_INLINE_STDFUNCS }, { "local-strings", PRAGMA_LOCAL_STRINGS }, + { "local_strings", PRAGMA_LOCAL_STRINGS }, { "message", PRAGMA_MESSAGE }, { "optimize", PRAGMA_OPTIMIZE }, { "register-vars", PRAGMA_REGISTER_VARS }, + { "register_vars", PRAGMA_REGISTER_VARS }, { "regvaraddr", PRAGMA_REGVARADDR }, { "rodata-name", PRAGMA_RODATA_NAME }, + { "rodata_name", PRAGMA_RODATA_NAME }, { "signed-chars", PRAGMA_SIGNED_CHARS }, + { "signed_chars", PRAGMA_SIGNED_CHARS }, { "static-locals", PRAGMA_STATIC_LOCALS }, + { "static_locals", PRAGMA_STATIC_LOCALS }, { "warn", PRAGMA_WARN }, { "wrapped-call", PRAGMA_WRAPPED_CALL }, + { "wrapped_call", PRAGMA_WRAPPED_CALL }, { "writable-strings", PRAGMA_WRITABLE_STRINGS }, + { "writable_strings", PRAGMA_WRITABLE_STRINGS }, { "zpsym", PRAGMA_ZPSYM }, }; +#define PRAGMA_COUNT (sizeof (Pragmas) / sizeof (Pragmas[0])) /* Result of ParsePushPop */ typedef enum { From 4008ec581423d5e17ac5e35ca9ee307f79f20a49 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 1 Sep 2024 10:23:10 +0200 Subject: [PATCH 229/707] Document the new #pragma names. --- doc/cc65.sgml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index efe48b61b..2219ccf6a 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1273,6 +1273,12 @@ If the first parameter is <tt/push/, the old value is saved onto a stack before changing it. The value may later be restored by using the <tt/pop/ parameter with the <tt/#pragma/. +For all pragma names that contain hyphens, the same name using underlines +instead of the hyphens is available as an alternative. While the former +resembles the corresponding command line option and is more orthogonal, the +latter may be more compatible with external tools that rewrite the token +sequences of the input. + <sect1><tt>#pragma allow-eager-inline ([push,] on|off)</tt><label id="pragma-allow-eager-inline"><p> From e40058257eb3798ea46a47957d95d87e7e78721c Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 1 Sep 2024 10:23:29 +0200 Subject: [PATCH 230/707] Added a test for the available #pragmas. --- test/val/pragmas.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 test/val/pragmas.c diff --git a/test/val/pragmas.c b/test/val/pragmas.c new file mode 100644 index 000000000..802c7a5c3 --- /dev/null +++ b/test/val/pragmas.c @@ -0,0 +1,44 @@ +/* Note: This tests just if the #pragmas are understood. It doesn't test if +** they do really work. This would require much more work. +*/ + +void func(void); +#pragma align(push, 1024) +#pragma allow-eager-inline(push, on) +#pragma allow_eager_inline(pop) +#pragma bss-name(push, "BSS") +#pragma bss_name(pop) +#pragma charmap(1, 1) +#pragma check-stack(on) +#pragma check_stack(off) +#pragma code-name(push, "CODE") +#pragma code_name("CODE") +#pragma codesize(200) +#pragma data-name("DATA") +#pragma data_name("DATA") +#pragma inline-stdfuncs(off) +#pragma inline_stdfuncs(on) +#pragma local-strings(off) +#pragma local_strings(off) +#pragma message("in a bottle") +#pragma optimize(off) +#pragma register-vars(off) +#pragma register_vars(on) +#pragma regvaraddr(on) +#pragma rodata-name("RODATA") +#pragma rodata_name("RODATA") +#pragma signed-chars(off) +#pragma signed_chars(on) +#pragma static-locals(off) +#pragma static_locals(on) +#pragma warn(unused-param, on) +#pragma wrapped-call(push, func, 0) // push is required for this #pragma +#pragma wrapped_call(push, func, 1) +#pragma writable-strings(on) +#pragma writable_strings(off) +#pragma zpsym("func") + +int main () +{ + return 0; +} From ef17250c64b2e7842e0807ccb63156c05cde35df Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 1 Sep 2024 10:26:45 +0200 Subject: [PATCH 231/707] Fixed a compiler warning. --- src/cc65/scanner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 6b5235679..879925c7c 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -1267,7 +1267,7 @@ static int CloseBrace (Collection* C, token_t Tok) */ { if (CollCount (C) > 0) { - token_t LastTok = (token_t)CollLast (C); + token_t LastTok = (token_t)(intptr_t)CollLast (C); if (LastTok == Tok) { CollPop (C); NextToken (); From 35c3fe5d0a8710312e5722ad9fad1581784c80fa Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 1 Sep 2024 10:29:59 +0200 Subject: [PATCH 232/707] Fix issue #2044. While doing so, cleanup copy&pasted code. --- src/ld65/config.c | 15 +++++--- src/ld65/exports.c | 87 +++++++++++++++++++--------------------------- 2 files changed, 47 insertions(+), 55 deletions(-) diff --git a/src/ld65/config.c b/src/ld65/config.c index 6c1f6ad4c..947302e98 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -889,6 +889,7 @@ static void ParseO65 (void) CfgOptionalAssign (); /* Check which attribute was given */ + CfgSymbol* Sym; switch (AttrTok) { case CFGTOK_EXPORT: @@ -896,8 +897,11 @@ static void ParseO65 (void) AttrFlags |= atExport; /* We expect an identifier */ CfgAssureIdent (); - /* Remember it as an export for later */ - NewCfgSymbol (CfgSymO65Export, GetStrBufId (&CfgSVal)); + /* Remember it as an export for later. We do not support o65 + * output for the 65816, so the address size is always 16 bit. + */ + Sym = NewCfgSymbol (CfgSymO65Export, GetStrBufId (&CfgSVal)); + Sym->AddrSize = ADDR_SIZE_ABS; /* Eat the identifier token */ CfgNextTok (); break; @@ -907,8 +911,11 @@ static void ParseO65 (void) AttrFlags |= atImport; /* We expect an identifier */ CfgAssureIdent (); - /* Remember it as an import for later */ - NewCfgSymbol (CfgSymO65Import, GetStrBufId (&CfgSVal)); + /* Remember it as an import for later. We do not support o65 + * output for the 65816, so the address size is always 16 bit. + */ + Sym = NewCfgSymbol (CfgSymO65Import, GetStrBufId (&CfgSVal)); + Sym->AddrSize = ADDR_SIZE_ABS; /* Eat the identifier token */ CfgNextTok (); break; diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 9149f54d1..9fa0e4019 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -808,6 +808,15 @@ static int CmpExpName (const void* K1, const void* K2) +static int CmpExpValue (const void* K1, const void* K2) +/* Compare function for qsort */ +{ + long Diff = GetExportVal (*(Export**)K1) - GetExportVal (*(Export**)K2); + return Diff < 0? -1 : Diff > 0? 1 : 0; +} + + + static void CreateExportPool (void) /* Create an array with pointer to all exports */ { @@ -880,19 +889,25 @@ static char GetAddrSizeCode (unsigned char AddrSize) -void PrintExportMapByName (FILE* F) -/* Print an export map, sorted by symbol name, to the given file */ +static void PrintExportMap (Export** Pool, unsigned Count, FILE* F) +/* Print an export map to the given file */ { unsigned I; - unsigned Count; /* Print all exports */ - Count = 0; - for (I = 0; I < ExpCount; ++I) { - const Export* E = ExpPool [I]; + unsigned Col = 0; + for (I = 0; I < Count; ++I) { + const Export* E = Pool [I]; - /* Print unreferenced symbols only if explictly requested */ - if (VerboseMap || E->ImpCount > 0 || SYM_IS_CONDES (E->Type)) { + /* Print unreferenced symbols only if explictly requested. If Expr is + ** NULL, the export is undefined. This happens for imports that don't + ** have a matching export, but if we have one of those, we don't come + ** here. It does also happen for imports that where satisfied from + ** elsewhere, like o65 imports defined in the linker config. + ** So ignore exports here that have an invalid Expr. + */ + if (E->Expr != 0 && + (VerboseMap || E->ImpCount > 0 || SYM_IS_CONDES (E->Type))) { fprintf (F, "%-25s %06lX %c%c%c%c ", GetString (E->Name), @@ -901,8 +916,8 @@ void PrintExportMapByName (FILE* F) SYM_IS_LABEL (E->Type)? 'L' : 'E', GetAddrSizeCode ((unsigned char) E->AddrSize), SYM_IS_CONDES (E->Type)? 'I' : ' '); - if (++Count == 2) { - Count = 0; + if (++Col == 2) { + Col = 0; fprintf (F, "\n"); } } @@ -912,13 +927,10 @@ void PrintExportMapByName (FILE* F) -static int CmpExpValue (const void* I1, const void* I2) -/* Compare function for qsort */ +void PrintExportMapByName (FILE* F) +/* Print an export map, sorted by symbol name, to the given file */ { - long V1 = GetExportVal (ExpPool [*(unsigned *)I1]); - long V2 = GetExportVal (ExpPool [*(unsigned *)I2]); - - return V1 < V2 ? -1 : V1 == V2 ? 0 : 1; + PrintExportMap (ExpPool, ExpCount, F); } @@ -926,43 +938,16 @@ static int CmpExpValue (const void* I1, const void* I2) void PrintExportMapByValue (FILE* F) /* Print an export map, sorted by symbol value, to the given file */ { - unsigned I; - unsigned Count; - unsigned *ExpValXlat; + /* Create a new pool that is sorted by value */ + Export** Pool = xmalloc (ExpCount * sizeof (Export*)); + memcpy (Pool, ExpPool, ExpCount * sizeof (Export*)); + qsort (Pool, ExpCount, sizeof (Export*), CmpExpValue); - /* Create a translation table where the symbols are sorted by value. */ - ExpValXlat = xmalloc (ExpCount * sizeof (unsigned)); - for (I = 0; I < ExpCount; ++I) { - /* Initialize table with current sort order. */ - ExpValXlat [I] = I; - } + /* Print the exports */ + PrintExportMap (Pool, ExpCount, F); - /* Sort them by value */ - qsort (ExpValXlat, ExpCount, sizeof (unsigned), CmpExpValue); - - /* Print all exports */ - Count = 0; - for (I = 0; I < ExpCount; ++I) { - const Export* E = ExpPool [ExpValXlat [I]]; - - /* Print unreferenced symbols only if explictly requested */ - if (VerboseMap || E->ImpCount > 0 || SYM_IS_CONDES (E->Type)) { - fprintf (F, - "%-25s %06lX %c%c%c%c ", - GetString (E->Name), - GetExportVal (E), - E->ImpCount? 'R' : ' ', - SYM_IS_LABEL (E->Type)? 'L' : 'E', - GetAddrSizeCode ((unsigned char) E->AddrSize), - SYM_IS_CONDES (E->Type)? 'I' : ' '); - if (++Count == 2) { - Count = 0; - fprintf (F, "\n"); - } - } - } - fprintf (F, "\n"); - xfree (ExpValXlat); + /* Free the allocated buffer */ + xfree (Pool); } From 4b68d19993c41da4f77342e8bc4dea74a9d4f80c Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 1 Sep 2024 10:42:18 +0200 Subject: [PATCH 233/707] Fix issue #1663. --- src/ca65/condasm.c | 72 +++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index 6198f4017..f872ec9ed 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -133,24 +133,26 @@ static void SetIfCond (IfDesc* ID, int C) -static void ElseClause (IfDesc* ID, const char* Directive) -/* Enter an .ELSE clause */ +static int ElseClause (IfDesc* ID, const char* Directive) +/* Enter an .ELSE clause. Return true if this was ok, zero on errors. */ { /* Check if we have an open .IF - otherwise .ELSE is not allowed */ if (ID == 0) { Error ("Unexpected %s", Directive); - return; + return 0; } /* Check for a duplicate else, then remember that we had one */ if (ID->Flags & ifElse) { /* We already had a .ELSE ! */ Error ("Duplicate .ELSE"); + return 0; } ID->Flags |= ifElse; /* Condition is inverted now */ ID->Flags ^= ifCond; + return 1; } @@ -226,46 +228,52 @@ void DoConditionals (void) D = GetCurrentIf (); /* Allow an .ELSE */ - ElseClause (D, ".ELSE"); + if (ElseClause (D, ".ELSE")) { + /* Remember the data for the .ELSE */ + if (D) { + ReleaseFullLineInfo (&D->LineInfos); + GetFullLineInfo (&D->LineInfos); + D->Name = ".ELSE"; + } - /* Remember the data for the .ELSE */ - if (D) { - ReleaseFullLineInfo (&D->LineInfos); - GetFullLineInfo (&D->LineInfos); - D->Name = ".ELSE"; + /* Calculate the new overall condition */ + CalcOverallIfCond (); + + /* Skip .ELSE */ + NextTok (); + ExpectSep (); + } else { + /* Problem with .ELSE, ignore remainder of line */ + SkipUntilSep (); } - - /* Calculate the new overall condition */ - CalcOverallIfCond (); - - /* Skip .ELSE */ - NextTok (); - ExpectSep (); break; case TOK_ELSEIF: D = GetCurrentIf (); /* Handle as if there was an .ELSE first */ - ElseClause (D, ".ELSEIF"); + if (ElseClause (D, ".ELSEIF")) { + /* Calculate the new overall if condition */ + CalcOverallIfCond (); - /* Calculate the new overall if condition */ - CalcOverallIfCond (); + /* Allocate and prepare a new descriptor */ + D = AllocIf (".ELSEIF", 0); + NextTok (); - /* Allocate and prepare a new descriptor */ - D = AllocIf (".ELSEIF", 0); - NextTok (); + /* Ignore the new condition if we are inside a false .ELSE + ** branch. This way we won't get any errors about undefined + ** symbols or similar... + */ + if (IfCond) { + SetIfCond (D, ConstExpression ()); + ExpectSep (); + } - /* Ignore the new condition if we are inside a false .ELSE - ** branch. This way we won't get any errors about undefined - ** symbols or similar... - */ - if (IfCond) { - SetIfCond (D, ConstExpression ()); - ExpectSep (); + /* Get the new overall condition */ + CalcOverallIfCond (); + } else { + /* Problem with .ELSEIF, ignore remainder of line */ + SkipUntilSep (); } - - /* Get the new overall condition */ - CalcOverallIfCond (); break; case TOK_ENDIF: From b5cc68d6e2afe6d249ad31c83bf64382eade7b49 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 1 Sep 2024 12:41:25 +0200 Subject: [PATCH 234/707] Do not save any register variables when entering main(). Do not restore the C stack when leaving main(). Both are unnecessary and just bloat the executable. --- src/cc65/codegen.c | 45 +++++++++++++++++++++++++-------------------- src/cc65/codegen.h | 2 +- src/cc65/function.c | 8 +++++--- src/cc65/locals.c | 44 ++++++++++++++++++++++++++++++++++---------- 4 files changed, 65 insertions(+), 34 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 69dcc1c6c..45823fab6 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -507,34 +507,39 @@ void g_enter (unsigned flags, unsigned argsize) -void g_leave (void) +void g_leave (int IsMainFunc) /* Function epilogue */ { - /* How many bytes of locals do we have to drop? */ - unsigned ToDrop = (unsigned) -StackPtr; + /* In the main function nothing has to be dropped because the program + ** is terminated anyway. + */ + if (!IsMainFunc) { + /* How many bytes of locals do we have to drop? */ + unsigned ToDrop = (unsigned) -StackPtr; - /* If we didn't have a variable argument list, don't call leave */ - if (funcargs >= 0) { + /* If we didn't have a variable argument list, don't call leave */ + if (funcargs >= 0) { - /* Drop stackframe if needed */ - g_drop (ToDrop + funcargs); + /* Drop stackframe if needed */ + g_drop (ToDrop + funcargs); - } else if (StackPtr != 0) { + } else if (StackPtr != 0) { + + /* We've a stack frame to drop */ + if (ToDrop > 255) { + g_drop (ToDrop); /* Inlines the code */ + AddCodeLine ("jsr leave"); + } else { + AddCodeLine ("ldy #$%02X", ToDrop); + AddCodeLine ("jsr leavey"); + } - /* We've a stack frame to drop */ - if (ToDrop > 255) { - g_drop (ToDrop); /* Inlines the code */ - AddCodeLine ("jsr leave"); } else { - AddCodeLine ("ldy #$%02X", ToDrop); - AddCodeLine ("jsr leavey"); + + /* Nothing to drop */ + AddCodeLine ("jsr leave"); + } - - } else { - - /* Nothing to drop */ - AddCodeLine ("jsr leave"); - } /* Add the final rts */ diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index 8e04b45e4..b95df5cfb 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -247,7 +247,7 @@ void g_scale (unsigned flags, long val); void g_enter (unsigned flags, unsigned argsize); /* Function prologue */ -void g_leave (void); +void g_leave (int IsMainFunc); /* Function epilogue */ diff --git a/src/cc65/function.c b/src/cc65/function.c index a4b860251..d5cab3993 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -646,11 +646,13 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* Output the function exit code label */ g_defcodelabel (F_GetRetLab (CurrentFunc)); - /* Restore the register variables */ - F_RestoreRegVars (CurrentFunc); + /* Restore the register variables (not necessary for main function) */ + if (!F_IsMainFunc (CurrentFunc)) { + F_RestoreRegVars (CurrentFunc); + } /* Generate the exit code */ - g_leave (); + g_leave (F_IsMainFunc (CurrentFunc)); /* Emit references to imports/exports */ EmitExternals (); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 34d762324..c4d0aa25b 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -111,22 +111,31 @@ static void ParseRegisterDecl (Declarator* Decl, int Reg) /* Get the size of the variable */ unsigned Size = SizeOf (Decl->Type); - /* Save the current contents of the register variable on stack */ - F_AllocLocalSpace (CurrentFunc); - g_save_regvars (Reg, Size); - - /* Add the symbol to the symbol table. We do that now, because for register - ** variables the current stack pointer is implicitly used as location for - ** the save area. - */ - Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, Reg); - /* Check for an optional initialization */ if (CurTok.Tok == TOK_ASSIGN) { /* Skip the '=' */ NextToken (); + /* If the register variable is initialized, the initialization code may + ** access other already declared variables. This means that we have to + ** allocate them now. + */ + F_AllocLocalSpace (CurrentFunc); + + /* Save the current contents of the register variable on stack. This is + ** not necessary for the main function. + */ + if (!F_IsMainFunc (CurrentFunc)) { + g_save_regvars (Reg, Size); + } + + /* Add the symbol to the symbol table. We do that now, because for + ** register variables the current stack pointer is implicitly used + ** as location for the save area (unused in case of main()). + */ + Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, Reg); + /* Special handling for compound types */ if (IsCompound) { @@ -173,6 +182,21 @@ static void ParseRegisterDecl (Declarator* Decl, int Reg) /* Mark the variable as referenced */ Sym->Flags |= SC_REF; + } else { + + /* Save the current contents of the register variable on stack. This is + ** not necessary for the main function. + */ + if (!F_IsMainFunc (CurrentFunc)) { + F_AllocLocalSpace (CurrentFunc); + g_save_regvars (Reg, Size); + } + + /* Add the symbol to the symbol table. We do that now, because for + ** register variables the current stack pointer is implicitly used + ** as location for the save area (unused in case of main()). + */ + Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, Reg); } /* Cannot allocate a variable of unknown size */ From b4aef6eac4f81ab2e29fc301559e23b4d464d1cc Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 1 Sep 2024 13:16:35 +0200 Subject: [PATCH 235/707] Fix macro preprocessing for #include. Arguments enclosed in "" or <> must not be preprocessed. See ISO/IEC 9899 1990 (E) section 6.8.2. --- src/cc65/preproc.c | 27 +++++++++++++++++++++++---- test/val/bug2458.c | 10 ++++++++++ test/val/bug2458.h | 1 + 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 test/val/bug2458.c create mode 100644 test/val/bug2458.h diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 66cbb2a9d..1ee810060 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -2812,11 +2812,30 @@ static void DoInclude (void) InputType IT; StrBuf Filename = AUTO_STRBUF_INITIALIZER; - /* Macro-replace a single line with special support for <filename> */ - SB_Clear (MLine); - PreprocessDirective (Line, MLine, MSM_TOK_HEADER); + /* Skip whitespace so the input pointer points to the argument */ + SkipWhitespace (0); - /* Read from the processed line */ + /* We may have three forms of the #include directive: + ** + ** - # include "q-char-sequence" new-line + ** - # include <h-char-sequence> new-line + ** - # include pp-tokens new-line + ** + ** The former two are processed as is while the latter is preprocessed and + ** must then resemble one of the first two forms. + */ + if (CurC == '"' || CurC == '<') { + /* Copy the argument part over to MLine */ + unsigned Start = SB_GetIndex (Line); + unsigned Length = SB_GetLen (Line) - Start; + SB_Slice (MLine, Line, Start, Length); + } else { + /* Macro-replace a single line with special support for <filename> */ + SB_Clear (MLine); + PreprocessDirective (Line, MLine, MSM_TOK_HEADER); + } + + /* Read from the copied/preprocessed line */ SB_Reset (MLine); MLine = InitLine (MLine); diff --git a/test/val/bug2458.c b/test/val/bug2458.c new file mode 100644 index 000000000..1494a7946 --- /dev/null +++ b/test/val/bug2458.c @@ -0,0 +1,10 @@ +#define str(arg) #arg +#include str(bug2458.h) /* Ok, macro replacement */ + +#define string foo +#include <string.h> /* Ok, no macro replacement */ + +int main() +{ + return 0; +} diff --git a/test/val/bug2458.h b/test/val/bug2458.h new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/test/val/bug2458.h @@ -0,0 +1 @@ + From b2aceaea241d39cc7f821790579e77e70c71fd4a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 1 Sep 2024 19:58:07 +0200 Subject: [PATCH 236/707] Fix behavior of .INCLUDE within a macro or .REPEAT. In the original code .INCLUDE was executed after expansion of the macro or .REPEAT - which was wrong and caused all sorts of unexpected behavior. Related issues/PRs are #231, #1473, #2159 and maybe others. Note: After this change error messages for nested macro/.include statements may be wrong. This is an unrelated bug that was always there and got exposed by this fix. The bug needs to be addressed in a separate PR. --- src/ca65/istack.c | 26 ++++++++++++++++++++++++++ src/ca65/istack.h | 20 ++++++++++++++++++++ src/ca65/scanner.c | 11 +++++++++-- 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/ca65/istack.c b/src/ca65/istack.c index 7a95e7e8c..979c09740 100644 --- a/src/ca65/istack.c +++ b/src/ca65/istack.c @@ -156,3 +156,29 @@ void CheckInputStack (void) Error ("Open %s", IStack->Desc); } } + + + +InputStack RetrieveInputStack (void) +/* Retrieve the current input stack. This will also clear it. Used when +** including a file. The current input stack is stored together with the old +** input file and restored when the file is closed. + */ +{ + /* We do not touch the counter so input sources are counted across + ** includes. + */ + InputStack S = IStack; + IStack = 0; + return S; +} + + + +void RestoreInputStack (InputStack S) +/* Restore an old input stack that was retrieved by RetrieveInputStack(). */ +{ + CHECK (IStack == 0); + IStack = S; +} + diff --git a/src/ca65/istack.h b/src/ca65/istack.h index aa37bab14..28c413d39 100644 --- a/src/ca65/istack.h +++ b/src/ca65/istack.h @@ -38,6 +38,17 @@ +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Opaque pointer to an input stack */ +typedef void* InputStack; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -63,6 +74,15 @@ void CheckInputStack (void); ** stuff on the input stack. */ +InputStack RetrieveInputStack (void); +/* Retrieve the current input stack. This will also clear it. Used when +** including a file. The current input stack is stored together with the old +** input file and restored when the file is closed. + */ + +void RestoreInputStack (InputStack S); +/* Restore an old input stack that was retrieved by RetrieveInputStack(). */ + /* End of istack.h */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 146c74958..89ff851fc 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -113,6 +113,7 @@ struct CharSource { token_t Tok; /* Last token */ int C; /* Last character */ int SkipN; /* For '\r\n' line endings, skip '\n\ if next */ + InputStack IStack; /* Saved input stack */ const CharSourceFunctions* Func; /* Pointer to function table */ union { InputFile File; /* File data */ @@ -321,6 +322,9 @@ static void UseCharSource (CharSource* S) S->Tok = CurTok.Tok; S->C = C; + /* Remember the current input stack */ + S->IStack = RetrieveInputStack (); + /* Use the new input source */ S->Next = Source; Source = S; @@ -347,7 +351,10 @@ static void DoneCharSource (void) /* Restore the old token */ CurTok.Tok = Source->Tok; - C = Source->C; + C = Source->C; + + /* Restore the old input source */ + RestoreInputStack (Source->IStack); /* Remember the last stacked input source */ S = Source->Next; @@ -1521,7 +1528,7 @@ CharAgain: /* In case of the main file, do not close it, but return EOF. */ if (Source && Source->Next) { DoneCharSource (); - goto Again; + goto Restart; } else { CurTok.Tok = TOK_EOF; } From cc0db26e20d4508f63db539ea619c57863e47d27 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 1 Sep 2024 20:22:29 +0200 Subject: [PATCH 237/707] Added some tests. --- test/asm/listing/070-include-macro.inc | 1 + test/asm/listing/070-include-macro.s | 13 +++++++++++++ test/asm/listing/070-include-repeat.inc | 1 + test/asm/listing/070-include-repeat.s | 4 ++++ test/asm/listing/ref/070-include-macro.err-ref | 1 + test/asm/listing/ref/070-include-repeat.err-ref | 6 ++++++ 6 files changed, 26 insertions(+) create mode 100644 test/asm/listing/070-include-macro.inc create mode 100644 test/asm/listing/070-include-macro.s create mode 100644 test/asm/listing/070-include-repeat.inc create mode 100644 test/asm/listing/070-include-repeat.s create mode 100644 test/asm/listing/ref/070-include-macro.err-ref create mode 100644 test/asm/listing/ref/070-include-repeat.err-ref diff --git a/test/asm/listing/070-include-macro.inc b/test/asm/listing/070-include-macro.inc new file mode 100644 index 000000000..0152a7965 --- /dev/null +++ b/test/asm/listing/070-include-macro.inc @@ -0,0 +1 @@ +foo: diff --git a/test/asm/listing/070-include-macro.s b/test/asm/listing/070-include-macro.s new file mode 100644 index 000000000..aad55cb52 --- /dev/null +++ b/test/asm/listing/070-include-macro.s @@ -0,0 +1,13 @@ +.macro IncludeFile FilePath + .proc bar + .include FilePath + .endproc +.endmacro + +IncludeFile "070-include-macro.inc" + +.ifdef bar::foo + .out "bar::foo is defined" +.else + .out "bar::foo is undefined" +.endif diff --git a/test/asm/listing/070-include-repeat.inc b/test/asm/listing/070-include-repeat.inc new file mode 100644 index 000000000..0eb22a710 --- /dev/null +++ b/test/asm/listing/070-include-repeat.inc @@ -0,0 +1 @@ +.out "include file" diff --git a/test/asm/listing/070-include-repeat.s b/test/asm/listing/070-include-repeat.s new file mode 100644 index 000000000..20170255f --- /dev/null +++ b/test/asm/listing/070-include-repeat.s @@ -0,0 +1,4 @@ +.repeat 3 + .include "070-include-repeat.inc" + .out "main file" +.endrepeat diff --git a/test/asm/listing/ref/070-include-macro.err-ref b/test/asm/listing/ref/070-include-macro.err-ref new file mode 100644 index 000000000..5faf98c4b --- /dev/null +++ b/test/asm/listing/ref/070-include-macro.err-ref @@ -0,0 +1 @@ +bar::foo is defined diff --git a/test/asm/listing/ref/070-include-repeat.err-ref b/test/asm/listing/ref/070-include-repeat.err-ref new file mode 100644 index 000000000..d42e70ee7 --- /dev/null +++ b/test/asm/listing/ref/070-include-repeat.err-ref @@ -0,0 +1,6 @@ +include file +main file +include file +main file +include file +main file From e2014611ef7932b7ef8f1e97c637e8fc29a6447a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Mon, 2 Sep 2024 07:02:41 +0200 Subject: [PATCH 238/707] Improve the usage output for the '-W' option. --- doc/cc65.sgml | 5 +++-- src/cc65/main.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 2219ccf6a..5c074991b 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -61,7 +61,7 @@ Short options: -Os Inline some standard functions -T Include source as comment -V Print the compiler version number - -W warning[,...] Suppress warnings + -W [-+]warning[,...] Control warnings ('-' disables, '+' enables) -d Debug mode -g Add debug info to object file -h Help (this text) @@ -84,8 +84,9 @@ Long options: --create-full-dep name Create a full make dependency file --data-name seg Set the name of the DATA segment --debug Debug mode + --debug-tables name Write symbol table debug info to a file --debug-info Add debug info to object file - --debug-opt name Configure optimizations with a file + --debug-opt name Debug optimization steps --debug-opt-output Debug output of each optimization step --dep-target target Use this dependency target --disable-opt name Disable an optimization step diff --git a/src/cc65/main.c b/src/cc65/main.c index 7dc5417f6..47435757c 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -91,7 +91,7 @@ static void Usage (void) " -Os\t\t\t\tInline some standard functions\n" " -T\t\t\t\tInclude source as comment\n" " -V\t\t\t\tPrint the compiler version number\n" - " -W warning[,...]\t\tSuppress warnings\n" + " -W [-+]warning[,...]\t\tControl warnings ('-' disables, '+' enables)\n" " -d\t\t\t\tDebug mode\n" " -g\t\t\t\tAdd debug info to object file\n" " -h\t\t\t\tHelp (this text)\n" From cd4357057f53a7a7fac0bb9dd39c7bfbe5a7a46a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:39:42 +0200 Subject: [PATCH 239/707] The change from #2495 didn't take into account that recursive calls to main() are legal in C. With the changes from #2495, such calls will usually crash the machine. But recursive calls to main() are rare and on the 6502 every byte saved is precious. So this change limits the effect of #2495 to cc65 mode and at the same time disallows recursive calls to main() in this mode. If recursive calls to main() are actually required, the code must be compiled in c89 or c99 mode. --- doc/cc65.sgml | 5 +++++ src/cc65/codegen.c | 8 ++++---- src/cc65/codegen.h | 2 +- src/cc65/expr.c | 26 ++++++++++++++++++++++---- src/cc65/function.c | 10 +++++++--- src/cc65/locals.c | 15 +++++++++++---- test/ref/custom-reference-error.c | 3 +-- test/val/nullptr.c | 4 +++- 8 files changed, 54 insertions(+), 19 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 2219ccf6a..8dd6d0202 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -823,6 +823,11 @@ and the one defined by the ISO standard: as it sounds, since the 6502 has so few registers that it isn't possible to keep values in registers anyway. <p> +<item> In <tt/cc65/ mode, <tt/main()/ cannot be called recursively. If this + is necessary, the program must be compiled in <tt/c89/ or <tt/c99/ mode + using the <tt><ref id="option--standard" name="--standard"></tt> + command line option. + <p> </itemize> There may be some more minor differences I'm currently not aware of. The diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 45823fab6..166176f5e 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -507,13 +507,13 @@ void g_enter (unsigned flags, unsigned argsize) -void g_leave (int IsMainFunc) +void g_leave (int DoCleanup) /* Function epilogue */ { - /* In the main function nothing has to be dropped because the program - ** is terminated anyway. + /* In the main function in cc65 mode nothing has to be dropped because + ** the program is terminated anyway. */ - if (!IsMainFunc) { + if (DoCleanup) { /* How many bytes of locals do we have to drop? */ unsigned ToDrop = (unsigned) -StackPtr; diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index b95df5cfb..734c95372 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -247,7 +247,7 @@ void g_scale (unsigned flags, long val); void g_enter (unsigned flags, unsigned argsize); /* Function prologue */ -void g_leave (int IsMainFunc); +void g_leave (int DoCleanup); /* Function epilogue */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index f6c681db8..2939ab1cc 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1219,9 +1219,6 @@ static void Primary (ExprDesc* E) /* Is the symbol known? */ if (Sym) { - /* We found the symbol - skip the name token */ - NextToken (); - /* Check for illegal symbol types */ CHECK ((Sym->Flags & SC_TYPEMASK) != SC_LABEL); if ((Sym->Flags & SC_TYPEMASK) == SC_TYPEDEF) { @@ -1230,9 +1227,14 @@ static void Primary (ExprDesc* E) /* Assume an int type to make E valid */ E->Flags = E_LOC_STACK | E_RTYPE_LVAL; E->Type = type_int; + /* Skip the erroneous token */ + NextToken (); break; } + /* Skip the name token */ + NextToken (); + /* Mark the symbol as referenced */ Sym->Flags |= SC_REF; @@ -1286,7 +1288,23 @@ static void Primary (ExprDesc* E) ** rvalue, too, because we cannot store anything in a function. ** So fix the flags depending on the type. */ - if (IsTypeArray (E->Type) || IsTypeFunc (E->Type)) { + if (IsTypeArray (E->Type)) { + ED_AddrExpr (E); + } else if (IsTypeFunc (E->Type)) { + /* In cc65 mode we cannot call or take the address of + ** main(). + */ + if (IS_Get (&Standard) == STD_CC65 && + strcmp (Sym->Name, "main") == 0) { + /* Adjust the error message depending on a call or an + ** address operation. + */ + if (CurTok.Tok == TOK_LPAREN) { + Error ("'main' must not be called recursively"); + } else { + Error ("The address of 'main' cannot be taken"); + } + } ED_AddrExpr (E); } diff --git a/src/cc65/function.c b/src/cc65/function.c index d5cab3993..fed0349dd 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -646,13 +646,17 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* Output the function exit code label */ g_defcodelabel (F_GetRetLab (CurrentFunc)); - /* Restore the register variables (not necessary for main function) */ - if (!F_IsMainFunc (CurrentFunc)) { + /* Restore the register variables (not necessary for the main function in + ** cc65 mode) + */ + int CleanupOnExit = (IS_Get (&Standard) != STD_CC65) || + !F_IsMainFunc (CurrentFunc); + if (CleanupOnExit) { F_RestoreRegVars (CurrentFunc); } /* Generate the exit code */ - g_leave (F_IsMainFunc (CurrentFunc)); + g_leave (CleanupOnExit); /* Emit references to imports/exports */ EmitExternals (); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index c4d0aa25b..08e41918e 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -111,6 +111,13 @@ static void ParseRegisterDecl (Declarator* Decl, int Reg) /* Get the size of the variable */ unsigned Size = SizeOf (Decl->Type); + /* Check if this is the main function and we are in cc65 mode. If so, we + ** won't save the old contents of the register variables since in cc65 + ** mode main() may not be called recursively. + */ + int SaveRegVars = (IS_Get (&Standard) != STD_CC65) || + !F_IsMainFunc (CurrentFunc); + /* Check for an optional initialization */ if (CurTok.Tok == TOK_ASSIGN) { @@ -126,13 +133,13 @@ static void ParseRegisterDecl (Declarator* Decl, int Reg) /* Save the current contents of the register variable on stack. This is ** not necessary for the main function. */ - if (!F_IsMainFunc (CurrentFunc)) { + if (SaveRegVars) { g_save_regvars (Reg, Size); } /* Add the symbol to the symbol table. We do that now, because for ** register variables the current stack pointer is implicitly used - ** as location for the save area (unused in case of main()). + ** as location for the save area (maybe unused in case of main()). */ Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, Reg); @@ -187,14 +194,14 @@ static void ParseRegisterDecl (Declarator* Decl, int Reg) /* Save the current contents of the register variable on stack. This is ** not necessary for the main function. */ - if (!F_IsMainFunc (CurrentFunc)) { + if (SaveRegVars) { F_AllocLocalSpace (CurrentFunc); g_save_regvars (Reg, Size); } /* Add the symbol to the symbol table. We do that now, because for ** register variables the current stack pointer is implicitly used - ** as location for the save area (unused in case of main()). + ** as location for the save area (maybe unused in case of main()). */ Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, Reg); } diff --git a/test/ref/custom-reference-error.c b/test/ref/custom-reference-error.c index e98fb024d..455e0276d 100644 --- a/test/ref/custom-reference-error.c +++ b/test/ref/custom-reference-error.c @@ -22,6 +22,5 @@ return_t main(int argc, char* argv[]) n = 0; /* produce an error */ /* produce a warning */ } - -int arr[main(0, 0)]; /* produce an error */ int b = 0; +int arr[b]; /* produce an error */ diff --git a/test/val/nullptr.c b/test/val/nullptr.c index e64b82ee2..a5b72e8c5 100644 --- a/test/val/nullptr.c +++ b/test/val/nullptr.c @@ -28,6 +28,8 @@ struct S { } \ } while(0); +void func() { } + int main() { int a; @@ -60,7 +62,7 @@ int main() TEST_NON_NULL(((struct S*)&a)->a) /* Non-null pointer obtained with cast and -> */ - TEST_NON_NULL(((struct S*)&main)->a) + TEST_NON_NULL(((struct S*)&func)->a) if (failures != 0) { From 79606c4d20e00db5be257d25bf7ab78109e1df3e Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Mon, 2 Sep 2024 16:55:58 +0200 Subject: [PATCH 240/707] Overlooked a few target tests that take the address of main(). --- targettest/atari/mem.c | 4 +++- targettest/pce/conio.c | 4 +++- targettest/scanf-test.c | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/targettest/atari/mem.c b/targettest/atari/mem.c index bc70aded6..b15b215ed 100644 --- a/targettest/atari/mem.c +++ b/targettest/atari/mem.c @@ -21,6 +21,8 @@ unsigned int *MEMTOP = (unsigned int *)741; unsigned int *MEMLO = (unsigned int *)743; void *allocmem; +void code(void) { } + int main(void) { allocmem = malloc(257); @@ -35,7 +37,7 @@ int main(void) printf(" MEMLO = $%04X (%u)\n", *MEMLO, *MEMLO); printf(" ----------------------\n"); - printf(" main: $%04X (code)\n", &main); + printf(" code: $%04X (code)\n", &code); printf(" data: $%04X (data)\n", &data); printf(" _dos_type: $%04X (bss)\n", &_dos_type); printf(" allocmem: $%04X (dyn. data)\n", allocmem); diff --git a/targettest/pce/conio.c b/targettest/pce/conio.c index 55f828f26..819e601be 100644 --- a/targettest/pce/conio.c +++ b/targettest/pce/conio.c @@ -11,6 +11,8 @@ static char hex[16] = { "0123456789abcdef" }; static char charbuf[0x20]; static char colbuf[0x20]; +void func(void) { } + void main(void) { int stackvar = 42; @@ -65,7 +67,7 @@ void main(void) p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15] ); } - memcpy(p, main, i = 0); /* test that a zero length doesn't copy 64K */ + memcpy(p, func, i = 0); /* test that a zero length doesn't copy 64K */ gotoxy(0,ysize - 1); for (i = 0; i < xsize; ++i) { diff --git a/targettest/scanf-test.c b/targettest/scanf-test.c index f17b62294..e0ab95756 100644 --- a/targettest/scanf-test.c +++ b/targettest/scanf-test.c @@ -159,12 +159,14 @@ static void Pause(void) { #endif } +static void Nil() { } + int main(void) { long n0; unsigned t; int c, n1 = 12345, n2, n3; char s1[80], s2[80]; - void *p1 = main, *p2 = main, *p3 = main, *p4 = main; + void *p1 = Nil, *p2 = Nil, *p3 = Nil, *p4 = Nil; #ifndef USE_STDIO clrscr(); From d996e20c5f187023a39498aa4bf3e2b888aad362 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 3 Sep 2024 20:21:48 +0200 Subject: [PATCH 241/707] Fix issues #2461. This was always wrong even in cases where it seemed to work. If it did, it was by coincidence. --- src/cc65/codeoptutil.c | 6 ++-- test/val/bug2461.c | 67 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 test/val/bug2461.c diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 173d5185f..43b1dee22 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -1128,8 +1128,10 @@ void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) InsertEntry (D, X, D->IP++); } - /* In both cases, we can remove the load */ - LI->X.Flags |= LI_REMOVE; + /* If this is the right hand side, we can remove the load. */ + if (LI == &D->Rhs) { + LI->X.Flags |= LI_REMOVE; + } } else { /* opc zphi */ diff --git a/test/val/bug2461.c b/test/val/bug2461.c new file mode 100644 index 000000000..e8340b224 --- /dev/null +++ b/test/val/bug2461.c @@ -0,0 +1,67 @@ +/* related to bug #2461 */ + +/* Note: The values for MASK1, MASK2, the return values of GarbleAX and the + * arguments for CALC() are carefully chosen to elicit the bug. + */ + +#include <stdio.h> + +#define MASK1 0x000FU +#define MASK2 0x00FFU +#define CALC(num, op) (((num) & (~MASK1)) op ((num) & MASK2)) + +static unsigned Failures = 0; +static unsigned TestCount = 0; + +unsigned GarbleAX(void) +{ + static const unsigned Garbage[] = { + 0x1234, 0x0000, 0x1234, 0x1234 + }; + return Garbage[TestCount - 1]; +} + +unsigned WrongAdd(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALC(num, +); +} + +unsigned WrongAnd(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALC(num, &); +} + +unsigned WrongOr(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALC(num, |); +} + +unsigned WrongXor(unsigned num) +{ + unsigned ret=GarbleAX(); + return CALC(num, ^); +} + +void Test(unsigned (*F)(unsigned), unsigned Num, unsigned Ref) +{ + unsigned Res; + ++TestCount; + Res = F(Num); + if (Res != Ref) { + printf("Test %u failed: got %04X, expected %04X\n", TestCount, Res, Ref); + ++Failures; + } +} + +int main(void) +{ + Test(WrongAdd, 0x4715, CALC(0x4715, +)); + Test(WrongAnd, 0x4715, CALC(0x4715, &)); + Test(WrongOr, 0x4715, CALC(0x4715, |)); + Test(WrongXor, 0x4715, CALC(0x4715, ^)); + printf("Failures: %u\n", Failures); + return Failures; +} From 38f54875d053e62e3bab991facb8e13cdbc1e258 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 7 Sep 2024 17:06:45 +0200 Subject: [PATCH 242/707] Add files via upload --- libsrc/atmos/waitvsync.s | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 libsrc/atmos/waitvsync.s diff --git a/libsrc/atmos/waitvsync.s b/libsrc/atmos/waitvsync.s new file mode 100644 index 000000000..6113f3da2 --- /dev/null +++ b/libsrc/atmos/waitvsync.s @@ -0,0 +1,18 @@ +; +; Written by Stefan Haubenthal <polluks@sdf.org>, requires VSync hack +; +; void waitvsync (void); +; + + .export _waitvsync + + .include "atmos.inc" + +.proc _waitvsync + +wait: lda VIA::PRA2 + and #%00010000 ; CB1 + bne wait + rts + +.endproc From 033fd9e0dcc891c00df01dba611b1fffb5fb5591 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 7 Sep 2024 17:19:21 +0200 Subject: [PATCH 243/707] Update funcref.sgml --- doc/funcref.sgml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 130646538..ea2350aad 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -155,6 +155,7 @@ function. <item><ref id="atmos_tick" name="atmos_tick"> <item><ref id="atmos_tock" name="atmos_tock"> <item><ref id="atmos_zap" name="atmos_zap"> +<item><ref id="waitvsync" name="waitvsync"> </itemize> @@ -8358,6 +8359,7 @@ only in the presence of a prototype. <descrip> <tag/Function/Wait until the start of the next video frame. <tag/Header/<tt/ +<ref id="atmos.h" name="atmos.h">, <ref id="cbm.h" name="cbm.h">, <ref id="gamate.h" name="gamate.h">, <ref id="nes.h" name="nes.h">, @@ -8365,6 +8367,7 @@ only in the presence of a prototype. <tag/Declaration/<tt/void waitvsync (void);/ <tag/Description/Wait for vertical sync, to reduce flickering. <tag/Availability/Platforms served by the headers above +(Atmos requires the VSync hack) <tag/Example/None. </descrip> </quote> From f430341d5d46bd11a006b9fdb731d56c746394c7 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 7 Sep 2024 17:23:17 +0200 Subject: [PATCH 244/707] Update atmos.h --- include/atmos.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/atmos.h b/include/atmos.h index 38d423c46..460a0010f 100644 --- a/include/atmos.h +++ b/include/atmos.h @@ -169,6 +169,9 @@ void atmos_tock (void); void atmos_zap (void); /* Raygun sound effect */ +void waitvsync (void); +/* Wait for start of next frame */ + /* End of atmos.h */ From ab4cdafacb66f226afcd1c0ee77b49c670130c79 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 7 Sep 2024 18:07:35 +0200 Subject: [PATCH 245/707] Update atari7800.h --- include/atari7800.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/atari7800.h b/include/atari7800.h index 3cbeedb8b..b289bb41e 100644 --- a/include/atari7800.h +++ b/include/atari7800.h @@ -52,7 +52,7 @@ /* No support for dynamically loadable drivers */ #define DYN_DRV 0 -extern unsigned char get_tv(void); /* get TV system */ +unsigned char get_tv(void); /* get TV system */ #include <_tia.h> #define TIA (*(struct __tia*)0x0000) From c9fa9f00023a1ee6c26e66e5b4ce81b54d465e96 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 7 Sep 2024 18:08:18 +0200 Subject: [PATCH 246/707] Update atari5200.h --- include/atari5200.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/atari5200.h b/include/atari5200.h index ff176c15b..9a0399d0e 100644 --- a/include/atari5200.h +++ b/include/atari5200.h @@ -94,7 +94,7 @@ extern void atr5200std_joy[]; /* referred to by joy_static_stddrv[] */ #define _bordercolor(color) 0 /* wait for start of next frame */ -extern void waitvsync (void); +void waitvsync (void); /* end of atari5200.h */ #endif From 44aa5dca910db8bd96ef09d57d424707f582602f Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 7 Sep 2024 18:12:37 +0200 Subject: [PATCH 247/707] Update atari.h --- include/atari.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/atari.h b/include/atari.h index 04cacab33..0af109264 100644 --- a/include/atari.h +++ b/include/atari.h @@ -220,17 +220,17 @@ /* Color register functions */ /*****************************************************************************/ -extern void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminance); -extern void __fastcall__ _setcolor_low (unsigned char color_reg, unsigned char color_value); -extern unsigned char __fastcall__ _getcolor (unsigned char color_reg); +void __fastcall__ _setcolor (unsigned char color_reg, unsigned char hue, unsigned char luminance); +void __fastcall__ _setcolor_low (unsigned char color_reg, unsigned char color_value); +unsigned char __fastcall__ _getcolor (unsigned char color_reg); /*****************************************************************************/ /* Other screen functions */ /*****************************************************************************/ -extern void waitvsync (void); /* wait for start of next frame */ -extern int __fastcall__ _graphics (unsigned char mode); /* mode value same as in BASIC */ -extern void __fastcall__ _scroll (signed char numlines); +void waitvsync (void); /* wait for start of next frame */ +int __fastcall__ _graphics (unsigned char mode); /* mode value same as in BASIC */ +void __fastcall__ _scroll (signed char numlines); /* numlines > 0 scrolls up */ /* numlines < 0 scrolls down */ @@ -239,18 +239,18 @@ extern void __fastcall__ _scroll (signed char numlines); /* Sound function */ /*****************************************************************************/ -extern void __fastcall__ _sound (unsigned char voice, unsigned char frequency, unsigned char distortion, unsigned char volume); +void __fastcall__ _sound (unsigned char voice, unsigned char frequency, unsigned char distortion, unsigned char volume); /*****************************************************************************/ /* Misc. functions */ /*****************************************************************************/ -extern unsigned char get_ostype(void); /* get ROM version */ -extern unsigned char get_tv(void); /* get TV system */ -extern void _save_vecs(void); /* save system vectors */ -extern void _rest_vecs(void); /* restore system vectors */ -extern char *_getdefdev(void); /* get default floppy device */ -extern unsigned char _is_cmdline_dos(void); /* does DOS support command lines */ +unsigned char get_ostype(void); /* get ROM version */ +unsigned char get_tv(void); /* get TV system */ +void _save_vecs(void); /* save system vectors */ +void _rest_vecs(void); /* restore system vectors */ +char *_getdefdev(void); /* get default floppy device */ +unsigned char _is_cmdline_dos(void); /* does DOS support command lines */ /*****************************************************************************/ From b355620939a9720da91cb90408439ff90868ab84 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 7 Sep 2024 18:49:53 +0200 Subject: [PATCH 248/707] Optimise waitvsync.s --- libsrc/atmos/waitvsync.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/atmos/waitvsync.s b/libsrc/atmos/waitvsync.s index 6113f3da2..15abe1926 100644 --- a/libsrc/atmos/waitvsync.s +++ b/libsrc/atmos/waitvsync.s @@ -10,8 +10,8 @@ .proc _waitvsync -wait: lda VIA::PRA2 - and #%00010000 ; CB1 + lda #%00010000 +wait: and VIA::PRA2 ; CB1 bne wait rts From be5a9f92ec814868e4eaa432159dc1a6ffe54b2a Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 7 Sep 2024 18:51:20 +0200 Subject: [PATCH 249/707] oops --- libsrc/atmos/waitvsync.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/atmos/waitvsync.s b/libsrc/atmos/waitvsync.s index 15abe1926..85e50a795 100644 --- a/libsrc/atmos/waitvsync.s +++ b/libsrc/atmos/waitvsync.s @@ -10,8 +10,8 @@ .proc _waitvsync - lda #%00010000 -wait: and VIA::PRA2 ; CB1 + lda #%00010000 ; CB1 +wait: and VIA::PRA2 bne wait rts From f5e434c6c815d4816813cafdb817c235946c29cf Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 7 Sep 2024 19:14:59 +0200 Subject: [PATCH 250/707] Update waitvsync.s --- libsrc/pet/waitvsync.s | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libsrc/pet/waitvsync.s b/libsrc/pet/waitvsync.s index 39b562e43..d74f76c9f 100644 --- a/libsrc/pet/waitvsync.s +++ b/libsrc/pet/waitvsync.s @@ -9,8 +9,7 @@ .include "pet.inc" _waitvsync: -@l1: - lda VIA_PB - and #%00100000 - bne @l1 + lda #%00100000 +: and VIA_PB + bne :- rts From 461554e616e41252ffef3e1b337ed2d993613e1a Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Sat, 7 Sep 2024 19:17:00 +0200 Subject: [PATCH 251/707] Update waitvsync.s --- libsrc/c128/waitvsync.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/c128/waitvsync.s b/libsrc/c128/waitvsync.s index e4bbbf7c9..573f574a7 100644 --- a/libsrc/c128/waitvsync.s +++ b/libsrc/c128/waitvsync.s @@ -23,8 +23,8 @@ _waitvsync: @c80: ;FIXME: do we have to switch banks? + lda #$20 @l3: - lda VDC_INDEX - and #$20 + and VDC_INDEX beq @l3 rts From 55d3a6ea39c3275958d2ac9a666b7bf8ffeb6ed7 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Wed, 4 Sep 2024 22:52:52 +0200 Subject: [PATCH 252/707] Optimize stpcpy's size and speed --- libsrc/common/stpcpy.c | 7 ------- libsrc/common/stpcpy.s | 22 ++++++++++++++++++++++ libsrc/common/strcpy.s | 7 +++++-- test/val/stpcpy.c | 13 +++++++++++-- 4 files changed, 38 insertions(+), 11 deletions(-) delete mode 100644 libsrc/common/stpcpy.c create mode 100644 libsrc/common/stpcpy.s diff --git a/libsrc/common/stpcpy.c b/libsrc/common/stpcpy.c deleted file mode 100644 index 12af47f2f..000000000 --- a/libsrc/common/stpcpy.c +++ /dev/null @@ -1,7 +0,0 @@ -#include <string.h> - -char * __fastcall__ stpcpy (char * dst, const char * src) -{ - strcpy (dst, src); - return dst + strlen (src); -} diff --git a/libsrc/common/stpcpy.s b/libsrc/common/stpcpy.s new file mode 100644 index 000000000..c8a10db94 --- /dev/null +++ b/libsrc/common/stpcpy.s @@ -0,0 +1,22 @@ +; +; Colin Leroy-Mira, 4 Sept. 2024 +; +; char* stpcpy (char* dest, const char* src); +; + + .export _stpcpy + .import _strcpy + + .importzp tmp1, ptr2 + +_stpcpy: + jsr _strcpy + + ldx ptr2+1 ; Load dest pointer's last high byte + tya ; Get the last offset strcpy wrote to + + clc + adc ptr2 ; Add to low byte value + bcc :+ + inx +: rts ; Return pointer to dest's terminator diff --git a/libsrc/common/strcpy.s b/libsrc/common/strcpy.s index 77b39fe76..9a100f540 100644 --- a/libsrc/common/strcpy.s +++ b/libsrc/common/strcpy.s @@ -25,6 +25,9 @@ L1: lda (ptr1),y inc ptr2+1 bne L1 -L9: lda ptr2 ; X still contains high byte - rts +L9: lda ptr2 ; X still contains dest's original high byte + ; On exit, we want AX to be dest (as this is what strcpy returns). + ; We also want (ptr2),y to still point to dest's terminator, as this + ; is used by stpcpy(). + rts diff --git a/test/val/stpcpy.c b/test/val/stpcpy.c index 8bdbfb926..1cc6458ed 100644 --- a/test/val/stpcpy.c +++ b/test/val/stpcpy.c @@ -8,10 +8,12 @@ #define STR_SHORT "Hello, World!" #define STR_LONG "This is a longer test string for stpcpy." +char dest[512]; +char multi_page[300]; + int main () { - char dest[50]; const char *src_empty; const char *src_short; const char *src_long; @@ -38,7 +40,14 @@ main () assert(end == &dest[sizeof (STR_LONG) - 1]); printf ("Test 3 passed.\n"); + memset(multi_page, 'a', sizeof(multi_page)-1); + multi_page[sizeof(multi_page)-1] = '\0'; + end = stpcpy (dest, multi_page); + assert(!strcmp (dest, multi_page)); + assert(!*end); + assert(end == &dest[sizeof (multi_page) - 1]); + printf ("Test 4 passed.\n"); + printf ("All tests passed.\n"); return EXIT_SUCCESS; } - From 838c8b48b744460f5cf1ee80164029d6c572878d Mon Sep 17 00:00:00 2001 From: coronax <coronax@gmail.com> Date: Sat, 7 Sep 2024 22:16:22 -0500 Subject: [PATCH 253/707] Set the clock id to CLOCK_REALTIME when calling clock_gettime. Previously, time() allocated stack space for the clock id argument, but didn't actually set a value. --- asminc/time.inc | 6 ++++++ libsrc/common/time.s | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/asminc/time.inc b/asminc/time.inc index 6064b4ba3..7c1ab3177 100644 --- a/asminc/time.inc +++ b/asminc/time.inc @@ -66,3 +66,9 @@ .global _clock_settime .global _localtime .global _mktime + + +;------------------------------------------------------------------------------ +; Constants + +CLOCK_REALTIME = 0 diff --git a/libsrc/common/time.s b/libsrc/common/time.s index 40b470f5b..36fd36323 100644 --- a/libsrc/common/time.s +++ b/libsrc/common/time.s @@ -6,7 +6,7 @@ .export _time - .import decsp1, ldeaxi + .import pusha, ldeaxi .importzp ptr1, sreg, tmp1, tmp2 .include "time.inc" @@ -22,7 +22,8 @@ ; Get the time (machine dependent) - jsr decsp1 + lda #CLOCK_REALTIME + jsr pusha lda #<time ldx #>time jsr _clock_gettime From 3c5269dede70a6dbe3ec40952595dd8c82d07a5e Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 8 Sep 2024 09:11:47 +0200 Subject: [PATCH 254/707] Warn for braces around a pointer initializer. --- src/cc65/initdata.c | 7 +++++++ test/ref/bug2134.c | 2 ++ test/ref/bug2134.cref | 2 ++ 3 files changed, 11 insertions(+) create mode 100644 test/ref/bug2134.c create mode 100644 test/ref/bug2134.cref diff --git a/src/cc65/initdata.c b/src/cc65/initdata.c index 82cebefc2..addc7421b 100644 --- a/src/cc65/initdata.c +++ b/src/cc65/initdata.c @@ -302,6 +302,13 @@ static unsigned ParsePointerInit (const Type* T) /* Optional opening brace */ unsigned BraceCount = OpeningCurlyBraces (0); + /* We warn if an initializer for a scalar contains braces, because this is + ** quite unusual and often a sign for some problem in the input. + */ + if (BraceCount > 0) { + Warning ("Braces around scalar initializer"); + } + /* Expression */ ExprDesc ED = NoCodeConstExpr (hie1); TypeConversion (&ED, T); diff --git a/test/ref/bug2134.c b/test/ref/bug2134.c new file mode 100644 index 000000000..9e95e1daa --- /dev/null +++ b/test/ref/bug2134.c @@ -0,0 +1,2 @@ +int i = { 0 }; +char* p = { 0 }; diff --git a/test/ref/bug2134.cref b/test/ref/bug2134.cref new file mode 100644 index 000000000..72bbbad04 --- /dev/null +++ b/test/ref/bug2134.cref @@ -0,0 +1,2 @@ +bug2134.c:1: Warning: Braces around scalar initializer +bug2134.c:2: Warning: Braces around scalar initializer From d825a40add4ceb23c3b09840b6f0fe29ebe93b3a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 8 Sep 2024 09:36:40 +0200 Subject: [PATCH 255/707] The test needs a main() function. --- test/ref/bug2134.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/ref/bug2134.c b/test/ref/bug2134.c index 9e95e1daa..9dd1e5c55 100644 --- a/test/ref/bug2134.c +++ b/test/ref/bug2134.c @@ -1,2 +1,3 @@ int i = { 0 }; char* p = { 0 }; +int main() { return 0; } From aff82483411bc8c505ef024ad18778fc902fdbe3 Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Sun, 8 Sep 2024 17:08:40 +0200 Subject: [PATCH 256/707] add comment on function prototypes --- Contributing.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Contributing.md b/Contributing.md index 5b53e0467..10d687424 100644 --- a/Contributing.md +++ b/Contributing.md @@ -204,6 +204,18 @@ char* nextLine (FILE* f); ### Header files +* All Headers should start with a copyright/license banner +* Function prototypes must be a single line, not contain the redundant + "extern" keyword, and followed by a brief comment that explains what + the function does, and separated from the next prototype by a blank + line: + +~~~C +void __fastcall__ cclear (unsigned char length); +/* Clear part of a line (write length spaces). */ + +~~~ + Headers that belong to the standard library (libc) must conform with the C standard. That means: From 6113dc5995ed2db57fb38d31cb18bbdf8e4a38ce Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 10 Sep 2024 08:12:31 +0200 Subject: [PATCH 257/707] Removed casts from stdint.h. Added a test. Fixes #2505. --- include/stdint.h | 76 ++++++++++----------- test/val/stdint.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+), 38 deletions(-) create mode 100644 test/val/stdint.c diff --git a/include/stdint.h b/include/stdint.h index 5d6f04769..6d51565e0 100644 --- a/include/stdint.h +++ b/include/stdint.h @@ -52,15 +52,15 @@ typedef unsigned char uint8_t; typedef unsigned uint16_t; typedef unsigned long uint32_t; -#define INT8_MIN ((int8_t) 0x80) -#define INT8_MAX ((int8_t) 0x7F) -#define INT16_MIN ((int16_t) 0x8000) -#define INT16_MAX ((int16_t) 0x7FFF) -#define INT32_MIN ((int32_t) 0x80000000) -#define INT32_MAX ((int32_t) 0x7FFFFFFF) -#define UINT8_MAX ((uint8_t) 0xFF) -#define UINT16_MAX ((uint16_t) 0xFFFF) -#define UINT32_MAX ((uint32_t) 0xFFFFFFFF) +#define INT8_MIN -128 +#define INT8_MAX 127 +#define INT16_MIN (-32767 - 1) +#define INT16_MAX 32767 +#define INT32_MIN (-2147483647L - 1L) +#define INT32_MAX 2147483647L +#define UINT8_MAX 255 +#define UINT16_MAX 65535U +#define UINT32_MAX 4294967295UL /* Minimum-width integer types */ typedef signed char int_least8_t; @@ -70,15 +70,15 @@ typedef unsigned char uint_least8_t; typedef unsigned uint_least16_t; typedef unsigned long uint_least32_t; -#define INT_LEAST8_MIN ((int_least8_t) 0x80) -#define INT_LEAST8_MAX ((int_least8_t) 0x7F) -#define INT_LEAST16_MIN ((int_least16_t) 0x8000) -#define INT_LEAST16_MAX ((int_least16_t) 0x7FFF) -#define INT_LEAST32_MIN ((int_least32_t) 0x80000000) -#define INT_LEAST32_MAX ((int_least32_t) 0x7FFFFFFF) -#define UINT_LEAST8_MAX ((uint_least8_t) 0xFF) -#define UINT_LEAST16_MAX ((uint_least16_t) 0xFFFF) -#define UINT_LEAST32_MAX ((uint_least32_t) 0xFFFFFFFF) +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX /* Fastest minimum-width integer types */ typedef signed char int_fast8_t; @@ -88,40 +88,40 @@ typedef unsigned char uint_fast8_t; typedef unsigned uint_fast16_t; typedef unsigned long uint_fast32_t; -#define INT_FAST8_MIN ((int_fast8_t) 0x80) -#define INT_FAST8_MAX ((int_fast8_t) 0x7F) -#define INT_FAST16_MIN ((int_fast16_t) 0x8000) -#define INT_FAST16_MAX ((int_fast16_t) 0x7FFF) -#define INT_FAST32_MIN ((int_fast32_t) 0x80000000) -#define INT_FAST32_MAX ((int_fast32_t) 0x7FFFFFFF) -#define UINT_FAST8_MAX ((uint_fast8_t) 0xFF) -#define UINT_FAST16_MAX ((uint_fast16_t) 0xFFFF) -#define UINT_FAST32_MAX ((uint_fast32_t) 0xFFFFFFFF) +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX /* Integer types capable of holding object pointers */ typedef int intptr_t; typedef unsigned uintptr_t; -#define INTPTR_MIN ((intptr_t)0x8000) -#define INTPTR_MAX ((intptr_t)0x7FFF) -#define UINTPTR_MAX ((uintptr_t) 0xFFFF) +#define INTPTR_MIN INT16_MIN +#define INTPTR_MAX INT16_MAX +#define UINTPTR_MAX UINT16_MAX /* Greatest width integer types */ typedef long intmax_t; typedef unsigned long uintmax_t; -#define INTMAX_MIN ((intmax_t) 0x80000000) -#define INTMAX_MAX ((intmax_t) 0x7FFFFFFF) -#define UINTMAX_MAX ((uintmax_t) 0xFFFFFFFF) +#define INTMAX_MIN INT32_MIN +#define INTMAX_MAX INT32_MAX +#define UINTMAX_MAX UINT32_MAX /* Limits of other integer types */ -#define PTRDIFF_MIN ((int) 0x8000) -#define PTRDIFF_MAX ((int) 0x7FFF) +#define PTRDIFF_MIN INT16_MIN +#define PTRDIFF_MAX INT16_MAX -#define SIG_ATOMIC_MIN ((unsigned char) 0x00) -#define SIG_ATOMIC_MAX ((unsigned char) 0xFF) +#define SIG_ATOMIC_MIN 0 +#define SIG_ATOMIC_MAX UINT8_MAX -#define SIZE_MAX 0xFFFF +#define SIZE_MAX UINT16_MAX /* Macros for minimum width integer constants */ #define INT8_C(c) c diff --git a/test/val/stdint.c b/test/val/stdint.c new file mode 100644 index 000000000..29b48346a --- /dev/null +++ b/test/val/stdint.c @@ -0,0 +1,167 @@ +/* Test definitions from stdint.h */ + +#include <stdio.h> +#include <stdint.h> +#include <stddef.h> +#include <stdlib.h> +#include <limits.h> +#include <signal.h> + +/* All macros from stdint.h must be evaluatable by the preprocessor */ +#if INT8_MIN +#endif +#if INT8_MAX +#endif +#if INT16_MIN +#endif +#if INT16_MAX +#endif +#if INT32_MIN +#endif +#if INT32_MAX +#endif +#if UINT8_MAX +#endif +#if UINT16_MAX +#endif +#if UINT32_MAX +#endif +#if INT_LEAST8_MIN +#endif +#if INT_LEAST8_MAX +#endif +#if INT_LEAST16_MIN +#endif +#if INT_LEAST16_MAX +#endif +#if INT_LEAST32_MIN +#endif +#if INT_LEAST32_MAX +#endif +#if UINT_LEAST8_MAX +#endif +#if UINT_LEAST16_MAX +#endif +#if UINT_LEAST32_MAX +#endif +#if INT_FAST8_MIN +#endif +#if INT_FAST8_MAX +#endif +#if INT_FAST16_MIN +#endif +#if INT_FAST16_MAX +#endif +#if INT_FAST32_MIN +#endif +#if INT_FAST32_MAX +#endif +#if UINT_FAST8_MAX +#endif +#if UINT_FAST16_MAX +#endif +#if UINT_FAST32_MAX +#endif +#if INTPTR_MIN +#endif +#if INTPTR_MAX +#endif +#if UINTPTR_MAX +#endif +#if INTMAX_MIN +#endif +#if INTMAX_MAX +#endif +#if UINTMAX_MAX +#endif +#if PTRDIFF_MIN +#endif +#if PTRDIFF_MAX +#endif +#if SIG_ATOMIC_MIN +#endif +#if SIG_ATOMIC_MAX +#endif +#if SIZE_MAX +#endif + +#define SMIN(type) ((type)(1L << (sizeof(type) * CHAR_BIT - 1))) +#define SMAX(type) ((type)(~SMIN(type))) +#define UMAX(type) ((type)(~(type)0)) + +#define SMIN_CHECK(type, val) \ + if (SMIN(type) != val) { \ + ++failures; \ + printf("Mismatch for %s, minimum (%ld) is not %s (%ld)\n", \ + #type, (long)SMIN(type), #val, (long)val); \ + } +#define SMAX_CHECK(type, val) \ + if (SMAX(type) != val) { \ + ++failures; \ + printf("Mismatch for %s, maximum (%ld) is not %s (%ld)\n", \ + #type, (long)SMAX(type), #val, (long)val); \ + } +#define UMAX_CHECK(type, val) \ + if (UMAX(type) != val) { \ + ++failures; \ + printf("Mismatch for %s, maximum (%lu) is not %s (%lu)\n", \ + #type, (unsigned long)UMAX(type), #val, \ + (unsigned long)val); \ + } + +static unsigned failures = 0; + +int main() +{ + SMIN_CHECK(int8_t, INT8_MIN); + SMAX_CHECK(int8_t, INT8_MAX); + SMIN_CHECK(int16_t, INT16_MIN); + SMAX_CHECK(int16_t, INT16_MAX); + SMIN_CHECK(int32_t, INT32_MIN); + SMAX_CHECK(int32_t, INT32_MAX); + UMAX_CHECK(uint8_t, UINT8_MAX); + UMAX_CHECK(uint16_t, UINT16_MAX); + UMAX_CHECK(uint32_t, UINT32_MAX); + + SMIN_CHECK(int_least8_t, INT_LEAST8_MIN); + SMAX_CHECK(int_least8_t, INT_LEAST8_MAX); + SMIN_CHECK(int_least16_t, INT_LEAST16_MIN); + SMAX_CHECK(int_least16_t, INT_LEAST16_MAX); + SMIN_CHECK(int_least32_t, INT_LEAST32_MIN); + SMAX_CHECK(int_least32_t, INT_LEAST32_MAX); + UMAX_CHECK(uint_least8_t, UINT_LEAST8_MAX); + UMAX_CHECK(uint_least16_t, UINT_LEAST16_MAX); + UMAX_CHECK(uint_least32_t, UINT_LEAST32_MAX); + + SMIN_CHECK(int_fast8_t, INT_FAST8_MIN); + SMAX_CHECK(int_fast8_t, INT_FAST8_MAX); + SMIN_CHECK(int_fast16_t, INT_FAST16_MIN); + SMAX_CHECK(int_fast16_t, INT_FAST16_MAX); + SMIN_CHECK(int_fast32_t, INT_FAST32_MIN); + SMAX_CHECK(int_fast32_t, INT_FAST32_MAX); + UMAX_CHECK(uint_fast8_t, UINT_FAST8_MAX); + UMAX_CHECK(uint_fast16_t, UINT_FAST16_MAX); + UMAX_CHECK(uint_fast32_t, UINT_FAST32_MAX); + + SMIN_CHECK(intptr_t, INTPTR_MIN); + SMAX_CHECK(intptr_t, INTPTR_MAX); + UMAX_CHECK(uintptr_t, UINTPTR_MAX); + + SMIN_CHECK(intmax_t, INTMAX_MIN); + SMAX_CHECK(intmax_t, INTMAX_MAX); + UMAX_CHECK(uintmax_t, UINTMAX_MAX); + + SMIN_CHECK(ptrdiff_t, PTRDIFF_MIN); + SMAX_CHECK(ptrdiff_t, PTRDIFF_MAX); + +#if SIG_ATOMIC_MIN < 0 + SMIN_CHECK(sig_atomic_t, SIG_ATOMIC_MIN); + SMAX_CHECK(sig_atomic_t, SIG_ATOMIC_MAX); +#else + UMAX_CHECK(sig_atomic_t, SIG_ATOMIC_MAX); +#endif + + UMAX_CHECK(size_t, SIZE_MAX); + + return failures; +} From 2f6f5f0da142f2a21f30449fe6de78d24e2987ae Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:20:01 +0200 Subject: [PATCH 258/707] Fix problem with #line when there is no whitespace between line number and filename. y --- src/cc65/preproc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 1ee810060..96db1d8fe 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -2913,7 +2913,7 @@ static unsigned GetLineDirectiveNum (void) /* Ensure the buffer is terminated with a '\0' */ SB_Terminate (&Buf); - if (SkipWhitespace (0) != 0 || CurC == '\0') { + if (SB_GetLen (&Buf) > 0) { const char* Str = SB_GetConstBuf (&Buf); if (Str[0] == '\0') { PPWarning ("#line directive interprets number as decimal, not octal"); @@ -2929,9 +2929,10 @@ static unsigned GetLineDirectiveNum (void) } } } else { - PPError ("#line directive requires a simple decimal digit sequence"); + PPError ("#line directive requires a decimal digit sequence"); ClearLine (); } + SkipWhitespace (0); /* Done with the buffer */ SB_Done (&Buf); From 70ca6d420063c0fe0b9abb731232ca533a1d958e Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:21:19 +0200 Subject: [PATCH 259/707] Fixed a standard noncompliance: In C99 and above there must be whitespace between a name of an object like macro and its replacement list. --- src/cc65/preproc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 96db1d8fe..d033520b8 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -2640,6 +2640,18 @@ static void DoDefine (void) goto Error_Handler; } NextChar (); + + } else { + + /* Object like macro. Check ISO/IEC 9899:1999 (E) 6.10.3p3: + ** "There shall be white-space between the identifier and the + ** replacement list in the definition of an object-like macro." + ** Note: C89 doesn't have this constraint. + */ + if (Std == STD_C99 && !IsSpace (CurC)) { + PPWarning ("ISO C99 requires whitespace after the macro name"); + } + } /* Remove whitespace and comments from the line, store the preprocessed From 36a810cdb23b903ca4f3771a94b3b9a2489e634a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 12 Sep 2024 09:10:37 +0200 Subject: [PATCH 260/707] Make lastline.sh ignore empty files. Fixes #2514. --- .github/checks/lastline.sh | 2 +- .gitignore | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/checks/lastline.sh b/.github/checks/lastline.sh index d80d2fb57..d243a01e1 100755 --- a/.github/checks/lastline.sh +++ b/.github/checks/lastline.sh @@ -9,7 +9,7 @@ nl=' ' nl=$'\n' r1="${nl}$" -FILES=`find $CHECK_PATH -type f \( -name \*.inc -o -name Makefile -o -name \*.cfg -o -name \*.\[chs\] -o -name \*.mac -o -name \*.asm -o -name \*.sgml \) -print | while read f; do +FILES=`find $CHECK_PATH -type f -size +0 \( -name \*.inc -o -name Makefile -o -name \*.cfg -o -name \*.\[chs\] -o -name \*.mac -o -name \*.asm -o -name \*.sgml \) -print | while read f; do t=$(tail -c2 $f; printf x) [[ ${t%x} =~ $r1 ]] || echo "$f" done` diff --git a/.gitignore b/.gitignore index 9112484b8..772a2f204 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,4 @@ /cc65.zip /util/atari/*.exe /util/gamate/*.exe - +targettest/cbm/cbmread.prg From efa2020d932e645de0fa21af4c36db16654ff0b4 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 12 Sep 2024 09:14:57 +0200 Subject: [PATCH 261/707] Improved/fixed the time() function: - When the underlying clock_gettime function returned an error, the value returned via *timep was wrong. - Reduced code size by 7 bytes. - Don't suck in ldeaxi. --- libsrc/common/time.s | 51 ++++++++++++++++-------------------- test/val/time-test2.c | 61 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 28 deletions(-) create mode 100644 test/val/time-test2.c diff --git a/libsrc/common/time.s b/libsrc/common/time.s index 36fd36323..4092e71c6 100644 --- a/libsrc/common/time.s +++ b/libsrc/common/time.s @@ -22,55 +22,50 @@ ; Get the time (machine dependent) + .assert timespec::tv_sec = 0, error lda #CLOCK_REALTIME jsr pusha lda #<time ldx #>time jsr _clock_gettime - sta tmp2 - lda #<time - ldx #>time - .assert timespec::tv_sec = 0, error - jsr ldeaxi - sta tmp1 ; Save low byte of result + +; _clock_gettime returns 0 on success and -1 on error. Check that. + + inx ; Did _clock_gettime return -1? + bne @L2 ; Jump if not + +; We had an error so invalidate time. A contains $FF. + + ldy #3 +@L1: sta time,y + dey + bpl @L1 ; Restore timep and check if it is NULL - pla +@L2: pla sta ptr1+1 pla sta ptr1 ; Restore timep ora ptr1+1 ; timep == 0? - beq @L1 + beq @L4 ; timep is not NULL, store the result there ldy #3 - lda sreg+1 +@L3: lda time,y sta (ptr1),y dey - lda sreg - sta (ptr1),y - dey - txa - sta (ptr1),y - dey - lda tmp1 - sta (ptr1),y + bpl @L3 -; If the result is != 0, return -1 +; Load the final result. -@L1: lda tmp2 - beq @L2 - - tax - sta sreg +@L4: lda time+3 sta sreg+1 - rts - -; Reload the low byte of the result and return - -@L2: lda tmp1 + lda time+2 + sta sreg + ldx time+1 + lda time rts .endproc diff --git a/test/val/time-test2.c b/test/val/time-test2.c new file mode 100644 index 000000000..725bbd0e6 --- /dev/null +++ b/test/val/time-test2.c @@ -0,0 +1,61 @@ +/* Another test for time() */ + +#include <stdio.h> +#include <time.h> + +static int failures = 0; +#define INV_TIME ((time_t)-1) +#define TEST_TIME ((time_t)0x78AB1234) + +/* We supply our own clock_gettime function so we can control the values +** supplied to time() internally. +*/ +static time_t timeval; +static int timeres; +int __fastcall__ clock_gettime (clockid_t, struct timespec *tp) +{ + /* Don't touch tp in case of an error */ + if (timeres != -1) { + tp->tv_sec = timeval; + tp->tv_nsec = 0; + } + return timeres; +} + +int main() +{ + time_t res, pres; + + /* First test: Force time() to return an error. Check that both, the + ** returned value and the value passed via pointer are (time_t)-1. + */ + timeval = 42; + timeres = -1; + res = time(&pres); + if (res != INV_TIME || pres != INV_TIME) { + printf("Error in test 1\n"); + ++failures; + } + + /* Second test: Return a valid value and check both results */ + timeval = TEST_TIME; + timeres = 0; + res = time(&pres); + if (res != TEST_TIME || pres != TEST_TIME) { + printf("Error in test 2\n"); + ++failures; + } + + /* Third test: Return no error but an invalid value and check both + ** results + */ + timeval = INV_TIME; + timeres = 0; + res = time(&pres); + if (res != INV_TIME || pres != INV_TIME) { + printf("Error in test 3\n"); + ++failures; + } + + return failures; +} From 3f83cf81f3c62f91eeed4097f01a91fa020c2c02 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Fri, 13 Sep 2024 19:02:13 +0200 Subject: [PATCH 262/707] Revert the change to .gitignore so git status doesn't report a clean status as before. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 772a2f204..9112484b8 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,4 @@ /cc65.zip /util/atari/*.exe /util/gamate/*.exe -targettest/cbm/cbmread.prg + From 001fa05d48bddc68b8369bbb460e11e333a56f79 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Fri, 13 Sep 2024 19:18:31 +0200 Subject: [PATCH 263/707] Move the test to the test/standard directory. --- test/{val => standard}/stdint.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{val => standard}/stdint.c (100%) diff --git a/test/val/stdint.c b/test/standard/stdint.c similarity index 100% rename from test/val/stdint.c rename to test/standard/stdint.c From 6e18e0880adcaf6201e5c805b3905a8b2e0f7924 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 5 Sep 2024 19:59:02 +0200 Subject: [PATCH 264/707] Added/improved the optimizations: * Added a new pass that optimizes PHA/PLA sequences * Added a new pass that optimizes AND/EOR/ORA when an operand is known * Added a run of an existing pass at later stages to remove code that otherwise goes unchanged. * Handle binary operations in OptUnusedLoads in addition to real loads. --- src/cc65/codeent.c | 18 +++++ src/cc65/codeopt.c | 8 +++ src/cc65/coptind.c | 110 ++++++++++++++++++++++++++-- src/cc65/coptind.h | 7 +- src/cc65/coptmisc.c | 172 ++++++++++++++++++++++++++++++++++++++++++++ src/cc65/coptmisc.h | 6 ++ 6 files changed, 315 insertions(+), 6 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 928815934..a870ee981 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -2445,6 +2445,24 @@ static char* RegContentDesc (const RegContents* RC, char* Buf) sprintf (B, "Y:%02X ", RC->RegY); } B += 5; + if (RegValIsUnknown (RC->Ptr1Lo)) { + strcpy (B, "P1L:XX "); + } else { + sprintf (B, "P1L:%02X ", RC->Ptr1Lo); + } + B += 7; + if (RegValIsUnknown (RC->Ptr1Hi)) { + strcpy (B, "P1H:XX "); + } else { + sprintf (B, "P1H:%02X ", RC->Ptr1Hi); + } + B += 7; + if (RegValIsUnknown (RC->Tmp1)) { + strcpy (B, "T1:XX "); + } else { + sprintf (B, "T1:%02X ", RC->Tmp1); + } + B += 6; if (PStatesAreUnknown (RC->PFlags, PSTATE_C)) { strcpy (B, "~"); } else { diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index c9c1592bc..a716ad431 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -117,6 +117,7 @@ static OptFunc DOptBNegAX1 = { OptBNegAX1, "OptBNegAX1", 100, 0, static OptFunc DOptBNegAX2 = { OptBNegAX2, "OptBNegAX2", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptBNegAX3 = { OptBNegAX3, "OptBNegAX3", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptBNegAX4 = { OptBNegAX4, "OptBNegAX4", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptBinOps = { OptBinOps, "OptBinOps", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptBoolCmp = { OptBoolCmp, "OptBoolCmp", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptBoolTrans = { OptBoolTrans, "OptBoolTrans", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptBoolUnary1 = { OptBoolUnary1, "OptBoolUnary1", 40, 0, 0, 0, 0, 0 }; @@ -179,6 +180,7 @@ static OptFunc DOptPush1 = { OptPush1, "OptPush1", 65, 0, static OptFunc DOptPush2 = { OptPush2, "OptPush2", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptPushPop1 = { OptPushPop1, "OptPushPop1", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptPushPop2 = { OptPushPop2, "OptPushPop2", 0, 0, 0, 0, 0, 0 }; +static OptFunc DOptPushPop3 = { OptPushPop3, "OptPushPop3", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptRTS = { OptRTS, "OptRTS", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptRTSJumps1 = { OptRTSJumps1, "OptRTSJumps1", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptRTSJumps2 = { OptRTSJumps2, "OptRTSJumps2", 100, 0, 0, 0, 0, 0 }; @@ -231,6 +233,7 @@ static OptFunc* OptFuncs[] = { &DOptBNegAX2, &DOptBNegAX3, &DOptBNegAX4, + &DOptBinOps, &DOptBoolCmp, &DOptBoolTrans, &DOptBoolUnary1, @@ -292,6 +295,8 @@ static OptFunc* OptFuncs[] = { &DOptPush1, &DOptPush2, &DOptPushPop1, + &DOptPushPop2, + &DOptPushPop3, &DOptRTS, &DOptRTSJumps1, &DOptRTSJumps2, @@ -740,9 +745,11 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptStore5, 1); C += RunOptFunc (S, &DOptPushPop1, 1); C += RunOptFunc (S, &DOptPushPop2, 1); + C += RunOptFunc (S, &DOptPushPop3, 1); C += RunOptFunc (S, &DOptPrecalc, 1); C += RunOptFunc (S, &DOptShiftBack, 1); C += RunOptFunc (S, &DOptSignExtended, 1); + C += RunOptFunc (S, &DOptBinOps, 1); Changes += C; @@ -849,6 +856,7 @@ static unsigned RunOptGroup7 (CodeSeg* S) Changes += RunOptFunc (S, &DOptUnusedStores, 1); Changes += RunOptFunc (S, &DOptJumpTarget1, 5); Changes += RunOptFunc (S, &DOptStore5, 1); + Changes += RunOptFunc (S, &DOptTransfers1, 1); } C = RunOptFunc (S, &DOptSize2, 1); diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 9e9985c10..49855a345 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -151,7 +151,9 @@ static short ZPRegVal (unsigned short Use, const RegContents* RC) unsigned OptUnusedLoads (CodeSeg* S) -/* Remove loads of registers where the value loaded is not used later. */ +/* Remove loads of or operations with registers where the value loaded or +** produced is not used later. +*/ { unsigned Changes = 0; @@ -164,17 +166,24 @@ unsigned OptUnusedLoads (CodeSeg* S) /* Get next entry */ CodeEntry* E = CS_GetEntry (S, I); - /* Check if it's a register load or transfer insn */ - if ((E->Info & (OF_LOAD | OF_XFR | OF_REG_INCDEC)) != 0 && - (N = CS_GetNextEntry (S, I)) != 0 && - !CE_UseLoadFlags (N)) { + /* Check if this is one of the instruction we can operate on */ + int IsOp = (E->Info & (OF_LOAD | OF_XFR | OF_REG_INCDEC)) != 0 || + E->OPC == OP65_AND || + E->OPC == OP65_EOR || + E->OPC == OP65_ORA; + + /* Check for the necessary preconditions */ + if (IsOp && (N = CS_GetNextEntry (S, I)) != 0 && !CE_UseLoadFlags (N)) { /* Check which sort of load or transfer it is */ unsigned R; switch (E->OPC) { + case OP65_AND: case OP65_DEA: + case OP65_EOR: case OP65_INA: case OP65_LDA: + case OP65_ORA: case OP65_TXA: case OP65_TYA: R = REG_A; break; case OP65_DEX: @@ -1342,6 +1351,97 @@ unsigned OptPushPop2 (CodeSeg* S) +unsigned OptPushPop3 (CodeSeg* S) +/* Remove a pha/pla sequence where the contents of A are known */ +{ + unsigned Changes = 0; + unsigned Pha = 0; /* Index of PHA insn */ + unsigned Pla = 0; /* Index of PLA insn */ + CodeEntry* PhaEntry = 0; /* Pointer to PHA */ + + enum { + Searching, + FoundPha, + FoundPla + } State = Searching; + + /* Walk over the entries. Look for a PHA instruction where the contents + ** of A is known followed by a PLA later. + */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Get the input registers */ + const RegInfo* RI = E->RI; + + + const char* Arg; + CodeEntry* X; + switch (State) { + + case Searching: + if (E->OPC == OP65_PHA && RegValIsKnown (RI->In.RegA)) { + /* Found start of sequence */ + Pha = I; + PhaEntry = E; + State = FoundPha; + } + break; + + case FoundPha: + /* Check for several things that abort the sequence: + ** - End of the basic block + ** - Another PHA or any other stack manipulating instruction + ** If we find something that aborts the sequence, start over + ** searching for the next PHA. + */ + if (CE_HasLabel (E)) { + /* Switch back to searching at this instruction */ + State = Searching; + continue; + } + if (E->OPC == OP65_PHA) { + /* Start over at this instruction */ + State = Searching; + continue; + } + if (E->OPC == OP65_PHP || E->OPC == OP65_PLP || E->OPC == OP65_TXS) { + /* Start over at the next instruction */ + State = Searching; + } else if (E->OPC == OP65_PLA) { + /* Switch state. This will also switch to the next insn + ** which is ok. + */ + Pla = I; + State = FoundPla; + } + break; + + case FoundPla: + /* We found the sequence we were looking for. Replace it. */ + Arg = MakeHexArg (PhaEntry->RI->In.RegA); + X = NewCodeEntry (OP65_LDA, AM65_IMM, Arg, 0, E->LI); + CS_InsertEntry (S, X, Pla + 1); + CS_DelEntry (S, Pla); + CS_DelEntry (S, Pha); + ++Changes; + State = Searching; + break; + } + + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} + + + unsigned OptPrecalc (CodeSeg* S) /* Replace immediate operations with the accu where the current contents are ** known by a load of the final value. diff --git a/src/cc65/coptind.h b/src/cc65/coptind.h index 6d39ee1f8..3493543a4 100644 --- a/src/cc65/coptind.h +++ b/src/cc65/coptind.h @@ -50,7 +50,9 @@ unsigned OptUnusedLoads (CodeSeg* S); -/* Remove loads of registers where the value loaded is not used later. */ +/* Remove loads of or operations with registers where the value loaded or +** produced is not used later. +*/ unsigned OptUnusedStores (CodeSeg* S); /* Remove stores into zero page registers that aren't used later */ @@ -91,6 +93,9 @@ unsigned OptPushPop1 (CodeSeg* S); unsigned OptPushPop2 (CodeSeg* S); /* Remove a PHP/PLP sequence were no processor flags changed inside */ +unsigned OptPushPop3 (CodeSeg* S); +/* Remove a pha/pla sequence where the contents of A are known */ + unsigned OptPrecalc (CodeSeg* S); /* Replace immediate operations with the accu where the current contents are ** known by a load of the final value. diff --git a/src/cc65/coptmisc.c b/src/cc65/coptmisc.c index 523fbf17c..332247cf0 100644 --- a/src/cc65/coptmisc.c +++ b/src/cc65/coptmisc.c @@ -733,3 +733,175 @@ unsigned OptLoad2 (CodeSeg* S) /* Return the number of changes made */ return Changes; } + + + +unsigned OptBinOps (CodeSeg* S) +/* Search for an AND/EOR/ORA where the value of A or the operand is known and +** replace it by something simpler. +*/ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Get a pointer to the input registers of the insn */ + const RegContents* In = &E->RI->In; + + /* Check for AND/EOR/ORA and a known value in A */ + int Delete = 0; + CodeEntry* X = 0; + switch (E->OPC) { + + case OP65_AND: + if (In->RegA == 0x00) { + /* Zero AND anything gives zero. The instruction can be + ** replaced by an immediate load of zero. + */ + X = NewCodeEntry (OP65_LDA, AM65_IMM, "$00", 0, E->LI); + } else if (In->RegA == 0xFF) { + /* 0xFF AND anything equals the operand. The instruction + ** can be replaced by a simple load of the operand. + */ + X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, E->LI); + } else if (E->AM == AM65_ZP) { + short Operand = -1; + switch (GetKnownReg (E->Use & REG_ZP, In)) { + case REG_TMP1: Operand = In->Tmp1; break; + case REG_PTR1_LO: Operand = In->Ptr1Lo; break; + case REG_PTR1_HI: Operand = In->Ptr1Hi; break; + case REG_SREG_LO: Operand = In->SRegLo; break; + case REG_SREG_HI: Operand = In->SRegHi; break; + } + if (Operand == 0x00) { + /* AND with zero gives zero. The instruction can be + ** replaced by an immediate load of zero. + */ + X = NewCodeEntry (OP65_LDA, AM65_IMM, "$00", 0, E->LI); + } else if (Operand == 0xFF) { + /* AND with 0xFF is a no-op besides setting the flags. + ** The instruction can be removed if the flags aren't + ** used later. + */ + CodeEntry* N = CS_GetNextEntry (S, I); + if (N && !CE_UseLoadFlags (N)) { + Delete = 1; + } + } else if (Operand >= 0) { + /* The instruction can be replaced by an immediate + ** AND. + */ + const char* Arg = MakeHexArg (Operand); + X = NewCodeEntry (OP65_AND, AM65_IMM, Arg, 0, E->LI); + } + } + break; + + case OP65_EOR: + if (In->RegA == 0x00) { + /* Zero EOR anything equals the operand. The instruction + ** can be replaced by a simple load. + */ + X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, E->LI); + } else if (E->AM == AM65_ZP) { + short Operand = -1; + switch (GetKnownReg (E->Use & REG_ZP, In)) { + case REG_TMP1: Operand = In->Tmp1; break; + case REG_PTR1_LO: Operand = In->Ptr1Lo; break; + case REG_PTR1_HI: Operand = In->Ptr1Hi; break; + case REG_SREG_LO: Operand = In->SRegLo; break; + case REG_SREG_HI: Operand = In->SRegHi; break; + } + if (Operand == 0x00) { + /* EOR with 0x00 is a no-op besides setting the flags. + ** The instruction can be removed if the flags aren't + ** used later. + */ + CodeEntry* N = CS_GetNextEntry (S, I); + if (N && !CE_UseLoadFlags (N)) { + Delete = 1; + } + } else if (Operand >= 0) { + /* The instruction can be replaced by an immediate + ** EOR. + */ + const char* Arg = MakeHexArg (Operand); + X = NewCodeEntry (OP65_EOR, AM65_IMM, Arg, 0, E->LI); + } + } + break; + + case OP65_ORA: + if (In->RegA == 0x00) { + /* ORA with 0x00 is a no-op. The instruction can be + ** replaced by a simple load. + */ + X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, E->LI); + } else if (In->RegA == 0xFF) { + /* ORA with 0xFF gives 0xFF. The instruction can be replaced + ** by an immediate load of 0xFF. + */ + X = NewCodeEntry (OP65_LDA, AM65_IMM, "$FF", 0, E->LI); + } else if (E->AM == AM65_ZP) { + short Operand = -1; + switch (GetKnownReg (E->Use & REG_ZP, In)) { + case REG_TMP1: Operand = In->Tmp1; break; + case REG_PTR1_LO: Operand = In->Ptr1Lo; break; + case REG_PTR1_HI: Operand = In->Ptr1Hi; break; + case REG_SREG_LO: Operand = In->SRegLo; break; + case REG_SREG_HI: Operand = In->SRegHi; break; + } + if (Operand == 0x00) { + /* ORA with 0x00 is a no-op besides setting the flags. + ** The instruction can be removed if the flags aren't + ** used later. + */ + CodeEntry* N = CS_GetNextEntry (S, I); + if (N && !CE_UseLoadFlags (N)) { + Delete = 1; + } + } else if (Operand == 0xFF) { + /* ORA with 0xFF results in 0xFF. The instruction can + ** be replaced by a simple load. + */ + X = NewCodeEntry (OP65_LDA, AM65_IMM, "$FF", 0, E->LI); + } else if (Operand >= 0) { + /* The instruction can be replaced by an immediate + ** ORA. + */ + const char* Arg = MakeHexArg (Operand); + X = NewCodeEntry (OP65_ORA, AM65_IMM, Arg, 0, E->LI); + } + } + break; + + default: + break; + + } + + /* If we must delete the instruction, do that. If we have a replacement + ** entry, place it and remove the old one. + */ + if (X) { + CS_InsertEntry (S, X, I+1); + Delete = 1; + } + if (Delete) { + CS_DelEntry (S, I); + ++Changes; + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} diff --git a/src/cc65/coptmisc.h b/src/cc65/coptmisc.h index 89242351c..418b61e94 100644 --- a/src/cc65/coptmisc.h +++ b/src/cc65/coptmisc.h @@ -107,6 +107,12 @@ unsigned OptLoad1 (CodeSeg* S); unsigned OptLoad2 (CodeSeg* S); /* Replace calls to ldaxysp by inline code */ +unsigned OptBinOps (CodeSeg* S); +/* Search for an AND/EOR/ORA where the value of A or the operand is known and +** replace it by something simpler. +*/ + + /* End of coptmisc.h */ From f43cfd1ad0ad2f668a5808ad000bdc2feea5d6da Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sat, 7 Sep 2024 17:19:13 +0200 Subject: [PATCH 265/707] Fix the check for CPU flags being used after an instruction that gets removed. Previously only the next instruction was checked for usage of the CPU flags but this fails for certain code. --- src/cc65/codeinfo.c | 24 +++++++++++++----------- src/cc65/codeinfo.h | 3 +++ src/cc65/coptind.c | 6 +++--- src/cc65/coptmisc.c | 9 +++------ 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 427bfc52b..435794613 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -560,11 +560,8 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg) *Use = REG_NONE; } - /* Will destroy all registers */ - *Chg = REG_ALL; - - /* and will destroy all processor flags */ - *Chg |= PSTATE_ALL; + /* Will destroy all registers and processor flags */ + *Chg = (REG_ALL | PSTATE_ALL); /* Done */ return FNCLS_GLOBAL; @@ -577,8 +574,7 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg) ** are used mostly in inline assembly anyway. */ *Use = REG_ALL; - *Chg = REG_ALL; - *Chg |= PSTATE_ALL; + *Chg = (REG_ALL | PSTATE_ALL); return FNCLS_NUMERIC; } else { @@ -605,8 +601,7 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg) fprintf (stderr, "No info about internal function '%s'\n", Name); } *Use = REG_ALL; - *Chg = REG_ALL; - *Chg |= PSTATE_ALL; + *Chg = (REG_ALL | PSTATE_ALL); } return FNCLS_BUILTIN; } @@ -615,8 +610,7 @@ fncls_t GetFuncInfo (const char* Name, unsigned int* Use, unsigned int* Chg) ** registers and processor flags are changed */ *Use = REG_EAXY; - *Chg = REG_ALL; - *Chg |= PSTATE_ALL; + *Chg = (REG_ALL | PSTATE_ALL); return FNCLS_UNKNOWN; } @@ -899,6 +893,14 @@ int RegEAXUsed (struct CodeSeg* S, unsigned Index) +int LoadFlagsUsed (struct CodeSeg* S, unsigned Index) +/* Check if one of the flags set by a register load (Z and N) are used. */ +{ + return (GetRegInfo (S, Index, PSTATE_ZN) & PSTATE_ZN) != 0; +} + + + unsigned GetKnownReg (unsigned Use, const RegContents* RC) /* Return the register or zero page location from the set in Use, thats ** contents are known. If Use does not contain any register, or if the diff --git a/src/cc65/codeinfo.h b/src/cc65/codeinfo.h index 14ef54d8f..c57908dad 100644 --- a/src/cc65/codeinfo.h +++ b/src/cc65/codeinfo.h @@ -201,6 +201,9 @@ int RegAXUsed (struct CodeSeg* S, unsigned Index); int RegEAXUsed (struct CodeSeg* S, unsigned Index); /* Check if any of the four bytes in EAX are used. */ +int LoadFlagsUsed (struct CodeSeg* S, unsigned Index); +/* Check if one of the flags set by a register load (Z and N) are used. */ + unsigned GetKnownReg (unsigned Use, const struct RegContents* RC); /* Return the register or zero page location from the set in Use, thats ** contents are known. If Use does not contain any register, or if the diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 49855a345..52c47481e 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -151,8 +151,8 @@ static short ZPRegVal (unsigned short Use, const RegContents* RC) unsigned OptUnusedLoads (CodeSeg* S) -/* Remove loads of or operations with registers where the value loaded or -** produced is not used later. +/* Remove loads of or operations with registers where the value loaded or +** produced is not used later. */ { unsigned Changes = 0; @@ -173,7 +173,7 @@ unsigned OptUnusedLoads (CodeSeg* S) E->OPC == OP65_ORA; /* Check for the necessary preconditions */ - if (IsOp && (N = CS_GetNextEntry (S, I)) != 0 && !CE_UseLoadFlags (N)) { + if (IsOp && (N = CS_GetNextEntry (S, I)) != 0 && !LoadFlagsUsed (S, I+1)) { /* Check which sort of load or transfer it is */ unsigned R; diff --git a/src/cc65/coptmisc.c b/src/cc65/coptmisc.c index 332247cf0..e48d469a1 100644 --- a/src/cc65/coptmisc.c +++ b/src/cc65/coptmisc.c @@ -788,8 +788,7 @@ unsigned OptBinOps (CodeSeg* S) ** The instruction can be removed if the flags aren't ** used later. */ - CodeEntry* N = CS_GetNextEntry (S, I); - if (N && !CE_UseLoadFlags (N)) { + if (!LoadFlagsUsed (S, I+1)) { Delete = 1; } } else if (Operand >= 0) { @@ -822,8 +821,7 @@ unsigned OptBinOps (CodeSeg* S) ** The instruction can be removed if the flags aren't ** used later. */ - CodeEntry* N = CS_GetNextEntry (S, I); - if (N && !CE_UseLoadFlags (N)) { + if (!LoadFlagsUsed (S, I+1)) { Delete = 1; } } else if (Operand >= 0) { @@ -861,8 +859,7 @@ unsigned OptBinOps (CodeSeg* S) ** The instruction can be removed if the flags aren't ** used later. */ - CodeEntry* N = CS_GetNextEntry (S, I); - if (N && !CE_UseLoadFlags (N)) { + if (!LoadFlagsUsed (S, I+1)) { Delete = 1; } } else if (Operand == 0xFF) { From 231ab4169bd54696d3742214eb73a6527f9b7ff1 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sat, 7 Sep 2024 17:20:27 +0200 Subject: [PATCH 266/707] Added a test. --- test/val/and-eor-ora-optimizations.c | 86 ++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 test/val/and-eor-ora-optimizations.c diff --git a/test/val/and-eor-ora-optimizations.c b/test/val/and-eor-ora-optimizations.c new file mode 100644 index 000000000..6b5aba68c --- /dev/null +++ b/test/val/and-eor-ora-optimizations.c @@ -0,0 +1,86 @@ +/* Test some new optimization passes */ + +#include <stdio.h> + +static unsigned failures = 0; + +int func0() +{ + unsigned a = 0x1234, b = 0x55AA; + return (a & 0x00FF) & (b & 0xFF00); +} + +int func1() +{ + unsigned a = 0x1234, b = 0x55AA; + return (0x00FF & a) & (0xFF00 & b); +} + +int func2() +{ + unsigned a = 0x1234, b = 0x55AA; + return (a | 0x00FF) & (b | 0xFF00); +} + +int func3() +{ + unsigned a = 0x1234, b = 0x55AA; + return (0x00FF | a) & (0xFF00 | b); +} + +int func4() +{ + unsigned a = 0x1234, b = 0x55AA; + return (a | 0x00FF) | (b | 0xFF00); +} + +int func5() +{ + unsigned a = 0x1234, b = 0x55AA; + return (0x00FF | a) | (0xFF00 | b); +} + +int func6() +{ + unsigned a = 0x1234, b = 0x55AA; + return (a ^ 0x00FF) & (b & 0xFF00); +} + +int func7() +{ + unsigned a = 0x1234, b = 0x55AA; + return (0x00FF ^ a) & (0xFF00 & b); +} + +int func8() +{ + unsigned a = 0x1234, b = 0x55AA; + return (a | 0x00FF) | (b ^ 0xFF00); +} + +int func9() +{ + unsigned a = 0x1234, b = 0x55AA; + return (0x00FF | a) | (0xFF00 ^ b); +} + +void onetest(unsigned count, int (*f1)(void), int (*f2)(void), int result) +{ + int r1 = f1(); + int r2 = f2(); + if (r1 != result || r2 != result) { + printf("Test %u failed! Expected 0x%04X but got 0x%04X/0x%04X\n", + count, result, r1, r2); + ++failures; + } +} + +int main() +{ + onetest(1, func0, func1, 0x0000); + onetest(2, func2, func3, 0x12AA); + onetest(3, func4, func5, 0xFFFF); + onetest(4, func6, func7, 0x1000); + onetest(5, func8, func9, 0xBAFF); + return failures; +} From 175ec65af1324ac5f3737c336e7b7b049b777a27 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sat, 14 Sep 2024 21:12:19 +0200 Subject: [PATCH 267/707] Fix #2520. --- src/cc65/ppexpr.c | 2 +- test/val/bug2520.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 test/val/bug2520.c diff --git a/src/cc65/ppexpr.c b/src/cc65/ppexpr.c index 8d8c0b65d..dc6803f91 100644 --- a/src/cc65/ppexpr.c +++ b/src/cc65/ppexpr.c @@ -726,7 +726,7 @@ static void PPhieQuest (PPExpr* Expr) PPhieQuest (&Expr3); /* Set the result */ - Expr->IVal = Expr->IVal ? Expr2.IVal != 0 : Expr3.IVal != 0; + Expr->IVal = Expr->IVal ? Expr2.IVal : Expr3.IVal; /* Restore evaluation as before */ PPEvaluationEnabled = PPEvaluationEnabledPrev; diff --git a/test/val/bug2520.c b/test/val/bug2520.c new file mode 100644 index 000000000..7a216df4d --- /dev/null +++ b/test/val/bug2520.c @@ -0,0 +1,4 @@ +#if (1 ? 2 : 0) != 2 +#error +#endif +int main() { return 0; } From 7dc09fdb05051de5273abb83679924b7b265a680 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 15 Sep 2024 19:22:16 +0200 Subject: [PATCH 268/707] add test related to bug#2515 / pr#2518 --- test/misc/Makefile | 8 ++++++++ test/misc/bug2515.c | 4 ++++ test/misc/bug2515.c99.ref | 2 ++ test/misc/bug2515.ref | 1 + 4 files changed, 15 insertions(+) create mode 100644 test/misc/bug2515.c create mode 100644 test/misc/bug2515.c99.ref create mode 100644 test/misc/bug2515.ref diff --git a/test/misc/Makefile b/test/misc/Makefile index cfcae0530..ebae0964e 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -102,6 +102,14 @@ $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) +# should not compile, but gives different diagnostics in C99 mode than in others +$(WORKDIR)/bug2515.$1.$2.prg: bug2515.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug2515.$1.$2.prg) + $(NOT) $(CC65) --standard c99 -t sim$2 -$1 -o $$(@:.prg=.s) $$< 2>$(WORKDIR)/bug2515.$1.$2.out + $(ISEQUAL) $(WORKDIR)/bug2515.$1.$2.out bug2515.c99.ref + $(NOT) $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< 2>$(WORKDIR)/bug2515.$1.$2.out + $(ISEQUAL) $(WORKDIR)/bug2515.$1.$2.out bug2515.ref + # this one requires -Werror $(WORKDIR)/bug1768.$1.$2.prg: bug1768.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1768.$1.$2.prg) diff --git a/test/misc/bug2515.c b/test/misc/bug2515.c new file mode 100644 index 000000000..62ee52a25 --- /dev/null +++ b/test/misc/bug2515.c @@ -0,0 +1,4 @@ + +#line 13"x" +#define X"y" +int main() { foo; } diff --git a/test/misc/bug2515.c99.ref b/test/misc/bug2515.c99.ref new file mode 100644 index 000000000..f6cf2fcea --- /dev/null +++ b/test/misc/bug2515.c99.ref @@ -0,0 +1,2 @@ +x:13: Warning: ISO C99 requires whitespace after the macro name +x:14: Error: Undeclared identifier 'foo' diff --git a/test/misc/bug2515.ref b/test/misc/bug2515.ref new file mode 100644 index 000000000..affbaebb9 --- /dev/null +++ b/test/misc/bug2515.ref @@ -0,0 +1 @@ +x:14: Error: Undeclared identifier 'foo' From 9c69aac09769810efe1ab92d748e2d93abcfaf19 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:45:46 +0200 Subject: [PATCH 269/707] Fix some issues with signedness in preprocessor expressions. Do also disallow comma expressions since the aren't compliant and collide with macro invocations. --- src/cc65/ppexpr.c | 31 +++++++------------------------ test/err/bug2523.c | 3 +++ test/val/bug2523.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 test/err/bug2523.c create mode 100644 test/val/bug2523.c diff --git a/src/cc65/ppexpr.c b/src/cc65/ppexpr.c index 8d8c0b65d..bedb01507 100644 --- a/src/cc65/ppexpr.c +++ b/src/cc65/ppexpr.c @@ -55,7 +55,6 @@ static int PPEvaluationFailed = 0; -static void PPhie0 (PPExpr* Expr); static void PPhie1 (PPExpr* Expr); @@ -138,7 +137,7 @@ static void PPhiePrimary (PPExpr* Expr) ** recursively. */ NextToken (); - PPhie0 (Expr); + PPhie1 (Expr); ConsumeRParen (); break; @@ -263,6 +262,7 @@ void PPhie10 (PPExpr* Expr) NextToken (); PPhie10 (Expr); Expr->IVal = !Expr->IVal; + Expr->Flags &= ~PPEXPR_UNSIGNED; /* Result is signed */ break; case TOK_CEOF: @@ -424,10 +424,10 @@ static void PPhie_compare (const token_t* Ops, /* List of generators */ } } } - } - /* The result is signed */ - Expr->Flags &= ~PPEXPR_UNSIGNED; + /* The result is signed */ + Expr->Flags &= ~PPEXPR_UNSIGNED; + } } @@ -711,7 +711,7 @@ static void PPhieQuest (PPExpr* Expr) /* Parse second expression */ PPExprInit (&Expr2); - PPhie0 (&Expr2); + PPhie1 (&Expr2); /* Skip the colon */ ConsumeColon (); @@ -809,23 +809,6 @@ static void PPhie1 (PPExpr* Expr) -static void PPhie0 (PPExpr* Expr) -/* Handle the comma "," operator */ -{ - PPhie1 (Expr); - - while (CurTok.Tok == TOK_COMMA) { - /* Skip the comma */ - NextToken (); - /* Reset the expression */ - PPExprInit (Expr); - /* Use the next operand as the value instead */ - PPhie1 (Expr); - } -} - - - void ParsePPExprInLine (PPExpr* Expr) /* Parse a line for PP expression */ { @@ -836,7 +819,7 @@ void ParsePPExprInLine (PPExpr* Expr) /* Parse */ PPExprInit (Expr); - PPhie0 (Expr); + PPhie1 (Expr); /* If the evaluation fails, the result is always zero */ if (PPEvaluationFailed) { diff --git a/test/err/bug2523.c b/test/err/bug2523.c new file mode 100644 index 000000000..7ab798557 --- /dev/null +++ b/test/err/bug2523.c @@ -0,0 +1,3 @@ +#if (1, 0) < 0 +#error +#endif diff --git a/test/val/bug2523.c b/test/val/bug2523.c new file mode 100644 index 000000000..8db72d055 --- /dev/null +++ b/test/val/bug2523.c @@ -0,0 +1,29 @@ +#if (0u - 1) < 0 +#error +#endif + +#if !1u - 1 > 0 +#error +#endif + +#if (1 & 1u) - 2 < 0 +#error +#endif + +#if (1 | 1u) - 2 < 0 +#error +#endif + +#if (1 ^ 1u) - 2 < 0 +#error +#endif + +#if (1u >> 1) - 2 < 0 +#error +#endif + +#if (0u << 1) - 1 < 0 +#error +#endif + +int main() { return 0; } From 41951a1345c301986b473ed113ad20f6497e6bcd Mon Sep 17 00:00:00 2001 From: Sven Oliver Moll <svolli@svolli.de> Date: Thu, 26 Sep 2024 19:33:26 +0200 Subject: [PATCH 270/707] updated customizing documentation "weak = yes" is now "type = weak" --- doc/customizing.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/customizing.sgml b/doc/customizing.sgml index e18bcf86c..58631eb3c 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -140,7 +140,7 @@ FEATURES { SYMBOLS { # Define the stack size for the application - __STACKSIZE__: value = $0200, weak = yes; + __STACKSIZE__: value = $0200, type = weak; } </code></tscreen> From 02840d503c7196ecd528e6ad0109ba1bd772c988 Mon Sep 17 00:00:00 2001 From: lcvgit <121000412+lcvgit@users.noreply.github.com> Date: Mon, 21 Oct 2024 10:00:48 -0500 Subject: [PATCH 271/707] Fix checkversion.c Add missing shifts for checking version from __CC65__. --- samples/checkversion.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/checkversion.c b/samples/checkversion.c index 1d3494a87..ca8843921 100644 --- a/samples/checkversion.c +++ b/samples/checkversion.c @@ -10,11 +10,11 @@ #include <stdio.h> #include <stdlib.h> -#if ((__CC65__ & 0xff00) > 3) || ((__CC65__ & 0x000f) > 0) +#if (((__CC65__ & 0xff00) >> 8) > 3) || ((__CC65__ & 0x000f) > 0) /* compiler version is 2.19-git or higher */ # define VER_MAJOR ((__CC65__ >> 8) & 0xff) # define VER_MINOR (__CC65__ & 0xff) -#elif ((__CC65__ & 0xff00) == 3) +#elif (((__CC65__ & 0xff00) >> 8) == 3) /* broken values in version 2.16 - 2.19-git before the bug was fixed */ # define VER_MAJOR 2 # define VER_MINOR (((__CC65__ >> 4) & 0x0f) + 16) From c41eb007e48adcd5890b75111d63438111caf0f5 Mon Sep 17 00:00:00 2001 From: lcvgit <121000412+lcvgit@users.noreply.github.com> Date: Mon, 21 Oct 2024 10:09:00 -0500 Subject: [PATCH 272/707] Update checkversion.c Add missing shifts. --- samples/checkversion.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/checkversion.c b/samples/checkversion.c index ca8843921..f2a9d4a49 100644 --- a/samples/checkversion.c +++ b/samples/checkversion.c @@ -10,11 +10,11 @@ #include <stdio.h> #include <stdlib.h> -#if (((__CC65__ & 0xff00) >> 8) > 3) || ((__CC65__ & 0x000f) > 0) +#if ((__CC65__ >> 8) > 3) || ((__CC65__ & 0x000f) > 0) /* compiler version is 2.19-git or higher */ # define VER_MAJOR ((__CC65__ >> 8) & 0xff) # define VER_MINOR (__CC65__ & 0xff) -#elif (((__CC65__ & 0xff00) >> 8) == 3) +#elif ((__CC65__ >> 8) == 3) /* broken values in version 2.16 - 2.19-git before the bug was fixed */ # define VER_MAJOR 2 # define VER_MINOR (((__CC65__ >> 4) & 0x0f) + 16) From eb6003aaf77d91c39e81b7bd54bd206c15a0f19f Mon Sep 17 00:00:00 2001 From: Alex Thissen <athissen@killer-apps2.nl> Date: Fri, 9 Aug 2024 13:11:02 +0200 Subject: [PATCH 273/707] Mikey enumeration values for cc65 include files and new bit definitions for ca65 --- asminc/lynx.inc | 347 ++++++++++++++++++++++++++++++----------------- include/_mikey.h | 255 +++++++++++++++++++++++++++------- 2 files changed, 430 insertions(+), 172 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index 0d34e1c7c..d6a8cd70a 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -83,7 +83,7 @@ MATHJ = $FC6F SPRCTL0 = $FC80 ; Sprite bits-per-pixel definitions -BPP_MASK = %11000000 ; Mask for settings bits per pixel +BPP_MASK = %11000000 ; Mask for settings bits per pixel BPP_1 = %00000000 BPP_2 = %01000000 BPP_3 = %10000000 @@ -94,23 +94,23 @@ VFLIP = %00010000 ; Sprite types - redefined to reflect the reality caused by the shadow error TYPE_SHADOW = %00000111 TYPE_XOR = %00000110 -TYPE_NONCOLL = %00000101 ; Non-colliding +TYPE_NONCOLL = %00000101 ; Non-colliding TYPE_NORMAL = %00000100 TYPE_BOUNDARY = %00000011 -TYPE_BSHADOW = %00000010 ; Background shadow -TYPE_BACKNONCOLL = %00000001 ; Background non-colliding +TYPE_BSHADOW = %00000010 ; Background shadow +TYPE_BACKNONCOLL = %00000001 ; Background non-colliding TYPE_BACKGROUND = %00000000 SPRCTL1 = $FC81 LITERAL = %10000000 PACKED = %00000000 -ALGO3 = %01000000 ; Broken, do not set this bit! +ALGO3 = %01000000 ; Broken, do not set this bit! ; Sprite reload mask definitions RELOAD_MASK = %00110000 -RENONE = %00000000 ; Reload nothing -REHV = %00010000 ; Reload hsize, vsize -REHVS = %00100000 ; Reload hsize, vsize, stretch -REHVST = %00110000 ; Reload hsize, vsize, stretch, tilt +RENONE = %00000000 ; Reload nothing +REHV = %00010000 ; Reload hsize, vsize +REHVS = %00100000 ; Reload hsize, vsize, stretch +REHVST = %00110000 ; Reload hsize, vsize, stretch, tilt ; More sprite control 1 bit definitions REUSEPAL = %00001000 SKIP = %00000100 @@ -138,8 +138,9 @@ HOWIE = $FCC4 ; *** Mikey Addresses ; *** -; Mikey Timers +; Mikey timers +; Logical timer names TIMER0 = $FD00 TIMER1 = $FD04 TIMER2 = $FD08 @@ -148,20 +149,20 @@ TIMER4 = $FD10 TIMER5 = $FD14 TIMER6 = $FD18 TIMER7 = $FD1C -HTIMER = $FD00 ; horizontal line timer (timer 0) -VTIMER = $FD08 ; vertical blank timer (timer 2) -STIMER = $FD1C ; sound timer (timer 7) +HTIMER = TIMER0 ; horizontal line timer (timer 0) +VTIMER = TIMER2 ; vertical blank timer (timer 2) +STIMER = TIMER7 ; sound timer (timer 7) -HTIMBKUP = $FD00 ; horizontal line timer (timer 0) +HTIMBKUP = $FD00 ; horizontal line timer (timer 0) HTIMCTLA = $FD01 HTIMCNT = $FD02 HTIMCTLB = $FD03 -VTIMBKUP = $FD08 ; vertical blank timer (timer 2) +VTIMBKUP = $FD08 ; vertical blank timer (timer 2) VTIMCTLA = $FD09 VTIMCNT = $FD0A VTIMCTLB = $FD0B -BAUDBKUP = $FD10 ; serial timer (timer 4) -STIMBKUP = $FD1C ; sound timer (timer 7) +BAUDBKUP = $FD10 ; serial timer (timer 4) +STIMBKUP = $FD1C ; sound timer (timer 7) STIMCTLA = $FD1D STIMCNT = $FD1E STIMCTLB = $FD1F @@ -199,129 +200,227 @@ TIM7CTLA = $FD1D TIM7CNT = $FD1E TIM7CTLB = $FD1F +; Timer offsets +TIM_BACKUP = 0 +TIM_CONTROLA = 1 +TIM_COUNT = 2 +TIM_CONTROLB = 3 + +; TIM_CONTROLA control bits +ENABLE_INT = %10000000 +RESET_DONE = %01000000 +ENABLE_RELOAD = %00010000 +ENABLE_COUNT = %00001000 +AUD_CLOCK_MASK = %00000111 + +; Clock settings +AUD_LINKING = %00000111 +AUD_64 = %00000110 +AUD_32 = %00000101 +AUD_16 = %00000100 +AUD_8 = %00000011 +AUD_4 = %00000010 +AUD_2 = %00000001 +AUD_1 = %00000000 + +; TIM_CONTROLB control bits +TIMER_DONE = %00001000 +LAST_CLOCK = %00000100 +BORROW_IN = %00000010 +BORROW_OUT = %00000001 + ; Mikey Audio -AUDIO0 = $FD20 ; audio channel 0 -AUDIO1 = $FD28 ; audio channel 1 -AUDIO2 = $FD30 ; audio channel 2 -AUDIO3 = $FD38 ; audio channel 3 +AUDIO0 = $FD20 ; audio channel 0 +AUDIO1 = $FD28 ; audio channel 1 +AUDIO2 = $FD30 ; audio channel 2 +AUDIO3 = $FD38 ; audio channel 3 -AUD0VOL = $FD20 -AUD0FEED = $FD21 -AUD0OUT = $FD22 -AUD0SHIFT = $FD23 -AUD0BKUP = $FD24 -AUD0CTLA = $FD25 -AUD0CNT = $FD26 -AUD0CTLB = $FD27 -AUD1VOL = $FD28 -AUD1FEED = $FD29 -AUD1OUT = $FD2A -AUD1SHIFT = $FD2B -AUD1BKUP = $FD2C -AUD1CTLA = $FD2D -AUD1CNT = $FD2E -AUD1CTLB = $FD2F -AUD2VOL = $FD30 -AUD2FEED = $FD31 -AUD2OUT = $FD32 -AUD2SHIFT = $FD33 -AUD2BKUP = $FD34 -AUD2CTLA = $FD35 -AUD2CNT = $FD36 -AUD2CTLB = $FD37 -AUD3VOL = $FD38 -AUD3FEED = $FD39 -AUD3OUT = $FD3A -AUD3SHIFT = $FD3B -AUD3BKUP = $FD3C -AUD3CTLA = $FD3D -AUD3CNT = $FD3E -AUD3CTLB = $FD3F +AUD0VOL = $FD20 +AUD0FEED = $FD21 +AUD0OUT = $FD22 +AUD0SHIFT = $FD23 +AUD0BKUP = $FD24 +AUD0CTLA = $FD25 +AUD0CNT = $FD26 +AUD0CTLB = $FD27 +AUD1VOL = $FD28 +AUD1FEED = $FD29 +AUD1OUT = $FD2A +AUD1SHIFT = $FD2B +AUD1BKUP = $FD2C +AUD1CTLA = $FD2D +AUD1CNT = $FD2E +AUD1CTLB = $FD2F +AUD2VOL = $FD30 +AUD2FEED = $FD31 +AUD2OUT = $FD32 +AUD2SHIFT = $FD33 +AUD2BKUP = $FD34 +AUD2CTLA = $FD35 +AUD2CNT = $FD36 +AUD2CTLB = $FD37 +AUD3VOL = $FD38 +AUD3FEED = $FD39 +AUD3OUT = $FD3A +AUD3SHIFT = $FD3B +AUD3BKUP = $FD3C +AUD3CTLA = $FD3D +AUD3CNT = $FD3E +AUD3CTLB = $FD3F + +; AUD_CONTROL bits are almost identical to TIM_CONTROLA bits. +; See TIM_CONTROLA above for the other definitions +FEEDBACK_7 = %10000000 +ENABLE_INTEGRATE = %00100000 + +; Stereo control registers follow +; Stereo capability does not exist in all Lynxes +; Left and right may be reversed, and if so will be corrected in a later +; release + +ATTENREG0 = $FD40 ; Stereo attenuation registers +ATTENREG1 = $FD41 +ATTENREG2 = $FD42 +ATTENREG3 = $FD43 +LEFT_ATTENMASK = %11110000 +RIGHT_ATTENMASK = %00001111 + +; Bit definitions for MPAN and MSTEREO registers +LEFT3_SELECT = %10000000 +LEFT2_SELECT = %01000000 +LEFT1_SELECT = %00100000 +LEFT0_SELECT = %00010000 +RIGHT3_SELECT = %00001000 +RIGHT2_SELECT = %00000100 +RIGHT1_SELECT = %00000010 +RIGHT0_SELECT = %00000001 + +MPAN = $FD44 MSTEREO = $FD50 -; Mikey Misc - -; Interrupt bits in INTRST and INTSET -TIMER0_INTERRUPT = $01 -TIMER1_INTERRUPT = $02 -TIMER2_INTERRUPT = $04 -TIMER3_INTERRUPT = $08 -TIMER4_INTERRUPT = $10 -TIMER5_INTERRUPT = $20 -TIMER6_INTERRUPT = $40 -TIMER7_INTERRUPT = $80 - -HBL_INTERRUPT = TIMER0_INTERRUPT -VBL_INTERRUPT = TIMER2_INTERRUPT -SERIAL_INTERRUPT = TIMER4_INTERRUPT -SND_INTERRUPT = TIMER7_INTERRUPT +; Mikey interrupts INTRST = $FD80 INTSET = $FD81 -MAGRDY0 = $FD84 -MAGRDY1 = $FD85 -AUDIN = $FD86 -SYSCTL1 = $FD87 -MIKEYHREV = $FD88 -MIKEYSREV = $FD89 +; Interrupt bits in INTRST and INTSET +TIMER0_INTERRUPT = %00000001 +TIMER1_INTERRUPT = %00000010 +TIMER2_INTERRUPT = %00000100 +TIMER3_INTERRUPT = %00001000 +TIMER4_INTERRUPT = %00010000 +TIMER5_INTERRUPT = %00100000 +TIMER6_INTERRUPT = %01000000 +TIMER7_INTERRUPT = %10000000 -IODIR = $FD8A -IODAT = $FD8B +HBL_INTERRUPT = TIMER0_INTERRUPT +VBL_INTERRUPT = TIMER2_INTERRUPT +SERIAL_INTERRUPT = TIMER4_INTERRUPT +SND_INTERRUPT = TIMER7_INTERRUPT + +MAGRDY0 = $FD84 +MAGRDY1 = $FD85 +AUDIN = $FD86 +SYSCTL1 = $FD87 +; SYSCTL1 bit definitions +POWERON = %00000010 +CART_ADDR_STROBE = %00000001 + +MIKEYHREV = $FD88 +MIKEYSREV = $FD89 + +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 +AUDIN_BIT = %00010000 ; Note that there is also the address AUDIN +READ_ENABLE = %00010000 ; Same bit for AUDIN_BIT +RESTLESS = %00001000 +NOEXP = %00000100 ; If set, redeye is not connected +CART_ADDR_DATA = %00000010 +CART_POWER_OFF = %00000010 ; Same bit for CART_ADDR_DATA +EXTERNAL_POWER = %00000001 -SERCTL = $FD8C +SERCTL = $FD8C ; SERCTL bit definitions for write operations -TXINTEN = $80 -RXINTEN = $40 -PAREN = $10 -RESETERR = $08 -TXOPEN = $04 -TXBRK = $02 -PAREVEN = $01 +TXINTEN = %10000000 +RXINTEN = %01000000 +PAREN = %00010000 +RESETERR = %00001000 +TXOPEN = %00000100 +TXBRK = %00000010 +PAREVEN = %00000001 ; SERCTL bit definitions for read operations -TXRDY = $80 -RXRDY = $40 -TXEMPTY = $20 -PARERR = $10 -OVERRUN = $08 -FRAMERR = $04 -RXBRK = $02 -PARBIT = $01 +TXRDY = %10000000 +RXRDY = %01000000 +TXEMPTY = %00100000 +PARERR = %00010000 +OVERRUN = %00001000 +FRAMERR = %00000100 +RXBRK = %00000010 +PARBIT = %00000001 -SERDAT = $FD8D -SDONEACK = $FD90 -CPUSLEEP = $FD91 -DISPCTL = $FD92 -PBKUP = $FD93 -DISPADRL = $FD94 -DISPADRH = $FD95 -MTEST0 = $FD9C -MTEST1 = $FD9D -MTEST2 = $FD9E -PALETTE = $FDA0 ; hardware rgb palette -GCOLMAP = $FDA0 ; hardware rgb palette (green) -RBCOLMAP = $FDB0 ; hardware rgb palette (red-blue) +SERDAT = $FD8D +SDONEACK = $FD90 +CPUSLEEP = $FD91 +DISPCTL = $FD92 +; DISPCTL bit definitions +DISP_COLOR = %10000000 ; must be set to 1 +DISP_FOURBIT = %01000000 ; must be set to 1 +DISP_FLIP = %00100000 +DMA_ENABLE = %00010000 ; must be set to 1 +PBKUP = $FD93 +DISPADRL = $FD94 +DISPADRH = $FD95 -; *** -; *** Misc Hardware + 6502 vectors -; *** +MTEST0 = $FD9C +; MTEST0 bit definitions +AT_CNT16 = %10000000 +AT_TEST = %01000000 +XCLKEN = %00100000 +UART_TURBO = %00010000 +ROM_SEL = %00001000 +ROM_TEST = %00000100 +M_TEST = %00000010 +CPU_TEST = %00000001 -MAPCTL = $FFF9 -VECTORS = $FFFB -INTVECTL = $FFFE -INTVECTH = $FFFF -RSTVECTL = $FFFC -RSTVECTH = $FFFD -NMIVECTL = $FFFA -NMIVECTH = $FFFB +MTEST1 = $FD9D +; MTEST1 bit definitions +P_CNT16 = %01000000 +REF_CNT16 = %00100000 +VID_TRIG = %00010000 +REF_TRIG = %00001000 +VID_DMA_DIS = %00000100 +REF_FAST = %00000010 +REF_DIS = %00000001 +MTEST2 = $FD9E +; MTEST2 bit definitions +V_STROBE = %00010000 +V_ZERO = %00001000 +H_120 = %00000100 +H_ZERO = %00000010 +V_BLANKEF = %00000001 + +PALETTE = $FDA0 ; hardware rgb palette +GCOLMAP = $FDA0 ; hardware rgb palette (green) +RBCOLMAP = $FDB0 ; hardware rgb palette (red-blue) + +; Memory mapping control and 6502 vectors + +MAPCTL = $FFF9 +; MAPCTL bit definitions +TURBO_DISABLE = %10000000 +VECTOR_SPACE = %00001000 ; 1 maps RAM into specified space +ROM_SPACE = %00000100 +MIKEY_SPACE = %00000010 +SUZY_SPACE = %00000001 + +VECTORS = $FFFB +INTVECTL = $FFFE +INTVECTH = $FFFF +RSTVECTL = $FFFC +RSTVECTH = $FFFD +NMIVECTL = $FFFA +NMIVECTH = $FFFB diff --git a/include/_mikey.h b/include/_mikey.h index b9b7f6906..9a50745b2 100644 --- a/include/_mikey.h +++ b/include/_mikey.h @@ -27,7 +27,7 @@ #ifndef __MIKEY_H #define __MIKEY_H -/* timer structure */ +/* Timer structure */ typedef struct _mikey_timer { unsigned char reload; unsigned char control; @@ -39,7 +39,7 @@ typedef struct _mikey_all_timers { struct _mikey_timer timer[8]; } _mikey_all_timers; -/* audio channel structure */ +/* Audio channel structure */ typedef struct _mikey_audio { unsigned char volume; unsigned char feedback; @@ -53,54 +53,213 @@ typedef struct _mikey_audio { /* Define a structure with the mikey register offsets */ struct __mikey { - struct _mikey_timer timer0; // 0xFD00 - struct _mikey_timer timer1; // 0xFD04 - struct _mikey_timer timer2; // 0xFD08 - struct _mikey_timer timer3; // 0xFD0C - struct _mikey_timer timer4; // 0xFD10 - struct _mikey_timer timer5; // 0xFD14 - struct _mikey_timer timer6; // 0xFD18 - struct _mikey_timer timer7; // 0xFD1C - struct _mikey_audio channel_a; // 0xFD20 - struct _mikey_audio channel_b; // 0xFD28 - struct _mikey_audio channel_c; // 0xFD30 - struct _mikey_audio channel_d; // 0xFD38 - unsigned char attena; // 0xFD40 ?? not yet allocated? - unsigned char attenb; // 0xFD41 | - unsigned char attenc; // 0xFD42 | - unsigned char attend; // 0xFD43 | - unsigned char panning; // 0xFD44 | - unsigned char unused0[11]; // 0xFD45 - 0xFD4F not used - unsigned char mstereo; // 0xFD50 stereo control bits - unsigned char unused1[47]; // 0xFD51 - 0xFD7F not used - unsigned char intrst; // 0xFD80 interrupt poll 0 - unsigned char intset; // 0xFD81 interrupt poll 1 - unsigned char unused2[2]; // 0xFD82 - 0xFD83 not used - unsigned char magrdy0; // 0xFD84 mag tape channel0 ready bit - unsigned char magrdy1; // 0xFD85 mag tape channel1 ready bit - unsigned char audin; // 0xFD86 audio in - unsigned char sysctl1; // 0xFD87 control bits - unsigned char mikeyrev; // 0xFD88 mikey hardware rev - unsigned char mikeysrev; // 0xFD89 mikey software rev - unsigned char iodir; // 0xFD8A parallel i/o data dir - unsigned char iodat; // 0xFD8B parallel data - unsigned char serctl; // 0xFD8C serial control register - unsigned char serdat; // 0xFD8D serial data - unsigned char unused3[2]; // 0xFD8E - 0xFD8F not used - unsigned char sdoneack; // 0xFD90 suzy done acknowledge - unsigned char cpusleep; // 0xFD91 cpu bus request disable - unsigned char dispctl; // 0xFD92 video bus request enable, viddma - unsigned char pkbkup; // 0xFD93 magic 'P' count - unsigned char *scrbase; // 0xFD94 start address of video display - unsigned char unused4[6]; // 0xFD96 - 0xFD9B not used - unsigned char mtest0; // 0xFD9C - unsigned char mtest1; // 0xFD9D - unsigned char mtest2; // 0xFD9E - unsigned char unused5; // 0xFD9F not used - unsigned char palette[32]; // 0xFDA0 - 0xFDBF palette 32 bytes - // 0xFDC0 - 0xFDFF not used + struct _mikey_timer timer0; // 0xFD00 + struct _mikey_timer timer1; // 0xFD04 + struct _mikey_timer timer2; // 0xFD08 + struct _mikey_timer timer3; // 0xFD0C + struct _mikey_timer timer4; // 0xFD10 + struct _mikey_timer timer5; // 0xFD14 + struct _mikey_timer timer6; // 0xFD18 + struct _mikey_timer timer7; // 0xFD1C + struct _mikey_audio channel_a; // 0xFD20 + struct _mikey_audio channel_b; // 0xFD28 + struct _mikey_audio channel_c; // 0xFD30 + struct _mikey_audio channel_d; // 0xFD38 + unsigned char attena; // 0xFD40 ?? not yet allocated? + unsigned char attenb; // 0xFD41 | + unsigned char attenc; // 0xFD42 | + unsigned char attend; // 0xFD43 | + unsigned char panning; // 0xFD44 | + unsigned char unused0[11]; // 0xFD45 - 0xFD4F not used + unsigned char mstereo; // 0xFD50 stereo control bits + unsigned char unused1[47]; // 0xFD51 - 0xFD7F not used + unsigned char intrst; // 0xFD80 interrupt poll 0 + unsigned char intset; // 0xFD81 interrupt poll 1 + unsigned char unused2[2]; // 0xFD82 - 0xFD83 not used + unsigned char magrdy0; // 0xFD84 mag tape channel0 ready bit + unsigned char magrdy1; // 0xFD85 mag tape channel1 ready bit + unsigned char audin; // 0xFD86 audio in + unsigned char sysctl1; // 0xFD87 control bits + unsigned char mikeyrev; // 0xFD88 mikey hardware rev + unsigned char mikeysrev; // 0xFD89 mikey software rev + unsigned char iodir; // 0xFD8A parallel i/o data dir + unsigned char iodat; // 0xFD8B parallel data + unsigned char serctl; // 0xFD8C serial control register + unsigned char serdat; // 0xFD8D serial data + unsigned char unused3[2]; // 0xFD8E - 0xFD8F not used + unsigned char sdoneack; // 0xFD90 suzy done acknowledge + unsigned char cpusleep; // 0xFD91 cpu bus request disable + unsigned char dispctl; // 0xFD92 video bus request enable, viddma + unsigned char pkbkup; // 0xFD93 magic 'P' count + unsigned char *scrbase; // 0xFD94 start address of video display + unsigned char unused4[6]; // 0xFD96 - 0xFD9B not used + unsigned char mtest0; // 0xFD9C + unsigned char mtest1; // 0xFD9D + unsigned char mtest2; // 0xFD9E + unsigned char unused5; // 0xFD9F not used + unsigned char palette[32]; // 0xFDA0 - 0xFDBF palette 32 bytes + unsigned char unused6[64]; // 0xFDC0 - 0xFDFF not used + unsigned char bootrom[504]; // 0xFE00 - 0xFFD8 boot rom + unsigned char reserved; // 0xFFD8 reserved for future hardware + unsigned char mapctl; // 0xFFF9 map control register + struct { + unsigned char *nmi; // 0xFFFA NMI vector + unsigned char *reset; // 0xFFFB reset vector + unsigned char *irq; // 0xFFFC IRQ vector + } vectors; }; +// TIM_CONTROLA control bit definitions +enum { + ENABLE_INT = 0x80, + RESET_DONE = 0x40, + ENABLE_RELOAD = 0x10, + ENABLE_COUNT = 0x08 +}; + +// AUD_CONTROL control bit definitions +enum { + FEEDBACK_7 = 0x80, + ENABLE_INTEGRATE = 0x20 +}; + +// Audio and timer clock settings for source period +enum { + AUD_LINKING = 0x07, + AUD_64 = 0x06, + AUD_32 = 0x05, + AUD_16 = 0x04, + AUD_8 = 0x03, + AUD_4 = 0x02, + AUD_2 = 0x01, + AUD_1 = 0x00 +}; + +// TIM_CONTROLB control bit definitions +enum { + TIMER_DONE = 0x08, + LAST_CLOCK = 0x04, + BORROW_IN = 0x02, + BORROW_OUT = 0x01 +}; + +// MPAN and MSTEREO registers bit definitions +enum { + LEFT3_SELECT = 0x80, + LEFT2_SELECT = 0x40, + LEFT1_SELECT = 0x20, + LEFT0_SELECT = 0x10, + RIGHT3_SELECT = 0x08, + RIGHT2_SELECT = 0x04, + RIGHT1_SELECT = 0x02, + RIGHT0_SELECT = 0x01, + LEFT_ATTENMASK = 0xF0, + RIGHT_ATTENMASK = 0x0F +}; + +// Interrupt Reset and Set bit definitions +enum { + TIMER7_INT = 0x80, + TIMER6_INT = 0x40, + TIMER5_INT = 0x20, + TIMER4_INT = 0x10, + TIMER3_INT = 0x08, + TIMER2_INT = 0x04, + TIMER1_INT = 0x02, + TIMER0_INT = 0x01, + SERIAL_INT = TIMER4_INT, + VERTICAL_INT = TIMER2_INT, + HORIZONTAL_INT = TIMER0_INT +}; + +// SYSCTL1 bit definitions +enum { + POWERON = 0x02, + CART_ADDR_STROBE = 0x01 +}; + +// IODIR and IODAT bit definitions +enum { + AUDIN_BIT = 0x10, // different from AUDIN address + READ_ENABLE = 0x10, // same bit for AUDIN_BIT + RESTLESS = 0x08, + NOEXP = 0x04, // if set, redeye is not connected + CART_ADDR_DATA = 0x02, // + CART_POWER_OFF = 0x02, // same bit for CART_ADDR_DATA + EXTERNAL_POWER = 0x01 +}; + +// SERCTL bit definitions for write operations +enum { + TXINTEN = 0x80, + RXINTEN = 0x40, + PAREN = 0x10, + RESETERR = 0x08, + TXOPEN = 0x04, + TXBRK = 0x02, + PAREVEN = 0x01 +}; + +// SERCTL bit definitions for read operations +enum { + TXRDY = 0x80, + RXRDY = 0x40, + TXEMPTY = 0x20, + PARERR = 0x10, + OVERRUN = 0x08, + FRAMERR = 0x04, + RXBRK = 0x02, + PARBIT = 0x01 +}; + +// DISPCTL bit definitions +enum { + DISP_COLOR = 0x08, // must be set to 1 + DISP_FOURBIT = 0x04, // must be set to 1 + DISP_FLIP = 0x02, // + DMA_ENABLE = 0x01 // must be set to 1 +}; + +// MTEST0 bit definitions +enum { + AT_CNT16 = 0x80, + AT_TEST = 0x40, + XCLKEN = 0x20, + UART_TURBO = 0x10, + ROM_SEL = 0x08, + ROM_TEST = 0x04, + M_TEST = 0x02, + CPU_TEST = 0x01 +}; + +// MTEST1 bit definitions +enum { + P_CNT16 = 0x40, + REF_CNT16 = 0x20, + VID_TRIG = 0x10, + REF_TRIG = 0x08, + VID_DMA_DIS = 0x04, + REF_FAST = 0x02, + REF_DIS = 0x01 +}; + +// MTEST2 bit definitions +enum { + V_STROBE = 0x10, + V_ZERO = 0x08, + H_120 = 0x04, + H_ZERO = 0x02, + V_BLANKEF = 0x01 +}; + +// MAPCTL bit definitions +enum { + TURBO_DISABLE = 0x80, + VECTOR_SPACE = 0x08, + ROM_SPACE = 0x04, + MIKEY_SPACE = 0x02, + SUZY_SPACE = 0x01 +}; #endif From 3553975b025f2524ec1b9802520c18045f17a799 Mon Sep 17 00:00:00 2001 From: Alex Thissen <athissen@killer-apps2.nl> Date: Fri, 9 Aug 2024 13:53:41 +0200 Subject: [PATCH 274/707] Math improvements to Suzy include file --- include/_suzy.h | 69 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/include/_suzy.h b/include/_suzy.h index 8ab7f68dd..c2c9de49c 100644 --- a/include/_suzy.h +++ b/include/_suzy.h @@ -242,10 +242,38 @@ typedef struct PENPAL_1 { #define MIKEYSPACE 0x02 #define SUZYSPACE 0x01 +// Structures for math registers +struct _math_unsigned_multiply { + unsigned int factor1; // 0xFC52 - 0xFC53 + unsigned int factor2; // 0xFC54 - 0xFC55 write starts multiply + unsigned char unused2[10]; // 0xFC56 - 0xFC5F do not use + unsigned long product; // 0xFC60 - 0xFC63 + unsigned char unused3[8]; // 0xFC64 - 0xFC6B do not use + unsigned long accumulate; // 0xFC6C - 0xFC6F +}; + +struct _math_signed_multiply { + int factor1; // 0xFC52 - 0xFC53 + int factor2; // 0xFC54 - 0xFC55 write starts multiply + unsigned char unused2[10]; // 0xFC56 - 0xFC5F do not use + long product; // 0xFC60 - 0xFC63 + unsigned char unused3[8]; // 0xFC64 - 0xFC6B do not use + long accumulate; // 0xFC6C - 0xFC6F +}; + +struct _math_divide { + unsigned long quotient; // 0xFC52 - 0xFC55 + unsigned int divisor; // 0xFC56 - 0xFC57 + unsigned char unused2[8]; // 0xFC58 - 0xFC5F do not use + unsigned int dividend2; // 0xFC60 - 0xFC61 + unsigned int dividend1; // 0xFC62 - 0xFC63 write starts divide + unsigned char unused3[8]; // 0xFC64 - 0xFC6B do not use + unsigned long remainder; // 0xFC6C - 0xFC6F +}; /* Suzy Hardware Registers */ struct __suzy { - unsigned int tmpadr; // 0xFC00 Temporary address + unsigned char *tmpadr; // 0xFC00 Temporary address unsigned int tiltacc; // 0xFC02 Tilt accumulator unsigned int hoff; // 0xFC04 Offset to H edge of screen unsigned int voff; // 0xFC06 Offset to V edge of screen @@ -271,22 +299,29 @@ struct __suzy { unsigned char *procaddr; // 0xFC2E address of current spr data proc unsigned char unused0[32]; // 0xFC30 - 0xFC4F reserved/unused unsigned char unused1[2]; // 0xFC50 - 0xFC51 do not use - unsigned char mathd; // 0xFC52 - unsigned char mathc; // 0xFC53 - unsigned char mathb; // 0xFC54 - unsigned char matha; // 0xFC55 - unsigned char mathp; // 0xFC56 - unsigned char mathn; // 0xFC57 - unsigned char unused2[8]; // 0xFC58 - 0xFC5F do not use - unsigned char mathh; // 0xFC60 - unsigned char mathg; // 0xFC61 - unsigned char mathf; // 0xFC62 - unsigned char mathe; // 0xFC63 - unsigned char unused3[8]; // 0xFC64 - 0xFC6B do not use - unsigned char mathm; // 0xFC6C - unsigned char mathl; // 0xFC6D - unsigned char mathk; // 0xFC6E - unsigned char mathj; // 0xFC6F + union { + struct { + unsigned char mathd; // 0xFC52 + unsigned char mathc; // 0xFC53 + unsigned char mathb; // 0xFC54 + unsigned char matha; // 0xFC55 write starts a multiply operation + unsigned char mathp; // 0xFC56 + unsigned char mathn; // 0xFC57 + unsigned char unused2[8]; // 0xFC58 - 0xFC5F do not use + unsigned char mathh; // 0xFC60 + unsigned char mathg; // 0xFC61 + unsigned char mathf; // 0xFC62 + unsigned char mathe; // 0xFC63 write starts a divide operation + unsigned char unused3[8]; // 0xFC64 - 0xFC6B do not use + unsigned char mathm; // 0xFC6C + unsigned char mathl; // 0xFC6D + unsigned char mathk; // 0xFC6E + unsigned char mathj; // 0xFC6F + }; + struct _math_unsigned_multiply unsigned_multiply; + struct _math_signed_multiply signed_multiply; + struct _math_divide divide; + }; unsigned char unused4[16]; // 0xFC70 - 0xFC7F do not use unsigned char sprctl0; // 0xFC80 sprite control bits 0 unsigned char sprctl1; // 0xFC81 sprite control bits 1 From 7150fdf4b9608a4377f1c5c26e4c0a66f9faae54 Mon Sep 17 00:00:00 2001 From: Alex Thissen <athissen@killer-apps2.nl> Date: Fri, 9 Aug 2024 14:48:13 +0200 Subject: [PATCH 275/707] Enumerations and math structures for Suzy --- include/_suzy.h | 192 +++++++++++++++++++++++++----------------------- include/lynx.h | 177 +++++++++++++------------------------------- 2 files changed, 152 insertions(+), 217 deletions(-) diff --git a/include/_suzy.h b/include/_suzy.h index c2c9de49c..29a263880 100644 --- a/include/_suzy.h +++ b/include/_suzy.h @@ -24,73 +24,62 @@ /* */ /*****************************************************************************/ - #ifndef __SUZY_H #define __SUZY_H -/* Joypad $FCB0 */ -#define JOYPAD_RIGHT 0x10 -#define JOYPAD_LEFT 0x20 -#define JOYPAD_DOWN 0x40 -#define JOYPAD_UP 0x80 -#define BUTTON_OPTION1 0x08 -#define BUTTON_OPTION2 0x04 -#define BUTTON_INNER 0x02 -#define BUTTON_OUTER 0x01 +// JOYSTICK bit definitions +enum { + JOYPAD_RIGHT = 0x10, + JOYPAD_LEFT = 0x20, + JOYPAD_DOWN = 0x40, + JOYPAD_UP = 0x80, + BUTTON_OPTION1 = 0x08, + BUTTON_OPTION2 = 0x04, + BUTTON_INNER = 0x02, + BUTTON_OUTER = 0x01 +}; -/* Switches $FCB1 */ -#define BUTTON_PAUSE 0x01 +// SWITCHES bit definitions +enum { + CART1_IO_INACTIVE = 0x04, + CART0_IO_INACTIVE = 0x02, + BUTTON_PAUSE = 0x01 +}; +// SPRCTL0 bit definitions +enum { + BPP_4 = 0xC0, + BPP_3 = 0x80, + BPP_2 = 0x40, + BPP_1 = 0x00, + HFLIP = 0x20, + VFLIP = 0x10, + TYPE_SHADOW = 0x07, + TYPE_XOR = 0x06, + TYPE_NONCOLL = 0x05, + TYPE_NORMAL = 0x04, + TYPE_BOUNDARY = 0x03, + TYPE_BSHADOW = 0x02, + TYPE_BACKNONCOLL = 0x01, + TYPE_BACKGROUND = 0x00 +}; -/* Hardware Math */ -#define FACTOR_A *(unsigned int *) 0xFC54 -#define FACTOR_B *(unsigned int *) 0xFC52 -#define PRODUCT0 *(unsigned int *) 0xFC60 -#define PRODUCT1 *(unsigned int *) 0xFC62 -#define PRODUCT *(long *) 0xFC60 +// SPRCTL1 bit definitions +enum { + LITERAL = 0x80, + PACKED = 0x00, + ALGO3 = 0x40, + RENONE = 0x00, + REHV = 0x10, + REHVS = 0x20, + REHVST = 0x30, + REUSEPAL = 0x08, + SKIP = 0x04, + DRAWUP = 0x02, + DRAWLEFT = 0x01 +}; -#define DIVIDEND0 *(unsigned int *) 0xFC60 -#define DIVIDEND1 *(unsigned int *) 0xFC62 -#define DIVIDEND *(long *) 0xFC60 -#define DIVISOR *(unsigned int *) 0xFC56 -#define QUOTIENT0 *(unsigned int *) 0xFC52 -#define QUOTIENT1 *(unsigned int *) 0xFC54 -#define QUOTIENT *(long *) 0xFC52 -#define REMAINDER0 *(unsigned int *) 0xFC6C -#define REMAINDER1 *(unsigned int *) 0xFC6E -#define REMAINDER *(long *) 0xFC6C - - -/* Sprite control block (SCB) defines */ - -/* SPRCTL0 $FC80 */ -#define BPP_4 0xC0 -#define BPP_3 0x80 -#define BPP_2 0x40 -#define BPP_1 0x00 -#define HFLIP 0x20 -#define VFLIP 0x10 -#define TYPE_SHADOW 0x07 -#define TYPE_XOR 0x06 -#define TYPE_NONCOLL 0x05 -#define TYPE_NORMAL 0x04 -#define TYPE_BOUNDARY 0x03 -#define TYPE_BSHADOW 0x02 -#define TYPE_BACKNONCOLL 0x01 -#define TYPE_BACKGROUND 0x00 - -/* SPRCTL1 $FC81 */ -#define LITERAL 0x80 -#define PACKED 0x00 -#define ALGO3 0x40 -#define RENONE 0x00 -#define REHV 0x10 -#define REHVS 0x20 -#define REHVST 0x30 -#define REUSEPAL 0x08 -#define SKIP 0x04 -#define DRAWUP 0x02 -#define DRAWLEFT 0x01 +// Sprite control block (SCB) definitions typedef struct SCB_REHVST_PAL { // SCB with all attributes unsigned char sprctl0; @@ -210,37 +199,33 @@ typedef struct PENPAL_1 { unsigned char penpal[1]; } PENPAL_1; -/* Misc system defines */ +// SPRGO bit definitions +enum { + SPRITE_GO = 0x01, // sprite process start bit + EVER_ON = 0x04 // everon detector enable +}; -/* SPRGO $FC91 */ -#define EVER_ON 0x04 -#define SPRITE_GO 0x01 - -/* SPRSYS (write) $FC92 */ -#define SIGNMATH 0x80 -#define ACCUMULATE 0x40 -#define NO_COLLIDE 0x20 -#define VSTRETCH 0x10 -#define LEFTHAND 0x08 -#define CLR_UNSAFE 0x04 -#define SPRITESTOP 0x02 - -/* SPRSYS (read) $FC92 */ -#define MATHWORKING 0x80 -#define MATHWARNING 0x40 -#define MATHCARRY 0x20 -#define VSTRETCHING 0x10 -#define LEFTHANDED 0x08 -#define UNSAFE_ACCESS 0x04 -#define SPRITETOSTOP 0x02 -#define SPRITEWORKING 0x01 - -/* MAPCTL $FFF9 */ -#define HIGHSPEED 0x80 -#define VECTORSPACE 0x08 -#define ROMSPACE 0x04 -#define MIKEYSPACE 0x02 -#define SUZYSPACE 0x01 +// SPRSYS bit definitions for write operations +enum { + SIGNMATH = 0x80, // signed math + ACCUMULATE = 0x40, // accumulate multiplication results + NO_COLLIDE = 0x20, // do not collide with any sprites (also SPRCOLL bit definition) + VSTRETCH = 0x10, // stretch v + LEFTHAND = 0x08, + CLR_UNSAFE = 0x04, // unsafe access reset + SPRITESTOP = 0x02 // request to stop sprite process +}; +// SPRSYS bit definitions for read operations +enum { + MATHWORKING = 0x80, // math operation in progress + MATHWARNING = 0x40, // accumulator overflow on multiple or divide by zero + MATHCARRY = 0x20, // last carry bit + VSTRETCHING = 0x10, + LEFTHANDED = 0x08, + UNSAFE_ACCESS = 0x04, // unsafe access performed + SPRITETOSTOP = 0x02, // requested to stop + SPRITEWORKING = 0x01 // sprite process is active +}; // Structures for math registers struct _math_unsigned_multiply { @@ -348,6 +333,31 @@ struct __suzy { // 0xFCC5 - 0xFCFF unused }; +// Deprecated definitions + +/* Hardware Math */ +#define FACTOR_A *(unsigned int *) 0xFC54 +#define FACTOR_B *(unsigned int *) 0xFC52 +#define PRODUCT0 *(unsigned int *) 0xFC60 +#define PRODUCT1 *(unsigned int *) 0xFC62 +#define PRODUCT *(long *) 0xFC60 + +#define DIVIDEND0 *(unsigned int *) 0xFC60 +#define DIVIDEND1 *(unsigned int *) 0xFC62 +#define DIVIDEND *(long *) 0xFC60 +#define DIVISOR *(unsigned int *) 0xFC56 +#define QUOTIENT0 *(unsigned int *) 0xFC52 +#define QUOTIENT1 *(unsigned int *) 0xFC54 +#define QUOTIENT *(long *) 0xFC52 +#define REMAINDER0 *(unsigned int *) 0xFC6C +#define REMAINDER1 *(unsigned int *) 0xFC6E +#define REMAINDER *(long *) 0xFC6C + +/* MAPCTL $FFF9 */ +#define HIGHSPEED 0x80 +#define VECTORSPACE 0x08 +#define ROMSPACE 0x04 +#define MIKEYSPACE 0x02 +#define SUZYSPACE 0x01 #endif - diff --git a/include/lynx.h b/include/lynx.h index 41dc5acb3..e2c0c503f 100644 --- a/include/lynx.h +++ b/include/lynx.h @@ -31,27 +31,15 @@ /* */ /*****************************************************************************/ - - #ifndef _LYNX_H #define _LYNX_H - - /* Check for errors */ #if !defined(__LYNX__) # error This module may only be used when compiling for the Lynx game console! #endif - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Color defines */ +/* Color definitions */ #define COLOR_TRANSPARENT 0x00 #define COLOR_BLACK 0x01 #define COLOR_RED 0x02 @@ -88,6 +76,56 @@ #define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE #define TGI_COLOR_WHITE COLOR_WHITE +/* No support for dynamically loadable drivers */ +#define DYN_DRV 0 + +// Addresses of static drivers +extern void lynx_stdjoy_joy[]; // Referred to by joy_static_stddrv[] +extern void lynx_comlynx_ser[]; // Referred to by ser_static_stddrv[] +extern void lynx_160_102_16_tgi[]; // Referred to by tgi_static_stddrv[] + +// Sound support +void lynx_snd_init (void); // Initialize the sound driver +void lynx_snd_pause (void); // Pause sound +void lynx_snd_continue (void); // Continue sound after pause +void __fastcall__ lynx_snd_play (unsigned char channel, unsigned char *music); // Play tune on channel +void lynx_snd_stop (void); // Stop sound on all channels +void __fastcall__ lynx_snd_stop_channel (unsigned char channel); // Stop sound on all channels +unsigned char lynx_snd_active(void); // Show which channels are active + +// Cartridge access +void __fastcall__ lynx_load (int file_number); // Load a file into RAM using a zero-based index +void __fastcall__ lynx_exec (int file_number); // Load a file into ram and execute it + +// EEPROM access +unsigned __fastcall__ lynx_eeprom_read (unsigned char cell); // Read a 16 bit word from the given address +unsigned __fastcall__ lynx_eeprom_write (unsigned char cell, unsigned val); // Write the word at the given address +void __fastcall__ lynx_eeprom_erase (unsigned char cell); // Clear the word at the given address +unsigned __fastcall__ lynx_eeread (unsigned cell); // Read a 16 bit word from the given address 93C46, 93C66 or 93C86 +unsigned __fastcall__ lynx_eewrite (unsigned cell, unsigned val); // Write the word at the given address 93C46, 93C66 or 93C86 + +// TGI extras +#define tgi_sprite(spr) tgi_ioctl(0, spr) +#define tgi_flip() tgi_ioctl(1, (void*)0) +#define tgi_setbgcolor(bgcol) tgi_ioctl(2, (void*)(bgcol)) +#define tgi_setframerate(rate) tgi_ioctl(3, (void*)(rate)) +#define tgi_busy() tgi_ioctl(4, (void*)0) +#define tgi_updatedisplay() tgi_ioctl(4, (void*)1) +#define tgi_setcollisiondetection(active) tgi_ioctl(5, (void*)(active)) + +/* Hardware definitions */ +#include <_mikey.h> +#define MIKEY (*(struct __mikey *)0xFD00) + +#define _MIKEY_TIMERS (*(struct _mikey_all_timers *) 0xFD00) // mikey_timers[8] +#define _HBL_TIMER (*(struct _mikey_timer *) 0xFD00) // timer0 (HBL) +#define _VBL_TIMER (*(struct _mikey_timer *) 0xFD08) // timer2 (VBL) +#define _UART_TIMER (*(struct _mikey_timer *) 0xFD14) // timer4 (UART) +#define _VIDDMA (*(unsigned int *) 0xFD92) // dispctl/viddma + +#include <_suzy.h> +#define SUZY (*(volatile struct __suzy*)0xFC00) + /* Masks for joy_read */ #define JOY_UP_MASK 0x80 #define JOY_DOWN_MASK 0x40 @@ -102,118 +140,5 @@ #define JOY_BTN_A(v) ((v) & JOY_BTN_A_MASK) #define JOY_BTN_B(v) ((v) & JOY_BTN_B_MASK) -/* No support for dynamically loadable drivers */ -#define DYN_DRV 0 - - - -/*****************************************************************************/ -/* Variables */ -/*****************************************************************************/ - - - -/* The addresses of the static drivers */ -extern void lynx_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ -extern void lynx_comlynx_ser[]; /* Referred to by ser_static_stddrv[] */ -extern void lynx_160_102_16_tgi[]; /* Referred to by tgi_static_stddrv[] */ - - - -/*****************************************************************************/ -/* Sound support */ -/*****************************************************************************/ - - - -void lynx_snd_init (void); -/* Initialize the sound driver */ - -void lynx_snd_pause (void); -/* Pause sound */ - -void lynx_snd_continue (void); -/* Continue sound after pause */ - -void __fastcall__ lynx_snd_play (unsigned char channel, unsigned char *music); -/* Play tune on channel */ - -void lynx_snd_stop (void); -/* Stop sound on all channels */ - -void __fastcall__ lynx_snd_stop_channel (unsigned char channel); -/* Stop sound on all channels */ - -unsigned char lynx_snd_active(void); -/* Show which channels are active */ - - - -/*****************************************************************************/ -/* Accessing the cart */ -/*****************************************************************************/ - - - -void __fastcall__ lynx_load (int fileno); -/* Load a file into ram. The first entry is fileno=0. */ - -void __fastcall__ lynx_exec (int fileno); -/* Load a file into ram and execute it. */ - - - -/*****************************************************************************/ -/* Accessing the EEPROM */ -/*****************************************************************************/ - - - -unsigned __fastcall__ lynx_eeprom_read (unsigned char cell); -/* Read a 16 bit word from the given address */ - -unsigned __fastcall__ lynx_eeprom_write (unsigned char cell, unsigned val); -/* Write the word at the given address */ - -void __fastcall__ lynx_eeprom_erase (unsigned char cell); -/* Clear the word at the given address */ - -unsigned __fastcall__ lynx_eeread (unsigned cell); -/* Read a 16 bit word from the given address 93C46 93C66 or 93C86*/ - -unsigned __fastcall__ lynx_eewrite (unsigned cell, unsigned val); -/* Write the word at the given address 93C46 93C66 or 93C86*/ - - - -/*****************************************************************************/ -/* TGI extras */ -/*****************************************************************************/ - - - -#define tgi_sprite(spr) tgi_ioctl(0, spr) -#define tgi_flip() tgi_ioctl(1, (void*)0) -#define tgi_setbgcolor(bgcol) tgi_ioctl(2, (void*)(bgcol)) -#define tgi_setframerate(rate) tgi_ioctl(3, (void*)(rate)) -#define tgi_busy() tgi_ioctl(4, (void*)0) -#define tgi_updatedisplay() tgi_ioctl(4, (void*)1) -#define tgi_setcollisiondetection(active) tgi_ioctl(5, (void*)(active)) - -/* Define Hardware */ -#include <_mikey.h> -#define MIKEY (*(struct __mikey *)0xFD00) - -#define _MIKEY_TIMERS (*(struct _mikey_all_timers *) 0xFD00) // mikey_timers[8] -#define _HBL_TIMER (*(struct _mikey_timer *) 0xFD00) // timer0 (HBL) -#define _VBL_TIMER (*(struct _mikey_timer *) 0xFD08) // timer2 (VBL) -#define _UART_TIMER (*(struct _mikey_timer *) 0xFD14) // timer4 (UART) -#define _VIDDMA (*(unsigned int *) 0xFD92) // dispctl/viddma - -#include <_suzy.h> -#define SUZY (*(struct __suzy*)0xFC00) - - - /* End of lynx.h */ #endif From abcb073a5a30ddfbae8ddcdb1a82a42e047f18b4 Mon Sep 17 00:00:00 2001 From: Alex Thissen <athissen@killer-apps2.nl> Date: Fri, 9 Aug 2024 15:10:30 +0200 Subject: [PATCH 276/707] Bit definitions for Suzy --- asminc/lynx.inc | 192 ++++++++++++++++++++++++++++-------------------- 1 file changed, 113 insertions(+), 79 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index d6a8cd70a..458cd650f 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -79,7 +79,7 @@ MATHL = $FC6D MATHK = $FC6E MATHJ = $FC6F -; Suzy Misc +; Suzy sprite engine SPRCTL0 = $FC80 ; Sprite bits-per-pixel definitions @@ -117,15 +117,53 @@ SKIP = %00000100 DRAWUP = %00000010 DRAWLEFT = %00000001 -SPRCOLL = $FC82 -SPRINIT = $FC83 -SUZYHREV = $FC88 -SUZYSREV = $FC89 -SUZYBUSEN = $FC90 -SPRGO = $FC91 -SPRSYS = $FC92 -JOYSTICK = $FCB0 +SPRCOLL = $FC82 +SPRINIT = $FC83 +SUZYHREV = $FC88 +SUZYSREV = $FC89 +SUZYBUSEN = $FC90 + +SPRGO = $FC91 +; SPRGO bit definitions +SPRITE_GO = %00000001 ; sprite process start bit +EVER_ON = %00000100 ; everon detector enable + +SPRSYS = $FC92 +; SPRSYS bit definitions for write operations +SIGNMATH = 0x80 ; signed math +ACCUMULATE = 0x40 ; accumulate multiplication results +NO_COLLIDE = 0x20 ; do not collide with any sprites (also SPRCOLL bit definition) +VSTRETCH = 0x10 ; stretch v +LEFTHAND = 0x08 +CLR_UNSAFE = 0x04 ; unsafe access reset +SPRITESTOP = 0x02 ; request to stop sprite process +; SPRSYS bit definitions for read operations +MATHWORKING = 0x80 ; math operation in progress +MATHWARNING = 0x40 ; accumulator overflow on multiple or divide by zero +MATHCARRY = 0x20 ; last carry bit +VSTRETCHING = 0x10 +LEFTHANDED = 0x08 +UNSAFE_ACCESS = 0x04 ; unsafe access performed +SPRITETOSTOP = 0x02 ; requested to stop +SPRITEWORKING = 0x01 ; sprite process is active + +JOYSTICK = $FCB0 +; JOYSTICK bit definitions +JOYPAD_UP = 0x80 +JOYPAD_DOWN = 0x40 +JOYPAD_LEFT = 0x20 +JOYPAD_RIGHT = 0x10 +BUTTON_OPTION1 = 0x08 +BUTTON_OPTION2 = 0x04 +BUTTON_INNER = 0x02 +BUTTON_OUTER = 0x01 + SWITCHES = $FCB1 +; SWITCHES bit definitions +CART1_IO_INACTIVE = 0x04 +CART0_IO_INACTIVE = 0x02 +BUTTON_PAUSE = 0x01 + RCART0 = $FCB2 RCART1 = $FCB3 LEDS = $FCC0 @@ -133,72 +171,71 @@ PARSTATUS = $FCC2 PARDATA = $FCC3 HOWIE = $FCC4 - -; *** +; ; *** Mikey Addresses ; *** ; Mikey timers ; Logical timer names -TIMER0 = $FD00 -TIMER1 = $FD04 -TIMER2 = $FD08 -TIMER3 = $FD0C -TIMER4 = $FD10 -TIMER5 = $FD14 -TIMER6 = $FD18 -TIMER7 = $FD1C -HTIMER = TIMER0 ; horizontal line timer (timer 0) -VTIMER = TIMER2 ; vertical blank timer (timer 2) -STIMER = TIMER7 ; sound timer (timer 7) +TIMER0 = $FD00 +TIMER1 = $FD04 +TIMER2 = $FD08 +TIMER3 = $FD0C +TIMER4 = $FD10 +TIMER5 = $FD14 +TIMER6 = $FD18 +TIMER7 = $FD1C +HTIMER = TIMER0 ; horizontal line timer (timer 0) +VTIMER = TIMER2 ; vertical blank timer (timer 2) +STIMER = TIMER7 ; sound timer (timer 7) -HTIMBKUP = $FD00 ; horizontal line timer (timer 0) -HTIMCTLA = $FD01 -HTIMCNT = $FD02 -HTIMCTLB = $FD03 -VTIMBKUP = $FD08 ; vertical blank timer (timer 2) -VTIMCTLA = $FD09 -VTIMCNT = $FD0A -VTIMCTLB = $FD0B -BAUDBKUP = $FD10 ; serial timer (timer 4) -STIMBKUP = $FD1C ; sound timer (timer 7) -STIMCTLA = $FD1D -STIMCNT = $FD1E -STIMCTLB = $FD1F +HTIMBKUP = $FD00 ; horizontal line timer (timer 0) +HTIMCTLA = $FD01 +HTIMCNT = $FD02 +HTIMCTLB = $FD03 +VTIMBKUP = $FD08 ; vertical blank timer (timer 2) +VTIMCTLA = $FD09 +VTIMCNT = $FD0A +VTIMCTLB = $FD0B +BAUDBKUP = $FD10 ; serial timer (timer 4) +STIMBKUP = $FD1C ; sound timer (timer 7) +STIMCTLA = $FD1D +STIMCNT = $FD1E +STIMCTLB = $FD1F -TIM0BKUP = $FD00 -TIM0CTLA = $FD01 -TIM0CNT = $FD02 -TIM0CTLB = $FD03 -TIM1BKUP = $FD04 -TIM1CTLA = $FD05 -TIM1CNT = $FD06 -TIM1CTLB = $FD07 -TIM2BKUP = $FD08 -TIM2CTLA = $FD09 -TIM2CNT = $FD0A -TIM2CTLB = $FD0B -TIM3BKUP = $FD0C -TIM3CTLA = $FD0D -TIM3CNT = $FD0E -TIM3CTLB = $FD0F -TIM4BKUP = $FD10 -TIM4CTLA = $FD11 -TIM4CNT = $FD12 -TIM4CTLB = $FD13 -TIM5BKUP = $FD14 -TIM5CTLA = $FD15 -TIM5CNT = $FD16 -TIM5CTLB = $FD17 -TIM6BKUP = $FD18 -TIM6CTLA = $FD19 -TIM6CNT = $FD1A -TIM6CTLB = $FD1B -TIM7BKUP = $FD1C -TIM7CTLA = $FD1D -TIM7CNT = $FD1E -TIM7CTLB = $FD1F +TIM0BKUP = $FD00 +TIM0CTLA = $FD01 +TIM0CNT = $FD02 +TIM0CTLB = $FD03 +TIM1BKUP = $FD04 +TIM1CTLA = $FD05 +TIM1CNT = $FD06 +TIM1CTLB = $FD07 +TIM2BKUP = $FD08 +TIM2CTLA = $FD09 +TIM2CNT = $FD0A +TIM2CTLB = $FD0B +TIM3BKUP = $FD0C +TIM3CTLA = $FD0D +TIM3CNT = $FD0E +TIM3CTLB = $FD0F +TIM4BKUP = $FD10 +TIM4CTLA = $FD11 +TIM4CNT = $FD12 +TIM4CTLB = $FD13 +TIM5BKUP = $FD14 +TIM5CTLA = $FD15 +TIM5CNT = $FD16 +TIM5CTLB = $FD17 +TIM6BKUP = $FD18 +TIM6CTLA = $FD19 +TIM6CNT = $FD1A +TIM6CTLB = $FD1B +TIM7BKUP = $FD1C +TIM7CTLA = $FD1D +TIM7CNT = $FD1E +TIM7CTLB = $FD1F ; Timer offsets TIM_BACKUP = 0 @@ -212,7 +249,6 @@ RESET_DONE = %01000000 ENABLE_RELOAD = %00010000 ENABLE_COUNT = %00001000 AUD_CLOCK_MASK = %00000111 - ; Clock settings AUD_LINKING = %00000111 AUD_64 = %00000110 @@ -278,15 +314,16 @@ ENABLE_INTEGRATE = %00100000 ; Stereo capability does not exist in all Lynxes ; Left and right may be reversed, and if so will be corrected in a later ; release +ATTENREG0 = $FD40 ; Stereo attenuation registers +ATTENREG1 = $FD41 +ATTENREG2 = $FD42 +ATTENREG3 = $FD43 -ATTENREG0 = $FD40 ; Stereo attenuation registers -ATTENREG1 = $FD41 -ATTENREG2 = $FD42 -ATTENREG3 = $FD43 +MPAN = $FD44 +MSTEREO = $FD50 +; Bit definitions for MPAN and MSTEREO registers LEFT_ATTENMASK = %11110000 RIGHT_ATTENMASK = %00001111 - -; Bit definitions for MPAN and MSTEREO registers LEFT3_SELECT = %10000000 LEFT2_SELECT = %01000000 LEFT1_SELECT = %00100000 @@ -296,13 +333,10 @@ RIGHT2_SELECT = %00000100 RIGHT1_SELECT = %00000010 RIGHT0_SELECT = %00000001 -MPAN = $FD44 -MSTEREO = $FD50 - ; Mikey interrupts -INTRST = $FD80 -INTSET = $FD81 +INTRST = $FD80 +INTSET = $FD81 ; Interrupt bits in INTRST and INTSET TIMER0_INTERRUPT = %00000001 From 336c4287c5dc523144315cb40af07db1d9e79ffe Mon Sep 17 00:00:00 2001 From: Alex Thissen <athissen@killer-apps2.nl> Date: Fri, 9 Aug 2024 15:17:26 +0200 Subject: [PATCH 277/707] Missed some dangles spaces --- asminc/lynx.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index 458cd650f..542393847 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -159,7 +159,7 @@ BUTTON_INNER = 0x02 BUTTON_OUTER = 0x01 SWITCHES = $FCB1 -; SWITCHES bit definitions +; SWITCHES bit definitions CART1_IO_INACTIVE = 0x04 CART0_IO_INACTIVE = 0x02 BUTTON_PAUSE = 0x01 @@ -377,7 +377,7 @@ EXTERNAL_POWER = %00000001 SERCTL = $FD8C ; SERCTL bit definitions for write operations -TXINTEN = %10000000 +TXINTEN = %10000000 RXINTEN = %01000000 PAREN = %00010000 RESETERR = %00001000 From 489989f4c8eabf8b42cae6d6f62ab90d37f652b2 Mon Sep 17 00:00:00 2001 From: Alex Thissen <athissen@killer-apps2.nl> Date: Fri, 9 Aug 2024 15:28:54 +0200 Subject: [PATCH 278/707] Changed 0x hex values to % binary values --- asminc/lynx.inc | 52 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/asminc/lynx.inc b/asminc/lynx.inc index 542393847..150bee6d1 100644 --- a/asminc/lynx.inc +++ b/asminc/lynx.inc @@ -130,39 +130,39 @@ EVER_ON = %00000100 ; everon detector enable SPRSYS = $FC92 ; SPRSYS bit definitions for write operations -SIGNMATH = 0x80 ; signed math -ACCUMULATE = 0x40 ; accumulate multiplication results -NO_COLLIDE = 0x20 ; do not collide with any sprites (also SPRCOLL bit definition) -VSTRETCH = 0x10 ; stretch v -LEFTHAND = 0x08 -CLR_UNSAFE = 0x04 ; unsafe access reset -SPRITESTOP = 0x02 ; request to stop sprite process +SIGNMATH = %10000000 ; signed math +ACCUMULATE = %01000000 ; accumulate multiplication results +NO_COLLIDE = %00100000 ; do not collide with any sprites (also SPRCOLL bit definition) +VSTRETCH = %00010000 ; stretch v +LEFTHAND = %00001000 +CLR_UNSAFE = %00000100 ; unsafe access reset +SPRITESTOP = %00000010 ; request to stop sprite process ; SPRSYS bit definitions for read operations -MATHWORKING = 0x80 ; math operation in progress -MATHWARNING = 0x40 ; accumulator overflow on multiple or divide by zero -MATHCARRY = 0x20 ; last carry bit -VSTRETCHING = 0x10 -LEFTHANDED = 0x08 -UNSAFE_ACCESS = 0x04 ; unsafe access performed -SPRITETOSTOP = 0x02 ; requested to stop -SPRITEWORKING = 0x01 ; sprite process is active +MATHWORKING = %10000000 ; math operation in progress +MATHWARNING = %01000000 ; accumulator overflow on multiple or divide by zero +MATHCARRY = %00100000 ; last carry bit +VSTRETCHING = %00010000 +LEFTHANDED = %00001000 +UNSAFE_ACCESS = %00000100 ; unsafe access performed +SPRITETOSTOP = %00000010 ; requested to stop +SPRITEWORKING = %00000001 ; sprite process is active JOYSTICK = $FCB0 ; JOYSTICK bit definitions -JOYPAD_UP = 0x80 -JOYPAD_DOWN = 0x40 -JOYPAD_LEFT = 0x20 -JOYPAD_RIGHT = 0x10 -BUTTON_OPTION1 = 0x08 -BUTTON_OPTION2 = 0x04 -BUTTON_INNER = 0x02 -BUTTON_OUTER = 0x01 +JOYPAD_UP = %10000000 +JOYPAD_DOWN = %01000000 +JOYPAD_LEFT = %00100000 +JOYPAD_RIGHT = %00010000 +BUTTON_OPTION1 = %00001000 +BUTTON_OPTION2 = %00000100 +BUTTON_INNER = %00000010 +BUTTON_OUTER = %00000001 SWITCHES = $FCB1 ; SWITCHES bit definitions -CART1_IO_INACTIVE = 0x04 -CART0_IO_INACTIVE = 0x02 -BUTTON_PAUSE = 0x01 +CART1_IO_INACTIVE = %00000100 +CART0_IO_INACTIVE = %00000010 +BUTTON_PAUSE = %00000001 RCART0 = $FCB2 RCART1 = $FCB3 From 1f1a004a050fe74e030fcf3b9dfe34faad4c9645 Mon Sep 17 00:00:00 2001 From: Alex Thissen <athissen@killer-apps2.nl> Date: Fri, 9 Aug 2024 15:54:05 +0200 Subject: [PATCH 279/707] Minor tweaks to Suzy struct types. Named math union --- include/_suzy.h | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/include/_suzy.h b/include/_suzy.h index 29a263880..41029a071 100644 --- a/include/_suzy.h +++ b/include/_suzy.h @@ -258,28 +258,28 @@ struct _math_divide { /* Suzy Hardware Registers */ struct __suzy { - unsigned char *tmpadr; // 0xFC00 Temporary address - unsigned int tiltacc; // 0xFC02 Tilt accumulator - unsigned int hoff; // 0xFC04 Offset to H edge of screen - unsigned int voff; // 0xFC06 Offset to V edge of screen + unsigned char *tmpadr; // 0xFC00 Temporary address + unsigned int tiltacc; // 0xFC02 Tilt accumulator + unsigned int hoff; // 0xFC04 Offset to H edge of screen + unsigned int voff; // 0xFC06 Offset to V edge of screen unsigned char *sprbase; // 0xFC08 Base address of sprite unsigned char *colbase; // 0xFC0A Base address of collision buffer unsigned char *vidadr; // 0xFC0C Current vid buffer address unsigned char *coladr; // 0xFC0E Current col buffer address unsigned char *scbnext; // 0xFC10 Address of next SCB unsigned char *sprdline; // 0xFC12 start of sprite data line address - unsigned char *hposstrt; // 0xFC14 start hpos - unsigned char *vposstrt; // 0xFC16 start vpos - unsigned char *sprhsize; // 0xFC18 sprite h size - unsigned char *sprvsize; // 0xFC1A sprite v size - unsigned int stretchl; // 0xFC1C H size adder - unsigned int tilt; // 0xFC1E H pos adder - unsigned int sprdoff; // 0xFC20 offset to next sprite data line - unsigned int sprvpos; // 0xFC22 current vpos - unsigned int colloff; // 0xFC24 offset to collision depository - unsigned int vsizeacc; // 0xFC26 vertical size accumulator - unsigned int hsizeoff; // 0xFC28 horizontal size offset - unsigned int vsizeoff; // 0xFC2A vertical size offset + unsigned int hposstrt; // 0xFC14 start hpos + unsigned int vposstrt; // 0xFC16 start vpos + unsigned int sprhsize; // 0xFC18 sprite h size + unsigned int sprvsize; // 0xFC1A sprite v size + unsigned int stretchl; // 0xFC1C H size adder + unsigned int tilt; // 0xFC1E H pos adder + unsigned int sprdoff; // 0xFC20 offset to next sprite data line + unsigned int sprvpos; // 0xFC22 current vpos + unsigned int colloff; // 0xFC24 offset to collision depository + unsigned int vsizeacc; // 0xFC26 vertical size accumulator + unsigned int hsizeoff; // 0xFC28 horizontal size offset + unsigned int vsizeoff; // 0xFC2A vertical size offset unsigned char *scbaddr; // 0xFC2C address of current SCB unsigned char *procaddr; // 0xFC2E address of current spr data proc unsigned char unused0[32]; // 0xFC30 - 0xFC4F reserved/unused @@ -306,7 +306,7 @@ struct __suzy { struct _math_unsigned_multiply unsigned_multiply; struct _math_signed_multiply signed_multiply; struct _math_divide divide; - }; + } math; unsigned char unused4[16]; // 0xFC70 - 0xFC7F do not use unsigned char sprctl0; // 0xFC80 sprite control bits 0 unsigned char sprctl1; // 0xFC81 sprite control bits 1 From 0c018919fea8d0fc742311c0e37845a38df0f2df Mon Sep 17 00:00:00 2001 From: Alex Thissen <athissen@killer-apps.nl> Date: Mon, 28 Oct 2024 14:20:09 +0100 Subject: [PATCH 280/707] Removed union and structures for Suzy math --- include/_suzy.h | 76 +++++++++++++------------------------------------ 1 file changed, 20 insertions(+), 56 deletions(-) diff --git a/include/_suzy.h b/include/_suzy.h index 41029a071..5f4909012 100644 --- a/include/_suzy.h +++ b/include/_suzy.h @@ -227,36 +227,7 @@ enum { SPRITEWORKING = 0x01 // sprite process is active }; -// Structures for math registers -struct _math_unsigned_multiply { - unsigned int factor1; // 0xFC52 - 0xFC53 - unsigned int factor2; // 0xFC54 - 0xFC55 write starts multiply - unsigned char unused2[10]; // 0xFC56 - 0xFC5F do not use - unsigned long product; // 0xFC60 - 0xFC63 - unsigned char unused3[8]; // 0xFC64 - 0xFC6B do not use - unsigned long accumulate; // 0xFC6C - 0xFC6F -}; - -struct _math_signed_multiply { - int factor1; // 0xFC52 - 0xFC53 - int factor2; // 0xFC54 - 0xFC55 write starts multiply - unsigned char unused2[10]; // 0xFC56 - 0xFC5F do not use - long product; // 0xFC60 - 0xFC63 - unsigned char unused3[8]; // 0xFC64 - 0xFC6B do not use - long accumulate; // 0xFC6C - 0xFC6F -}; - -struct _math_divide { - unsigned long quotient; // 0xFC52 - 0xFC55 - unsigned int divisor; // 0xFC56 - 0xFC57 - unsigned char unused2[8]; // 0xFC58 - 0xFC5F do not use - unsigned int dividend2; // 0xFC60 - 0xFC61 - unsigned int dividend1; // 0xFC62 - 0xFC63 write starts divide - unsigned char unused3[8]; // 0xFC64 - 0xFC6B do not use - unsigned long remainder; // 0xFC6C - 0xFC6F -}; - -/* Suzy Hardware Registers */ +// Suzy hardware registers struct __suzy { unsigned char *tmpadr; // 0xFC00 Temporary address unsigned int tiltacc; // 0xFC02 Tilt accumulator @@ -284,29 +255,22 @@ struct __suzy { unsigned char *procaddr; // 0xFC2E address of current spr data proc unsigned char unused0[32]; // 0xFC30 - 0xFC4F reserved/unused unsigned char unused1[2]; // 0xFC50 - 0xFC51 do not use - union { - struct { - unsigned char mathd; // 0xFC52 - unsigned char mathc; // 0xFC53 - unsigned char mathb; // 0xFC54 - unsigned char matha; // 0xFC55 write starts a multiply operation - unsigned char mathp; // 0xFC56 - unsigned char mathn; // 0xFC57 - unsigned char unused2[8]; // 0xFC58 - 0xFC5F do not use - unsigned char mathh; // 0xFC60 - unsigned char mathg; // 0xFC61 - unsigned char mathf; // 0xFC62 - unsigned char mathe; // 0xFC63 write starts a divide operation - unsigned char unused3[8]; // 0xFC64 - 0xFC6B do not use - unsigned char mathm; // 0xFC6C - unsigned char mathl; // 0xFC6D - unsigned char mathk; // 0xFC6E - unsigned char mathj; // 0xFC6F - }; - struct _math_unsigned_multiply unsigned_multiply; - struct _math_signed_multiply signed_multiply; - struct _math_divide divide; - } math; + unsigned char mathd; // 0xFC52 + unsigned char mathc; // 0xFC53 + unsigned char mathb; // 0xFC54 + unsigned char matha; // 0xFC55 write starts a multiply operation + unsigned char mathp; // 0xFC56 + unsigned char mathn; // 0xFC57 + unsigned char unused2[8]; // 0xFC58 - 0xFC5F do not use + unsigned char mathh; // 0xFC60 + unsigned char mathg; // 0xFC61 + unsigned char mathf; // 0xFC62 + unsigned char mathe; // 0xFC63 write starts a divide operation + unsigned char unused3[8]; // 0xFC64 - 0xFC6B do not use + unsigned char mathm; // 0xFC6C + unsigned char mathl; // 0xFC6D + unsigned char mathk; // 0xFC6E + unsigned char mathj; // 0xFC6F unsigned char unused4[16]; // 0xFC70 - 0xFC7F do not use unsigned char sprctl0; // 0xFC80 sprite control bits 0 unsigned char sprctl1; // 0xFC81 sprite control bits 1 @@ -333,9 +297,7 @@ struct __suzy { // 0xFCC5 - 0xFCFF unused }; -// Deprecated definitions - -/* Hardware Math */ +// Hardware math registers #define FACTOR_A *(unsigned int *) 0xFC54 #define FACTOR_B *(unsigned int *) 0xFC52 #define PRODUCT0 *(unsigned int *) 0xFC60 @@ -353,6 +315,8 @@ struct __suzy { #define REMAINDER1 *(unsigned int *) 0xFC6E #define REMAINDER *(long *) 0xFC6C +// Deprecated definitions + /* MAPCTL $FFF9 */ #define HIGHSPEED 0x80 #define VECTORSPACE 0x08 From 3dad6c76fad020c2ffa21be9619bfa8119c3df0f Mon Sep 17 00:00:00 2001 From: Alex Thissen <athissen@killer-apps.nl> Date: Sat, 9 Nov 2024 12:01:22 +0100 Subject: [PATCH 281/707] Changed to C style comments --- include/_mikey.h | 30 +++++++++++++++--------------- include/_suzy.h | 47 ++++++++++++++++++++++++++++------------------- include/lynx.h | 10 +++++----- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/include/_mikey.h b/include/_mikey.h index 9a50745b2..05212aac9 100644 --- a/include/_mikey.h +++ b/include/_mikey.h @@ -109,7 +109,7 @@ struct __mikey { } vectors; }; -// TIM_CONTROLA control bit definitions +/* TIM_CONTROLA control bit definitions */ enum { ENABLE_INT = 0x80, RESET_DONE = 0x40, @@ -117,13 +117,13 @@ enum { ENABLE_COUNT = 0x08 }; -// AUD_CONTROL control bit definitions +/* AUD_CONTROL control bit definitions */ enum { FEEDBACK_7 = 0x80, ENABLE_INTEGRATE = 0x20 }; -// Audio and timer clock settings for source period +/* Audio and timer clock settings for source period */ enum { AUD_LINKING = 0x07, AUD_64 = 0x06, @@ -135,7 +135,7 @@ enum { AUD_1 = 0x00 }; -// TIM_CONTROLB control bit definitions +/* TIM_CONTROLB control bit definitions */ enum { TIMER_DONE = 0x08, LAST_CLOCK = 0x04, @@ -143,7 +143,7 @@ enum { BORROW_OUT = 0x01 }; -// MPAN and MSTEREO registers bit definitions +/* MPAN and MSTEREO registers bit definitions */ enum { LEFT3_SELECT = 0x80, LEFT2_SELECT = 0x40, @@ -157,7 +157,7 @@ enum { RIGHT_ATTENMASK = 0x0F }; -// Interrupt Reset and Set bit definitions +/* Interrupt Reset and Set bit definitions */ enum { TIMER7_INT = 0x80, TIMER6_INT = 0x40, @@ -172,13 +172,13 @@ enum { HORIZONTAL_INT = TIMER0_INT }; -// SYSCTL1 bit definitions +/* SYSCTL1 bit definitions */ enum { POWERON = 0x02, CART_ADDR_STROBE = 0x01 }; -// IODIR and IODAT bit definitions +/* IODIR and IODAT bit definitions */ enum { AUDIN_BIT = 0x10, // different from AUDIN address READ_ENABLE = 0x10, // same bit for AUDIN_BIT @@ -189,7 +189,7 @@ enum { EXTERNAL_POWER = 0x01 }; -// SERCTL bit definitions for write operations +/* SERCTL bit definitions for write operations */ enum { TXINTEN = 0x80, RXINTEN = 0x40, @@ -200,7 +200,7 @@ enum { PAREVEN = 0x01 }; -// SERCTL bit definitions for read operations +/* SERCTL bit definitions for read operations */ enum { TXRDY = 0x80, RXRDY = 0x40, @@ -212,7 +212,7 @@ enum { PARBIT = 0x01 }; -// DISPCTL bit definitions +/* DISPCTL bit definitions */ enum { DISP_COLOR = 0x08, // must be set to 1 DISP_FOURBIT = 0x04, // must be set to 1 @@ -220,7 +220,7 @@ enum { DMA_ENABLE = 0x01 // must be set to 1 }; -// MTEST0 bit definitions +/* MTEST0 bit definitions */ enum { AT_CNT16 = 0x80, AT_TEST = 0x40, @@ -232,7 +232,7 @@ enum { CPU_TEST = 0x01 }; -// MTEST1 bit definitions +/* MTEST1 bit definitions */ enum { P_CNT16 = 0x40, REF_CNT16 = 0x20, @@ -243,7 +243,7 @@ enum { REF_DIS = 0x01 }; -// MTEST2 bit definitions +/* MTEST2 bit definitions */ enum { V_STROBE = 0x10, V_ZERO = 0x08, @@ -252,7 +252,7 @@ enum { V_BLANKEF = 0x01 }; -// MAPCTL bit definitions +/* MAPCTL bit definitions */ enum { TURBO_DISABLE = 0x80, VECTOR_SPACE = 0x08, diff --git a/include/_suzy.h b/include/_suzy.h index 5f4909012..a9d5ddd7b 100644 --- a/include/_suzy.h +++ b/include/_suzy.h @@ -27,7 +27,7 @@ #ifndef __SUZY_H #define __SUZY_H -// JOYSTICK bit definitions +/* JOYSTICK bit definitions */ enum { JOYPAD_RIGHT = 0x10, JOYPAD_LEFT = 0x20, @@ -39,14 +39,14 @@ enum { BUTTON_OUTER = 0x01 }; -// SWITCHES bit definitions +/* SWITCHES bit definitions */ enum { CART1_IO_INACTIVE = 0x04, CART0_IO_INACTIVE = 0x02, BUTTON_PAUSE = 0x01 }; -// SPRCTL0 bit definitions +/* SPRCTL0 bit definitions */ enum { BPP_4 = 0xC0, BPP_3 = 0x80, @@ -64,7 +64,7 @@ enum { TYPE_BACKGROUND = 0x00 }; -// SPRCTL1 bit definitions +/* SPRCTL1 bit definitions */ enum { LITERAL = 0x80, PACKED = 0x00, @@ -79,9 +79,10 @@ enum { DRAWLEFT = 0x01 }; -// Sprite control block (SCB) definitions +/* Sprite control block (SCB) definitions */ -typedef struct SCB_REHVST_PAL { // SCB with all attributes +/* SCB with all attributes */ +typedef struct SCB_REHVST_PAL { unsigned char sprctl0; unsigned char sprctl1; unsigned char sprcoll; @@ -96,7 +97,8 @@ typedef struct SCB_REHVST_PAL { // SCB with all attributes unsigned char penpal[8]; } SCB_REHVST_PAL; -typedef struct SCB_REHVST { // SCB without pallette +/* SCB without pallette */ +typedef struct SCB_REHVST { unsigned char sprctl0; unsigned char sprctl1; unsigned char sprcoll; @@ -110,7 +112,8 @@ typedef struct SCB_REHVST { // SCB without pallette unsigned int tilt; } SCB_REHVST; -typedef struct SCB_REHV { // SCB without stretch/tilt +/* SCB without stretch/tilt */ +typedef struct SCB_REHV { unsigned char sprctl0; unsigned char sprctl1; unsigned char sprcoll; @@ -122,7 +125,8 @@ typedef struct SCB_REHV { // SCB without stretch/tilt unsigned int vsize; } SCB_REHV; -typedef struct SCB_REHV_PAL { // SCB without str/tilt, w/ penpal +/* SCB without stretch/tilt, with penpal */ +typedef struct SCB_REHV_PAL { unsigned char sprctl0; unsigned char sprctl1; unsigned char sprcoll; @@ -135,7 +139,8 @@ typedef struct SCB_REHV_PAL { // SCB without str/tilt, w/ penpal unsigned char penpal[8]; } SCB_REHV_PAL; -typedef struct SCB_REHVS { // SCB w/o tilt & penpal +/* SCB without tilt/penpal */ +typedef struct SCB_REHVS { unsigned char sprctl0; unsigned char sprctl1; unsigned char sprcoll; @@ -148,7 +153,8 @@ typedef struct SCB_REHVS { // SCB w/o tilt & penpal unsigned int stretch; } SCB_REHVS; -typedef struct SCB_REHVS_PAL { // SCB w/o tilt w/penpal +/* SCB without tilt, with penpal */ +typedef struct SCB_REHVS_PAL { unsigned char sprctl0; unsigned char sprctl1; unsigned char sprcoll; @@ -162,7 +168,8 @@ typedef struct SCB_REHVS_PAL { // SCB w/o tilt w/penpal unsigned char penpal[8]; } SCB_REHVS_PAL; -typedef struct SCB_RENONE { // SCB w/o size/stretch/tilt/pal +/* SCB without size/stretch/tilt/penpal */ +typedef struct SCB_RENONE { unsigned char sprctl0; unsigned char sprctl1; unsigned char sprcoll; @@ -172,7 +179,8 @@ typedef struct SCB_RENONE { // SCB w/o size/stretch/tilt/pal signed int vpos; } SCB_RENONE; -typedef struct SCB_RENONE_PAL { // SCB w/o size/str/tilt w/penpal +/* SCB without size/str/tilt, with penpal */ +typedef struct SCB_RENONE_PAL { unsigned char sprctl0; unsigned char sprctl1; unsigned char sprcoll; @@ -199,13 +207,13 @@ typedef struct PENPAL_1 { unsigned char penpal[1]; } PENPAL_1; -// SPRGO bit definitions +/* SPRGO bit definitions */ enum { SPRITE_GO = 0x01, // sprite process start bit EVER_ON = 0x04 // everon detector enable }; -// SPRSYS bit definitions for write operations +/* SPRSYS bit definitions for write operations */ enum { SIGNMATH = 0x80, // signed math ACCUMULATE = 0x40, // accumulate multiplication results @@ -215,7 +223,8 @@ enum { CLR_UNSAFE = 0x04, // unsafe access reset SPRITESTOP = 0x02 // request to stop sprite process }; -// SPRSYS bit definitions for read operations + +/* SPRSYS bit definitions for read operations */ enum { MATHWORKING = 0x80, // math operation in progress MATHWARNING = 0x40, // accumulator overflow on multiple or divide by zero @@ -227,7 +236,7 @@ enum { SPRITEWORKING = 0x01 // sprite process is active }; -// Suzy hardware registers +/* Suzy hardware registers */ struct __suzy { unsigned char *tmpadr; // 0xFC00 Temporary address unsigned int tiltacc; // 0xFC02 Tilt accumulator @@ -297,7 +306,7 @@ struct __suzy { // 0xFCC5 - 0xFCFF unused }; -// Hardware math registers +/* Hardware math registers */ #define FACTOR_A *(unsigned int *) 0xFC54 #define FACTOR_B *(unsigned int *) 0xFC52 #define PRODUCT0 *(unsigned int *) 0xFC60 @@ -315,7 +324,7 @@ struct __suzy { #define REMAINDER1 *(unsigned int *) 0xFC6E #define REMAINDER *(long *) 0xFC6C -// Deprecated definitions +/* Deprecated definitions */ /* MAPCTL $FFF9 */ #define HIGHSPEED 0x80 diff --git a/include/lynx.h b/include/lynx.h index e2c0c503f..fe4006461 100644 --- a/include/lynx.h +++ b/include/lynx.h @@ -79,12 +79,12 @@ /* No support for dynamically loadable drivers */ #define DYN_DRV 0 -// Addresses of static drivers +/* Addresses of static drivers */ extern void lynx_stdjoy_joy[]; // Referred to by joy_static_stddrv[] extern void lynx_comlynx_ser[]; // Referred to by ser_static_stddrv[] extern void lynx_160_102_16_tgi[]; // Referred to by tgi_static_stddrv[] -// Sound support +/* Sound support */ void lynx_snd_init (void); // Initialize the sound driver void lynx_snd_pause (void); // Pause sound void lynx_snd_continue (void); // Continue sound after pause @@ -93,18 +93,18 @@ void lynx_snd_stop (void); // Stop sound on all channels void __fastcall__ lynx_snd_stop_channel (unsigned char channel); // Stop sound on all channels unsigned char lynx_snd_active(void); // Show which channels are active -// Cartridge access +/* Cartridge access */ void __fastcall__ lynx_load (int file_number); // Load a file into RAM using a zero-based index void __fastcall__ lynx_exec (int file_number); // Load a file into ram and execute it -// EEPROM access +/* EEPROM access */ unsigned __fastcall__ lynx_eeprom_read (unsigned char cell); // Read a 16 bit word from the given address unsigned __fastcall__ lynx_eeprom_write (unsigned char cell, unsigned val); // Write the word at the given address void __fastcall__ lynx_eeprom_erase (unsigned char cell); // Clear the word at the given address unsigned __fastcall__ lynx_eeread (unsigned cell); // Read a 16 bit word from the given address 93C46, 93C66 or 93C86 unsigned __fastcall__ lynx_eewrite (unsigned cell, unsigned val); // Write the word at the given address 93C46, 93C66 or 93C86 -// TGI extras +/* TGI extras */ #define tgi_sprite(spr) tgi_ioctl(0, spr) #define tgi_flip() tgi_ioctl(1, (void*)0) #define tgi_setbgcolor(bgcol) tgi_ioctl(2, (void*)(bgcol)) From 40369124636a150a841024f6cf2e44b49a082416 Mon Sep 17 00:00:00 2001 From: Alex Thissen <athissen@killer-apps.nl> Date: Sat, 9 Nov 2024 12:06:37 +0100 Subject: [PATCH 282/707] Fix to trailing whitespace --- include/_suzy.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/_suzy.h b/include/_suzy.h index a9d5ddd7b..5de8ad678 100644 --- a/include/_suzy.h +++ b/include/_suzy.h @@ -113,7 +113,7 @@ typedef struct SCB_REHVST { } SCB_REHVST; /* SCB without stretch/tilt */ -typedef struct SCB_REHV { +typedef struct SCB_REHV { unsigned char sprctl0; unsigned char sprctl1; unsigned char sprcoll; @@ -180,7 +180,7 @@ typedef struct SCB_RENONE { } SCB_RENONE; /* SCB without size/str/tilt, with penpal */ -typedef struct SCB_RENONE_PAL { +typedef struct SCB_RENONE_PAL { unsigned char sprctl0; unsigned char sprctl1; unsigned char sprcoll; From 819a3145082994603efd00498c7bb883e26403db Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Sat, 9 Nov 2024 18:09:09 +0100 Subject: [PATCH 283/707] Apple2: Rewrite opendir in assembly 58 bytes size gain --- libsrc/apple2/dir.inc | 15 ++++ libsrc/apple2/opendir.c | 112 ----------------------------- libsrc/apple2/opendir.s | 156 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 112 deletions(-) create mode 100644 libsrc/apple2/dir.inc delete mode 100644 libsrc/apple2/opendir.c create mode 100644 libsrc/apple2/opendir.s diff --git a/libsrc/apple2/dir.inc b/libsrc/apple2/dir.inc new file mode 100644 index 000000000..afad44eb7 --- /dev/null +++ b/libsrc/apple2/dir.inc @@ -0,0 +1,15 @@ +.struct DIR + FD .word + ENTRY_LENGTH .byte + ENTRIES_PER_BLOCK .byte + CURRENT_ENTRY .byte + + .union + BYTES .byte 512 + .struct CONTENT + PREV_BLOCK .word + NEXT_BLOCK .word + ENTRIES .byte + .endstruct + .endunion +.endstruct diff --git a/libsrc/apple2/opendir.c b/libsrc/apple2/opendir.c deleted file mode 100644 index 1144d8511..000000000 --- a/libsrc/apple2/opendir.c +++ /dev/null @@ -1,112 +0,0 @@ -/*****************************************************************************/ -/* */ -/* opendir.h */ -/* */ -/* Open a directory */ -/* */ -/* */ -/* */ -/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include <stddef.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <dirent.h> -#include "dir.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -extern char _cwd[FILENAME_MAX]; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -DIR* __fastcall__ opendir (register const char* name) -{ - register DIR* dir; - - /* Alloc DIR */ - if ((dir = malloc (sizeof (*dir))) == NULL) { - - /* May not have been done by malloc() */ - _directerrno (ENOMEM); - - /* Return failure */ - return NULL; - } - - /* Interpret dot as current working directory */ - if (*name == '.') { - name = _cwd; - } - - /* Open directory file */ - if ((dir->fd = open (name, O_RDONLY)) != -1) { - - /* Read directory key block */ - if (read (dir->fd, - dir->block.bytes, - sizeof (dir->block)) == sizeof (dir->block)) { - - /* Get directory entry infos from directory header */ - dir->entry_length = dir->block.bytes[0x23]; - dir->entries_per_block = dir->block.bytes[0x24]; - - /* Skip directory header entry */ - dir->current_entry = 1; - - /* Return success */ - return dir; - } - - /* EOF: Most probably no directory file at all */ - if (_oserror == 0) { - _directerrno (EINVAL); - } - - /* Cleanup directory file */ - close (dir->fd); - } - - /* Cleanup DIR */ - free (dir); - - /* Return failure */ - return NULL; -} diff --git a/libsrc/apple2/opendir.s b/libsrc/apple2/opendir.s new file mode 100644 index 000000000..b75b83636 --- /dev/null +++ b/libsrc/apple2/opendir.s @@ -0,0 +1,156 @@ +; +; Colin Leroy-Mira <colin@colino.net>, 2024 +; +; DIR* __fastcall__ opendir (register const char* name) +; + + .export _opendir + + .import _open, _read, _close + .import _malloc, _free + .import ___directerrno + + .import ___oserror, __cwd + + .import pushptr1, popptr1 + .import pushax, pusha0 + + .importzp ptr1 + + .include "apple2.inc" + .include "dir.inc" + .include "errno.inc" + .include "fcntl.inc" + .include "zeropage.inc" + +.proc _opendir + sta ptr1 + stx ptr1+1 + + ldy #$00 + lda (ptr1),y + cmp #'.' + bne :+ + + lda #<__cwd + ldx #>__cwd + sta ptr1 + stx ptr1+1 + +: ; open directory + jsr pushptr1 + lda #O_RDONLY + jsr pusha0 + + ldy #$04 + jsr _open + + cmp #$FF ; Did we succeed? + beq @return_null + pha ; Yes - Push fd for backup + + ; malloc the dir struct + lda #<.sizeof(DIR) + ldx #>.sizeof(DIR) + jsr _malloc + bne :+ + + ; We failed to allocate + pla ; Get fd back + ldx #$00 + jsr _close ; close it + + lda #ENOMEM ; Set error + jsr ___directerrno + +@return_null: + lda #$00 + tax + rts + +: ; Store dir struct to pointer + sta ptr1 + stx ptr1+1 + + ; Push ptr1, read will destroy it + jsr pushptr1 + + ; Save fd to dir struct + lda #$00 + ldy #DIR::FD + 1 + sta (ptr1),y + + dey + pla ; Get fd back + sta (ptr1),y + + jsr pusha0 ; push fd for read + lda #<DIR::BYTES + clc + adc ptr1 + pha + lda #>DIR::BYTES + adc ptr1+1 + tax + pla + jsr pushax ; Push dir->block.bytes for read + + lda #<.sizeof(DIR::BYTES) + ldx #>.sizeof(DIR::BYTES) + + jsr _read ; Read directory block + cpx #>.sizeof(DIR::BYTES) + bne @err_read + cmp #<.sizeof(DIR::BYTES) + beq @read_ok + +@err_read: + ; Read failed, exit + lda ___oserror + bne :+ + lda #EINVAL + jsr ___directerrno + +: ; Close fd + jsr popptr1 ; Restore our dir pointer + ldy #$00 + lda (ptr1),y ; Get fd + ldx #$00 + jsr _close + + ; Free dir structure + lda ptr1 + ldx ptr1+1 + jsr _free + jmp @return_null + +@read_ok: + ; Read succeeded, populate dir struct + jsr popptr1 ; Restore our dir pointer + + ldy #$24 + DIR::BYTES + lda (ptr1),y ; ENTRIES_PER_BLOCK + pha ; Back it up + + dey + lda (ptr1),y ; ENTRY_LENGTH + + ldy #DIR::ENTRY_LENGTH + sta (ptr1),y + + pla + .assert DIR::ENTRIES_PER_BLOCK = DIR::ENTRY_LENGTH + 1, error + iny + sta (ptr1),y + + ; Skip directory header entry + .assert DIR::CURRENT_ENTRY = DIR::ENTRIES_PER_BLOCK + 1, error + iny + lda #$01 + sta (ptr1),y + + ; Return pointer to dir struct + lda ptr1 + ldx ptr1+1 + rts +.endproc From a945bedefc424f44d205f697ba413fd853854e3d Mon Sep 17 00:00:00 2001 From: Alex Thissen <athissen@killer-apps.nl> Date: Sat, 9 Nov 2024 19:46:11 +0100 Subject: [PATCH 284/707] Replaced all C++ style comments from Lynx include files --- include/_mikey.h | 123 ++++++++++++++++++------------------ include/_suzy.h | 160 +++++++++++++++++++++++------------------------ include/lynx.h | 44 ++++++------- 3 files changed, 163 insertions(+), 164 deletions(-) diff --git a/include/_mikey.h b/include/_mikey.h index 05212aac9..6e16e98ca 100644 --- a/include/_mikey.h +++ b/include/_mikey.h @@ -53,59 +53,59 @@ typedef struct _mikey_audio { /* Define a structure with the mikey register offsets */ struct __mikey { - struct _mikey_timer timer0; // 0xFD00 - struct _mikey_timer timer1; // 0xFD04 - struct _mikey_timer timer2; // 0xFD08 - struct _mikey_timer timer3; // 0xFD0C - struct _mikey_timer timer4; // 0xFD10 - struct _mikey_timer timer5; // 0xFD14 - struct _mikey_timer timer6; // 0xFD18 - struct _mikey_timer timer7; // 0xFD1C - struct _mikey_audio channel_a; // 0xFD20 - struct _mikey_audio channel_b; // 0xFD28 - struct _mikey_audio channel_c; // 0xFD30 - struct _mikey_audio channel_d; // 0xFD38 - unsigned char attena; // 0xFD40 ?? not yet allocated? - unsigned char attenb; // 0xFD41 | - unsigned char attenc; // 0xFD42 | - unsigned char attend; // 0xFD43 | - unsigned char panning; // 0xFD44 | - unsigned char unused0[11]; // 0xFD45 - 0xFD4F not used - unsigned char mstereo; // 0xFD50 stereo control bits - unsigned char unused1[47]; // 0xFD51 - 0xFD7F not used - unsigned char intrst; // 0xFD80 interrupt poll 0 - unsigned char intset; // 0xFD81 interrupt poll 1 - unsigned char unused2[2]; // 0xFD82 - 0xFD83 not used - unsigned char magrdy0; // 0xFD84 mag tape channel0 ready bit - unsigned char magrdy1; // 0xFD85 mag tape channel1 ready bit - unsigned char audin; // 0xFD86 audio in - unsigned char sysctl1; // 0xFD87 control bits - unsigned char mikeyrev; // 0xFD88 mikey hardware rev - unsigned char mikeysrev; // 0xFD89 mikey software rev - unsigned char iodir; // 0xFD8A parallel i/o data dir - unsigned char iodat; // 0xFD8B parallel data - unsigned char serctl; // 0xFD8C serial control register - unsigned char serdat; // 0xFD8D serial data - unsigned char unused3[2]; // 0xFD8E - 0xFD8F not used - unsigned char sdoneack; // 0xFD90 suzy done acknowledge - unsigned char cpusleep; // 0xFD91 cpu bus request disable - unsigned char dispctl; // 0xFD92 video bus request enable, viddma - unsigned char pkbkup; // 0xFD93 magic 'P' count - unsigned char *scrbase; // 0xFD94 start address of video display - unsigned char unused4[6]; // 0xFD96 - 0xFD9B not used - unsigned char mtest0; // 0xFD9C - unsigned char mtest1; // 0xFD9D - unsigned char mtest2; // 0xFD9E - unsigned char unused5; // 0xFD9F not used - unsigned char palette[32]; // 0xFDA0 - 0xFDBF palette 32 bytes - unsigned char unused6[64]; // 0xFDC0 - 0xFDFF not used - unsigned char bootrom[504]; // 0xFE00 - 0xFFD8 boot rom - unsigned char reserved; // 0xFFD8 reserved for future hardware - unsigned char mapctl; // 0xFFF9 map control register + struct _mikey_timer timer0; /* 0xFD00 */ + struct _mikey_timer timer1; /* 0xFD04 */ + struct _mikey_timer timer2; /* 0xFD08 */ + struct _mikey_timer timer3; /* 0xFD0C */ + struct _mikey_timer timer4; /* 0xFD10 */ + struct _mikey_timer timer5; /* 0xFD14 */ + struct _mikey_timer timer6; /* 0xFD18 */ + struct _mikey_timer timer7; /* 0xFD1C */ + struct _mikey_audio channel_a; /* 0xFD20 */ + struct _mikey_audio channel_b; /* 0xFD28 */ + struct _mikey_audio channel_c; /* 0xFD30 */ + struct _mikey_audio channel_d; /* 0xFD38 */ + unsigned char attena; /* 0xFD40 ?? not yet allocated? */ + unsigned char attenb; /* 0xFD41 | */ + unsigned char attenc; /* 0xFD42 | */ + unsigned char attend; /* 0xFD43 | */ + unsigned char panning; /* 0xFD44 | */ + unsigned char unused0[11]; /* 0xFD45 - 0xFD4F not used */ + unsigned char mstereo; /* 0xFD50 stereo control bits */ + unsigned char unused1[47]; /* 0xFD51 - 0xFD7F not used */ + unsigned char intrst; /* 0xFD80 interrupt poll 0 */ + unsigned char intset; /* 0xFD81 interrupt poll 1 */ + unsigned char unused2[2]; /* 0xFD82 - 0xFD83 not used */ + unsigned char magrdy0; /* 0xFD84 mag tape channel0 ready bit */ + unsigned char magrdy1; /* 0xFD85 mag tape channel1 ready bit */ + unsigned char audin; /* 0xFD86 audio in */ + unsigned char sysctl1; /* 0xFD87 control bits */ + unsigned char mikeyrev; /* 0xFD88 mikey hardware rev */ + unsigned char mikeysrev; /* 0xFD89 mikey software rev */ + unsigned char iodir; /* 0xFD8A parallel i/o data dir */ + unsigned char iodat; /* 0xFD8B parallel data */ + unsigned char serctl; /* 0xFD8C serial control register */ + unsigned char serdat; /* 0xFD8D serial data */ + unsigned char unused3[2]; /* 0xFD8E - 0xFD8F not used */ + unsigned char sdoneack; /* 0xFD90 suzy done acknowledge */ + unsigned char cpusleep; /* 0xFD91 cpu bus request disable */ + unsigned char dispctl; /* 0xFD92 video bus request enable, viddma */ + unsigned char pkbkup; /* 0xFD93 magic 'P' count */ + unsigned char *scrbase; /* 0xFD94 start address of video display */ + unsigned char unused4[6]; /* 0xFD96 - 0xFD9B not used */ + unsigned char mtest0; /* 0xFD9C */ + unsigned char mtest1; /* 0xFD9D */ + unsigned char mtest2; /* 0xFD9E */ + unsigned char unused5; /* 0xFD9F not used */ + unsigned char palette[32]; /* 0xFDA0 - 0xFDBF palette 32 bytes */ + unsigned char unused6[64]; /* 0xFDC0 - 0xFDFF not used */ + unsigned char bootrom[504]; /* 0xFE00 - 0xFFD8 boot rom */ + unsigned char reserved; /* 0xFFD8 reserved for future hardware */ + unsigned char mapctl; /* 0xFFF9 map control register */ struct { - unsigned char *nmi; // 0xFFFA NMI vector - unsigned char *reset; // 0xFFFB reset vector - unsigned char *irq; // 0xFFFC IRQ vector + unsigned char *nmi; /* 0xFFFA NMI vector */ + unsigned char *reset; /* 0xFFFB reset vector */ + unsigned char *irq; /* 0xFFFC IRQ vector */ } vectors; }; @@ -180,12 +180,12 @@ enum { /* IODIR and IODAT bit definitions */ enum { - AUDIN_BIT = 0x10, // different from AUDIN address - READ_ENABLE = 0x10, // same bit for AUDIN_BIT + AUDIN_BIT = 0x10, /* different from AUDIN address */ + READ_ENABLE = 0x10, /* same bit for AUDIN_BIT */ RESTLESS = 0x08, - NOEXP = 0x04, // if set, redeye is not connected - CART_ADDR_DATA = 0x02, // - CART_POWER_OFF = 0x02, // same bit for CART_ADDR_DATA + NOEXP = 0x04, /* if set, redeye is not connected */ + CART_ADDR_DATA = 0x02, + CART_POWER_OFF = 0x02, /* same bit for CART_ADDR_DATA */ EXTERNAL_POWER = 0x01 }; @@ -214,10 +214,10 @@ enum { /* DISPCTL bit definitions */ enum { - DISP_COLOR = 0x08, // must be set to 1 - DISP_FOURBIT = 0x04, // must be set to 1 - DISP_FLIP = 0x02, // - DMA_ENABLE = 0x01 // must be set to 1 + DISP_COLOR = 0x08, /* must be set to 1 */ + DISP_FOURBIT = 0x04, /* must be set to 1 */ + DISP_FLIP = 0x02, + DMA_ENABLE = 0x01 /* must be set to 1 */ }; /* MTEST0 bit definitions */ @@ -262,4 +262,3 @@ enum { }; #endif - diff --git a/include/_suzy.h b/include/_suzy.h index 5de8ad678..50845c958 100644 --- a/include/_suzy.h +++ b/include/_suzy.h @@ -209,101 +209,101 @@ typedef struct PENPAL_1 { /* SPRGO bit definitions */ enum { - SPRITE_GO = 0x01, // sprite process start bit - EVER_ON = 0x04 // everon detector enable + SPRITE_GO = 0x01, /* sprite process start bit */ + EVER_ON = 0x04 /* everon detector enable */ }; /* SPRSYS bit definitions for write operations */ enum { - SIGNMATH = 0x80, // signed math - ACCUMULATE = 0x40, // accumulate multiplication results - NO_COLLIDE = 0x20, // do not collide with any sprites (also SPRCOLL bit definition) - VSTRETCH = 0x10, // stretch v + SIGNMATH = 0x80, /* signed math */ + ACCUMULATE = 0x40, /* accumulate multiplication results */ + NO_COLLIDE = 0x20, /* do not collide with any sprites (also SPRCOLL bit definition) */ + VSTRETCH = 0x10, /* stretch v */ LEFTHAND = 0x08, - CLR_UNSAFE = 0x04, // unsafe access reset - SPRITESTOP = 0x02 // request to stop sprite process + CLR_UNSAFE = 0x04, /* unsafe access reset */ + SPRITESTOP = 0x02 /* request to stop sprite process */ }; /* SPRSYS bit definitions for read operations */ enum { - MATHWORKING = 0x80, // math operation in progress - MATHWARNING = 0x40, // accumulator overflow on multiple or divide by zero - MATHCARRY = 0x20, // last carry bit + MATHWORKING = 0x80, /* math operation in progress */ + MATHWARNING = 0x40, /* accumulator overflow on multiple or divide by zero */ + MATHCARRY = 0x20, /* last carry bit */ VSTRETCHING = 0x10, LEFTHANDED = 0x08, - UNSAFE_ACCESS = 0x04, // unsafe access performed - SPRITETOSTOP = 0x02, // requested to stop - SPRITEWORKING = 0x01 // sprite process is active + UNSAFE_ACCESS = 0x04, /* unsafe access performed */ + SPRITETOSTOP = 0x02, /* requested to stop */ + SPRITEWORKING = 0x01 /* sprite process is active */ }; /* Suzy hardware registers */ struct __suzy { - unsigned char *tmpadr; // 0xFC00 Temporary address - unsigned int tiltacc; // 0xFC02 Tilt accumulator - unsigned int hoff; // 0xFC04 Offset to H edge of screen - unsigned int voff; // 0xFC06 Offset to V edge of screen - unsigned char *sprbase; // 0xFC08 Base address of sprite - unsigned char *colbase; // 0xFC0A Base address of collision buffer - unsigned char *vidadr; // 0xFC0C Current vid buffer address - unsigned char *coladr; // 0xFC0E Current col buffer address - unsigned char *scbnext; // 0xFC10 Address of next SCB - unsigned char *sprdline; // 0xFC12 start of sprite data line address - unsigned int hposstrt; // 0xFC14 start hpos - unsigned int vposstrt; // 0xFC16 start vpos - unsigned int sprhsize; // 0xFC18 sprite h size - unsigned int sprvsize; // 0xFC1A sprite v size - unsigned int stretchl; // 0xFC1C H size adder - unsigned int tilt; // 0xFC1E H pos adder - unsigned int sprdoff; // 0xFC20 offset to next sprite data line - unsigned int sprvpos; // 0xFC22 current vpos - unsigned int colloff; // 0xFC24 offset to collision depository - unsigned int vsizeacc; // 0xFC26 vertical size accumulator - unsigned int hsizeoff; // 0xFC28 horizontal size offset - unsigned int vsizeoff; // 0xFC2A vertical size offset - unsigned char *scbaddr; // 0xFC2C address of current SCB - unsigned char *procaddr; // 0xFC2E address of current spr data proc - unsigned char unused0[32]; // 0xFC30 - 0xFC4F reserved/unused - unsigned char unused1[2]; // 0xFC50 - 0xFC51 do not use - unsigned char mathd; // 0xFC52 - unsigned char mathc; // 0xFC53 - unsigned char mathb; // 0xFC54 - unsigned char matha; // 0xFC55 write starts a multiply operation - unsigned char mathp; // 0xFC56 - unsigned char mathn; // 0xFC57 - unsigned char unused2[8]; // 0xFC58 - 0xFC5F do not use - unsigned char mathh; // 0xFC60 - unsigned char mathg; // 0xFC61 - unsigned char mathf; // 0xFC62 - unsigned char mathe; // 0xFC63 write starts a divide operation - unsigned char unused3[8]; // 0xFC64 - 0xFC6B do not use - unsigned char mathm; // 0xFC6C - unsigned char mathl; // 0xFC6D - unsigned char mathk; // 0xFC6E - unsigned char mathj; // 0xFC6F - unsigned char unused4[16]; // 0xFC70 - 0xFC7F do not use - unsigned char sprctl0; // 0xFC80 sprite control bits 0 - unsigned char sprctl1; // 0xFC81 sprite control bits 1 - unsigned char sprcoll; // 0xFC82 sprite collision number - unsigned char sprinit; // 0xFC83 sprite initialization bits - unsigned char unused5[4]; // 0xFC84 - 0xFC87 unused - unsigned char suzyhrev; // 0xFC88 suzy hardware rev - unsigned char suzysrev; // 0xFC89 suzy software rev - unsigned char unused6[6]; // 0xFC8A - 0xFC8F unused - unsigned char suzybusen; // 0xFC90 suzy bus enable - unsigned char sprgo; // 0xFC91 sprite process start bit - unsigned char sprsys; // 0xFC92 sprite system control bits - unsigned char unused7[29]; // 0xFC93 - 0xFCAF unused - unsigned char joystick; // 0xFCB0 joystick and buttons - unsigned char switches; // 0xFCB1 other switches - unsigned char cart0; // 0xFCB2 cart0 r/w - unsigned char cart1; // 0xFCB3 cart1 r/w - unsigned char unused8[8]; // 0xFCB4 - 0xFCBF unused - unsigned char leds; // 0xFCC0 leds - unsigned char unused9; // 0xFCC1 unused - unsigned char parstat; // 0xFCC2 parallel port status - unsigned char pardata; // 0xFCC3 parallel port data - unsigned char howie; // 0xFCC4 howie (?) - // 0xFCC5 - 0xFCFF unused + unsigned char *tmpadr; /* 0xFC00 Temporary address */ + unsigned int tiltacc; /* 0xFC02 Tilt accumulator */ + unsigned int hoff; /* 0xFC04 Offset to H edge of screen */ + unsigned int voff; /* 0xFC06 Offset to V edge of screen */ + unsigned char *sprbase; /* 0xFC08 Base address of sprite */ + unsigned char *colbase; /* 0xFC0A Base address of collision buffer */ + unsigned char *vidadr; /* 0xFC0C Current vid buffer address */ + unsigned char *coladr; /* 0xFC0E Current col buffer address */ + unsigned char *scbnext; /* 0xFC10 Address of next SCB */ + unsigned char *sprdline; /* 0xFC12 start of sprite data line address */ + unsigned int hposstrt; /* 0xFC14 start hpos */ + unsigned int vposstrt; /* 0xFC16 start vpos */ + unsigned int sprhsize; /* 0xFC18 sprite h size */ + unsigned int sprvsize; /* 0xFC1A sprite v size */ + unsigned int stretchl; /* 0xFC1C H size adder */ + unsigned int tilt; /* 0xFC1E H pos adder */ + unsigned int sprdoff; /* 0xFC20 offset to next sprite data line */ + unsigned int sprvpos; /* 0xFC22 current vpos */ + unsigned int colloff; /* 0xFC24 offset to collision depository */ + unsigned int vsizeacc; /* 0xFC26 vertical size accumulator */ + unsigned int hsizeoff; /* 0xFC28 horizontal size offset */ + unsigned int vsizeoff; /* 0xFC2A vertical size offset */ + unsigned char *scbaddr; /* 0xFC2C address of current SCB */ + unsigned char *procaddr; /* 0xFC2E address of current spr data proc */ + unsigned char unused0[32]; /* 0xFC30 - 0xFC4F reserved/unused */ + unsigned char unused1[2]; /* 0xFC50 - 0xFC51 do not use */ + unsigned char mathd; /* 0xFC52 */ + unsigned char mathc; /* 0xFC53 */ + unsigned char mathb; /* 0xFC54 */ + unsigned char matha; /* 0xFC55 write starts a multiply operation */ + unsigned char mathp; /* 0xFC56 */ + unsigned char mathn; /* 0xFC57 */ + unsigned char unused2[8]; /* 0xFC58 - 0xFC5F do not use */ + unsigned char mathh; /* 0xFC60 */ + unsigned char mathg; /* 0xFC61 */ + unsigned char mathf; /* 0xFC62 */ + unsigned char mathe; /* 0xFC63 write starts a divide operation */ + unsigned char unused3[8]; /* 0xFC64 - 0xFC6B do not use */ + unsigned char mathm; /* 0xFC6C */ + unsigned char mathl; /* 0xFC6D */ + unsigned char mathk; /* 0xFC6E */ + unsigned char mathj; /* 0xFC6F */ + unsigned char unused4[16]; /* 0xFC70 - 0xFC7F do not use */ + unsigned char sprctl0; /* 0xFC80 sprite control bits 0 */ + unsigned char sprctl1; /* 0xFC81 sprite control bits 1 */ + unsigned char sprcoll; /* 0xFC82 sprite collision number */ + unsigned char sprinit; /* 0xFC83 sprite initialization bits */ + unsigned char unused5[4]; /* 0xFC84 - 0xFC87 unused */ + unsigned char suzyhrev; /* 0xFC88 suzy hardware rev */ + unsigned char suzysrev; /* 0xFC89 suzy software rev */ + unsigned char unused6[6]; /* 0xFC8A - 0xFC8F unused */ + unsigned char suzybusen; /* 0xFC90 suzy bus enable */ + unsigned char sprgo; /* 0xFC91 sprite process start bit */ + unsigned char sprsys; /* 0xFC92 sprite system control bits */ + unsigned char unused7[29]; /* 0xFC93 - 0xFCAF unused */ + unsigned char joystick; /* 0xFCB0 joystick and buttons */ + unsigned char switches; /* 0xFCB1 other switches */ + unsigned char cart0; /* 0xFCB2 cart0 r/w */ + unsigned char cart1; /* 0xFCB3 cart1 r/w */ + unsigned char unused8[8]; /* 0xFCB4 - 0xFCBF unused */ + unsigned char leds; /* 0xFCC0 leds */ + unsigned char unused9; /* 0xFCC1 unused */ + unsigned char parstat; /* 0xFCC2 parallel port status */ + unsigned char pardata; /* 0xFCC3 parallel port data */ + unsigned char howie; /* 0xFCC4 howie (?) */ + /* 0xFCC5 - 0xFCFF unused */ }; /* Hardware math registers */ diff --git a/include/lynx.h b/include/lynx.h index fe4006461..259b3da71 100644 --- a/include/lynx.h +++ b/include/lynx.h @@ -80,29 +80,29 @@ #define DYN_DRV 0 /* Addresses of static drivers */ -extern void lynx_stdjoy_joy[]; // Referred to by joy_static_stddrv[] -extern void lynx_comlynx_ser[]; // Referred to by ser_static_stddrv[] -extern void lynx_160_102_16_tgi[]; // Referred to by tgi_static_stddrv[] +extern void lynx_stdjoy_joy[]; /* Referred to by joy_static_stddrv[] */ +extern void lynx_comlynx_ser[]; /* Referred to by ser_static_stddrv[] */ +extern void lynx_160_102_16_tgi[]; /* Referred to by tgi_static_stddrv[] */ /* Sound support */ -void lynx_snd_init (void); // Initialize the sound driver -void lynx_snd_pause (void); // Pause sound -void lynx_snd_continue (void); // Continue sound after pause -void __fastcall__ lynx_snd_play (unsigned char channel, unsigned char *music); // Play tune on channel -void lynx_snd_stop (void); // Stop sound on all channels -void __fastcall__ lynx_snd_stop_channel (unsigned char channel); // Stop sound on all channels -unsigned char lynx_snd_active(void); // Show which channels are active +void lynx_snd_init (void); /* Initialize the sound driver */ +void lynx_snd_pause (void); /* Pause sound */ +void lynx_snd_continue (void); /* Continue sound after pause */ +void __fastcall__ lynx_snd_play (unsigned char channel, unsigned char *music); /* Play tune on channel */ +void lynx_snd_stop (void); /* Stop sound on all channels */ +void __fastcall__ lynx_snd_stop_channel (unsigned char channel); /* Stop sound on all channels */ +unsigned char lynx_snd_active(void); /* Show which channels are active */ /* Cartridge access */ -void __fastcall__ lynx_load (int file_number); // Load a file into RAM using a zero-based index -void __fastcall__ lynx_exec (int file_number); // Load a file into ram and execute it +void __fastcall__ lynx_load (int file_number); /* Load a file into RAM using a zero-based index */ +void __fastcall__ lynx_exec (int file_number); /* Load a file into ram and execute it */ /* EEPROM access */ -unsigned __fastcall__ lynx_eeprom_read (unsigned char cell); // Read a 16 bit word from the given address -unsigned __fastcall__ lynx_eeprom_write (unsigned char cell, unsigned val); // Write the word at the given address -void __fastcall__ lynx_eeprom_erase (unsigned char cell); // Clear the word at the given address -unsigned __fastcall__ lynx_eeread (unsigned cell); // Read a 16 bit word from the given address 93C46, 93C66 or 93C86 -unsigned __fastcall__ lynx_eewrite (unsigned cell, unsigned val); // Write the word at the given address 93C46, 93C66 or 93C86 +unsigned __fastcall__ lynx_eeprom_read (unsigned char cell); /* Read a 16 bit word from the given address */ +unsigned __fastcall__ lynx_eeprom_write (unsigned char cell, unsigned val); /* Write the word at the given address */ +void __fastcall__ lynx_eeprom_erase (unsigned char cell); /* Clear the word at the given address */ +unsigned __fastcall__ lynx_eeread (unsigned cell); /* Read a 16 bit word from the given address 93C46, 93C66 or 93C86 */ +unsigned __fastcall__ lynx_eewrite (unsigned cell, unsigned val); /* Write the word at the given address 93C46, 93C66 or 93C86 */ /* TGI extras */ #define tgi_sprite(spr) tgi_ioctl(0, spr) @@ -117,11 +117,11 @@ unsigned __fastcall__ lynx_eewrite (unsigned cell, unsigned val); // Write the w #include <_mikey.h> #define MIKEY (*(struct __mikey *)0xFD00) -#define _MIKEY_TIMERS (*(struct _mikey_all_timers *) 0xFD00) // mikey_timers[8] -#define _HBL_TIMER (*(struct _mikey_timer *) 0xFD00) // timer0 (HBL) -#define _VBL_TIMER (*(struct _mikey_timer *) 0xFD08) // timer2 (VBL) -#define _UART_TIMER (*(struct _mikey_timer *) 0xFD14) // timer4 (UART) -#define _VIDDMA (*(unsigned int *) 0xFD92) // dispctl/viddma +#define _MIKEY_TIMERS (*(struct _mikey_all_timers *) 0xFD00) /* mikey_timers[8] */ +#define _HBL_TIMER (*(struct _mikey_timer *) 0xFD00) /* timer0 (HBL) */ +#define _VBL_TIMER (*(struct _mikey_timer *) 0xFD08) /* timer2 (VBL) */ +#define _UART_TIMER (*(struct _mikey_timer *) 0xFD14) /* timer4 (UART) */ +#define _VIDDMA (*(unsigned int *) 0xFD92) /* DISPCTL/VIDDMA */ #include <_suzy.h> #define SUZY (*(volatile struct __suzy*)0xFC00) From fa80e171a21d796d7f9c58d2fabd010dc0cfada5 Mon Sep 17 00:00:00 2001 From: Clyde Shaffer <clydeshaffer@gmail.com> Date: Tue, 12 Nov 2024 01:57:27 -0500 Subject: [PATCH 285/707] [LD65] Add bank number to dbgfile --- src/ld65/segments.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ld65/segments.c b/src/ld65/segments.c index 255b8ccd1..35d178774 100644 --- a/src/ld65/segments.c +++ b/src/ld65/segments.c @@ -638,6 +638,13 @@ void PrintDbgSegments (FILE* F) fprintf (F, ",oname=\"%s\",ooffs=%lu", S->OutputName, S->OutputOffs); } + if (S->MemArea) { + if (S->MemArea->BankExpr) { + if (IsConstExpr (S->MemArea->BankExpr)) { + fprintf (F, ",bank=%lu", GetExprVal(S->MemArea->BankExpr)); + } + } + } fputc ('\n', F); } } From 40d9f3eed513f4263f93aa6400acae931083a183 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Sun, 10 Nov 2024 13:38:35 +0100 Subject: [PATCH 286/707] Apple2: Provide a way to get directory file count The information is available in the directory key block. Providing it to the user as soon as opendir() is done can save them costly code. --- doc/apple2.sgml | 1 + doc/apple2enh.sgml | 1 + doc/funcref.sgml | 21 +++++++++++++++++++++ include/apple2.h | 5 +++++ include/dirent.h | 2 -- libsrc/apple2/dir.h | 1 + libsrc/apple2/dir.inc | 2 +- libsrc/apple2/dir_file_count.s | 24 ++++++++++++++++++++++++ libsrc/apple2/opendir.s | 21 ++++++++++----------- 9 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 libsrc/apple2/dir_file_count.s diff --git a/doc/apple2.sgml b/doc/apple2.sgml index c0255c4f7..c6b2fe8eb 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -332,6 +332,7 @@ usage. <item>_datetime <item>allow_lowercase <item>beep +<item>dir_file_count <item>get_ostype <item>gmtime_dt <item>mktime_dt diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 9c46bd4fb..ea950fa26 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -332,6 +332,7 @@ usage. <item>_filetype <item>_datetime <item>beep +<item>dir_file_count <item>get_ostype <item>gmtime_dt <item>mktime_dt diff --git a/doc/funcref.sgml b/doc/funcref.sgml index ea2350aad..7664739fe 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -97,6 +97,7 @@ function. <item>_dos_type <item>allow_lowercase <item><ref id="beep" name="beep"> +<item><ref id="dir_file_count" name="dir_file_count"> <item><ref id="get_ostype" name="get_ostype"> <item><ref id="gmtime_dt" name="gmtime_dt"> <item><ref id="mktime_dt" name="mktime_dt"> @@ -109,6 +110,7 @@ function. <itemize> <item>_dos_type <item><ref id="beep" name="beep"> +<item><ref id="dir_file_count" name="dir_file_count"> <item><ref id="get_ostype" name="get_ostype"> <item><ref id="gmtime_dt" name="gmtime_dt"> <item><ref id="mktime_dt" name="mktime_dt"> @@ -3524,6 +3526,25 @@ used in presence of a prototype. </quote> +<sect1>dir_file_count<label id="dir_file_count"><p> + +<quote> +<descrip> +<tag/Function/Returns the number of files in the directory. +<tag/Header/<tt/<ref id="apple2.h" name="apple2.h">/ +<tag/Declaration/<tt/unsigned int __fastcall__ dir_file_count(DIR *dir);/ +<tag/Description/<tt/dir_file_count/ is machine dependent and does not exist for +all supported targets. If it exists, it returns the number of active +(non-deleted) files in the directory. +<tag/Notes/<itemize> +<item>The function does not exist on all platforms. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/Example/None. +</descrip> +</quote> + + <sect1>div<label id="div"><p> <quote> diff --git a/include/apple2.h b/include/apple2.h index 1a840be6e..358d44ac4 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -232,6 +232,11 @@ struct tm* __fastcall__ gmtime_dt (const struct datetime* dt); time_t __fastcall__ mktime_dt (const struct datetime* dt); /* Converts a ProDOS date/time structure to a time_t UNIX timestamp */ +typedef struct DIR DIR; + +unsigned int __fastcall__ dir_file_count(DIR *dir); +/* Returns the number of active files in a ProDOS directory */ + #if !defined(__APPLE2ENH__) unsigned char __fastcall__ allow_lowercase (unsigned char onoff); /* If onoff is 0, lowercase characters printed to the screen via STDIO and diff --git a/include/dirent.h b/include/dirent.h index b95646833..60982ba05 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -147,7 +147,5 @@ void __fastcall__ seekdir (DIR* dir, long offs); void __fastcall__ rewinddir (DIR* dir); - - /* End of dirent.h */ #endif diff --git a/libsrc/apple2/dir.h b/libsrc/apple2/dir.h index 369080c47..ed44f08c6 100644 --- a/libsrc/apple2/dir.h +++ b/libsrc/apple2/dir.h @@ -45,6 +45,7 @@ struct DIR { int fd; unsigned char entry_length; unsigned char entries_per_block; + unsigned int file_count; unsigned char current_entry; union { unsigned char bytes[512]; diff --git a/libsrc/apple2/dir.inc b/libsrc/apple2/dir.inc index afad44eb7..545ae003b 100644 --- a/libsrc/apple2/dir.inc +++ b/libsrc/apple2/dir.inc @@ -2,8 +2,8 @@ FD .word ENTRY_LENGTH .byte ENTRIES_PER_BLOCK .byte + FILE_COUNT .word CURRENT_ENTRY .byte - .union BYTES .byte 512 .struct CONTENT diff --git a/libsrc/apple2/dir_file_count.s b/libsrc/apple2/dir_file_count.s new file mode 100644 index 000000000..aa864e32a --- /dev/null +++ b/libsrc/apple2/dir_file_count.s @@ -0,0 +1,24 @@ +; +; Colin Leroy-Mira <colin@colino.net>, 2024 +; +; unsigned int __fastcall__ dir_file_count(DIR *dir); +; + + .export _dir_file_count + + .importzp ptr1 + + .include "apple2.inc" + .include "dir.inc" + +.proc _dir_file_count + sta ptr1 + stx ptr1+1 + + ldy #DIR::FILE_COUNT + 1 + lda (ptr1),y + tax + dey + lda (ptr1),y + rts +.endproc diff --git a/libsrc/apple2/opendir.s b/libsrc/apple2/opendir.s index b75b83636..38110b680 100644 --- a/libsrc/apple2/opendir.s +++ b/libsrc/apple2/opendir.s @@ -128,24 +128,23 @@ ; Read succeeded, populate dir struct jsr popptr1 ; Restore our dir pointer - ldy #$24 + DIR::BYTES - lda (ptr1),y ; ENTRIES_PER_BLOCK - pha ; Back it up - + ; Get file_count to entry_length from block + ldy #$26 + DIR::BYTES +: lda (ptr1),y + pha dey - lda (ptr1),y ; ENTRY_LENGTH + cpy #$23 + DIR::BYTES - 1 + bne :- + ; Set entry_length to file_count in struct ldy #DIR::ENTRY_LENGTH +: pla sta (ptr1),y - - pla - .assert DIR::ENTRIES_PER_BLOCK = DIR::ENTRY_LENGTH + 1, error iny - sta (ptr1),y + cpy #DIR::CURRENT_ENTRY + bne :- ; Skip directory header entry - .assert DIR::CURRENT_ENTRY = DIR::ENTRIES_PER_BLOCK + 1, error - iny lda #$01 sta (ptr1),y From 700c01fa8b8927e46ddfe92662adb5dc73999dd8 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Thu, 14 Nov 2024 21:57:43 +0100 Subject: [PATCH 287/707] Rename dir_file_count to dir_entry_count --- doc/apple2.sgml | 2 +- doc/apple2enh.sgml | 2 +- doc/funcref.sgml | 14 +++++++------- include/apple2.h | 2 +- .../apple2/{dir_file_count.s => dir_entry_count.s} | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) rename libsrc/apple2/{dir_file_count.s => dir_entry_count.s} (74%) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index c6b2fe8eb..ffe0e2397 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -332,7 +332,7 @@ usage. <item>_datetime <item>allow_lowercase <item>beep -<item>dir_file_count +<item>dir_entry_count <item>get_ostype <item>gmtime_dt <item>mktime_dt diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index ea950fa26..fce6127bd 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -332,7 +332,7 @@ usage. <item>_filetype <item>_datetime <item>beep -<item>dir_file_count +<item>dir_entry_count <item>get_ostype <item>gmtime_dt <item>mktime_dt diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 7664739fe..f2dd02efc 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -97,7 +97,7 @@ function. <item>_dos_type <item>allow_lowercase <item><ref id="beep" name="beep"> -<item><ref id="dir_file_count" name="dir_file_count"> +<item><ref id="dir_entry_count" name="dir_entry_count"> <item><ref id="get_ostype" name="get_ostype"> <item><ref id="gmtime_dt" name="gmtime_dt"> <item><ref id="mktime_dt" name="mktime_dt"> @@ -110,7 +110,7 @@ function. <itemize> <item>_dos_type <item><ref id="beep" name="beep"> -<item><ref id="dir_file_count" name="dir_file_count"> +<item><ref id="dir_entry_count" name="dir_entry_count"> <item><ref id="get_ostype" name="get_ostype"> <item><ref id="gmtime_dt" name="gmtime_dt"> <item><ref id="mktime_dt" name="mktime_dt"> @@ -3526,16 +3526,16 @@ used in presence of a prototype. </quote> -<sect1>dir_file_count<label id="dir_file_count"><p> +<sect1>dir_entry_count<label id="dir_entry_count"><p> <quote> <descrip> -<tag/Function/Returns the number of files in the directory. +<tag/Function/Returns the number of entries in the directory. <tag/Header/<tt/<ref id="apple2.h" name="apple2.h">/ -<tag/Declaration/<tt/unsigned int __fastcall__ dir_file_count(DIR *dir);/ -<tag/Description/<tt/dir_file_count/ is machine dependent and does not exist for +<tag/Declaration/<tt/unsigned int __fastcall__ dir_entry_count(DIR *dir);/ +<tag/Description/<tt/dir_entry_count/ is machine dependent and does not exist for all supported targets. If it exists, it returns the number of active -(non-deleted) files in the directory. +(non-deleted) files and directories in the directory. <tag/Notes/<itemize> <item>The function does not exist on all platforms. </itemize> diff --git a/include/apple2.h b/include/apple2.h index 358d44ac4..15055f412 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -234,7 +234,7 @@ time_t __fastcall__ mktime_dt (const struct datetime* dt); typedef struct DIR DIR; -unsigned int __fastcall__ dir_file_count(DIR *dir); +unsigned int __fastcall__ dir_entry_count(DIR *dir); /* Returns the number of active files in a ProDOS directory */ #if !defined(__APPLE2ENH__) diff --git a/libsrc/apple2/dir_file_count.s b/libsrc/apple2/dir_entry_count.s similarity index 74% rename from libsrc/apple2/dir_file_count.s rename to libsrc/apple2/dir_entry_count.s index aa864e32a..6a80bef28 100644 --- a/libsrc/apple2/dir_file_count.s +++ b/libsrc/apple2/dir_entry_count.s @@ -1,17 +1,17 @@ ; ; Colin Leroy-Mira <colin@colino.net>, 2024 ; -; unsigned int __fastcall__ dir_file_count(DIR *dir); +; unsigned int __fastcall__ dir_entry_count(DIR *dir); ; - .export _dir_file_count + .export _dir_entry_count .importzp ptr1 .include "apple2.inc" .include "dir.inc" -.proc _dir_file_count +.proc _dir_entry_count sta ptr1 stx ptr1+1 From 90e436095853cc890b8471277ab7fd623041a4cf Mon Sep 17 00:00:00 2001 From: Clyde Shaffer <clydeshaffer@gmail.com> Date: Sat, 16 Nov 2024 17:13:04 -0500 Subject: [PATCH 288/707] Parse and report segment bank number in dbginfo module and test shell --- src/dbginfo/dbginfo.c | 30 ++++++++++++++++++++++++------ src/dbginfo/dbginfo.h | 1 + src/dbginfo/dbgsh.c | 3 ++- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/dbginfo/dbginfo.c b/src/dbginfo/dbginfo.c index fee41012c..1f693e513 100644 --- a/src/dbginfo/dbginfo.c +++ b/src/dbginfo/dbginfo.c @@ -127,6 +127,7 @@ typedef enum { TOK_ABSOLUTE = TOK_FIRST_KEYWORD, /* ABSOLUTE keyword */ TOK_ADDRSIZE, /* ADDRSIZE keyword */ TOK_AUTO, /* AUTO keyword */ + TOK_BANK, /* BANK keyword */ TOK_COUNT, /* COUNT keyword */ TOK_CSYM, /* CSYM keyword */ TOK_DEF, /* DEF keyword */ @@ -347,6 +348,7 @@ struct SegInfo { cc65_size Size; /* Size of segment */ char* OutputName; /* Name of output file */ unsigned long OutputOffs; /* Offset in output file */ + unsigned Bank; /* Bank number of memory area */ char Name[1]; /* Name of segment */ }; @@ -1618,7 +1620,8 @@ static int CompareScopeInfoByName (const void* L, const void* R) static SegInfo* NewSegInfo (const StrBuf* Name, unsigned Id, cc65_addr Start, cc65_addr Size, - const StrBuf* OutputName, unsigned long OutputOffs) + const StrBuf* OutputName, unsigned long OutputOffs, + unsigned Bank) /* Create a new SegInfo struct and return it */ { /* Allocate memory */ @@ -1628,6 +1631,7 @@ static SegInfo* NewSegInfo (const StrBuf* Name, unsigned Id, S->Id = Id; S->Start = Start; S->Size = Size; + S->Bank = Bank; if (SB_GetLen (OutputName) > 0) { /* Output file given */ S->OutputName = SB_StrDup (OutputName); @@ -1676,6 +1680,7 @@ static void CopySegInfo (cc65_segmentdata* D, const SegInfo* S) D->segment_size = S->Size; D->output_name = S->OutputName; D->output_offs = S->OutputOffs; + D->segment_bank = S->Bank; } @@ -2528,6 +2533,7 @@ static void NextToken (InputData* D) { "abs", TOK_ABSOLUTE }, { "addrsize", TOK_ADDRSIZE }, { "auto", TOK_AUTO }, + { "bank", TOK_BANK }, { "count", TOK_COUNT }, { "csym", TOK_CSYM }, { "def", TOK_DEF }, @@ -3838,6 +3844,7 @@ static void ParseSegment (InputData* D) StrBuf Name = STRBUF_INITIALIZER; StrBuf OutputName = STRBUF_INITIALIZER; unsigned long OutputOffs = 0; + unsigned Bank = 0; SegInfo* S; enum { ibNone = 0x000, @@ -3850,6 +3857,7 @@ static void ParseSegment (InputData* D) ibSize = 0x020, ibStart = 0x040, ibType = 0x080, + ibBank = 0x100, ibRequired = ibId | ibName | ibStart | ibSize | ibAddrSize | ibType, } InfoBits = ibNone; @@ -3863,10 +3871,11 @@ static void ParseSegment (InputData* D) Token Tok; /* Something we know? */ - if (D->Tok != TOK_ADDRSIZE && D->Tok != TOK_ID && - D->Tok != TOK_NAME && D->Tok != TOK_OUTPUTNAME && - D->Tok != TOK_OUTPUTOFFS && D->Tok != TOK_SIZE && - D->Tok != TOK_START && D->Tok != TOK_TYPE) { + if (D->Tok != TOK_ADDRSIZE && D->Tok != TOK_BANK && + D->Tok != TOK_ID && D->Tok != TOK_NAME && + D->Tok != TOK_OUTPUTNAME && D->Tok != TOK_OUTPUTOFFS && + D->Tok != TOK_SIZE && D->Tok != TOK_START && + D->Tok != TOK_TYPE) { /* Try smart error recovery */ if (D->Tok == TOK_IDENT || TokenIsKeyword (D->Tok)) { @@ -3892,6 +3901,15 @@ static void ParseSegment (InputData* D) InfoBits |= ibAddrSize; break; + case TOK_BANK: + if (!IntConstFollows (D)) { + goto ErrorExit; + } + Bank = D->IVal; + InfoBits |= ibBank; + NextToken (D); + break; + case TOK_ID: if (!IntConstFollows (D)) { goto ErrorExit; @@ -3992,7 +4010,7 @@ static void ParseSegment (InputData* D) } /* Create the segment info and remember it */ - S = NewSegInfo (&Name, Id, Start, Size, &OutputName, OutputOffs); + S = NewSegInfo (&Name, Id, Start, Size, &OutputName, OutputOffs, Bank); CollReplaceExpand (&D->Info->SegInfoById, S, Id); CollAppend (&D->Info->SegInfoByName, S); diff --git a/src/dbginfo/dbginfo.h b/src/dbginfo/dbginfo.h index 95aae837c..07914f238 100644 --- a/src/dbginfo/dbginfo.h +++ b/src/dbginfo/dbginfo.h @@ -521,6 +521,7 @@ struct cc65_segmentdata { cc65_size segment_size; /* Size of segment */ const char* output_name; /* Output file this seg was written to */ unsigned long output_offs; /* Offset of this seg in output file */ + unsigned segment_bank; }; typedef struct cc65_segmentinfo cc65_segmentinfo; diff --git a/src/dbginfo/dbgsh.c b/src/dbginfo/dbgsh.c index ba5d83849..6a95db2af 100644 --- a/src/dbginfo/dbgsh.c +++ b/src/dbginfo/dbgsh.c @@ -721,7 +721,7 @@ static void PrintSegmentHeader (void) /* Output a header for a list of segments */ { /* Header */ - PrintLine (" id name address size output file offs"); + PrintLine (" id name address size output file offs bank"); PrintSeparator (); } @@ -741,6 +741,7 @@ static void PrintSegments (const cc65_segmentinfo* S) PrintSize (D->segment_size, 7); Print ("%-16s", D->output_name? D->output_name : ""); PrintSize (D->output_offs, 6); + PrintId (D->segment_bank, 8); NewLine (); } } From f663ee428d9336b82823112b04cec3e3071e81e2 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Sat, 16 Nov 2024 21:59:00 +0100 Subject: [PATCH 289/707] Apple2: Rewrite readdir() and closedir() to assembly --- libsrc/apple2/closedir.c | 57 -------------------- libsrc/apple2/closedir.s | 35 ++++++++++++ libsrc/apple2/opendir.s | 104 ++++++++++++++++++----------------- libsrc/apple2/readdir.c | 90 ------------------------------- libsrc/apple2/readdir.s | 113 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 202 insertions(+), 197 deletions(-) delete mode 100644 libsrc/apple2/closedir.c create mode 100644 libsrc/apple2/closedir.s delete mode 100644 libsrc/apple2/readdir.c create mode 100644 libsrc/apple2/readdir.s diff --git a/libsrc/apple2/closedir.c b/libsrc/apple2/closedir.c deleted file mode 100644 index d37d15bba..000000000 --- a/libsrc/apple2/closedir.c +++ /dev/null @@ -1,57 +0,0 @@ -/*****************************************************************************/ -/* */ -/* closedir.c */ -/* */ -/* Close a directory */ -/* */ -/* */ -/* */ -/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include <stdlib.h> -#include <fcntl.h> -#include <dirent.h> -#include "dir.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -int __fastcall__ closedir (DIR* dir) -{ - int result; - - /* Cleanup directory file */ - result = close (dir->fd); - - /* Cleanup DIR */ - free (dir); - - return result; -} diff --git a/libsrc/apple2/closedir.s b/libsrc/apple2/closedir.s new file mode 100644 index 000000000..1f176092b --- /dev/null +++ b/libsrc/apple2/closedir.s @@ -0,0 +1,35 @@ +; +; Colin Leroy-Mira <colin@colino.net>, 2024 +; +; int __fastcall__ closedir (DIR *dir) +; + + .export _closedir, closedir_ptr1 + + .import _close + .import _free + .import pushax, popax, pushptr1, swapstk + + .importzp ptr1 + + .include "apple2.inc" + .include "dir.inc" + .include "errno.inc" + .include "fcntl.inc" + .include "zeropage.inc" + +_closedir: + sta ptr1 + stx ptr1+1 +closedir_ptr1: + ; Close fd + jsr pushptr1 ; Backup ptr1 + ldy #$00 + lda (ptr1),y ; Get fd + ldx #$00 + jsr _close + jsr swapstk ; Store result, pop ptr1 + + ; Free dir structure + jsr _free + jmp popax ; Return result diff --git a/libsrc/apple2/opendir.s b/libsrc/apple2/opendir.s index 38110b680..317be2755 100644 --- a/libsrc/apple2/opendir.s +++ b/libsrc/apple2/opendir.s @@ -4,16 +4,18 @@ ; DIR* __fastcall__ opendir (register const char* name) ; - .export _opendir + .export _opendir, read_dir_block_ptr1 + .import closedir_ptr1 .import _open, _read, _close - .import _malloc, _free + .import _malloc .import ___directerrno .import ___oserror, __cwd .import pushptr1, popptr1 .import pushax, pusha0 + .import return0, returnFFFF .importzp ptr1 @@ -37,7 +39,7 @@ sta ptr1 stx ptr1+1 -: ; open directory +: ; Open directory jsr pushptr1 lda #O_RDONLY jsr pusha0 @@ -58,23 +60,17 @@ ; We failed to allocate pla ; Get fd back ldx #$00 - jsr _close ; close it + jsr _close ; Close it lda #ENOMEM ; Set error jsr ___directerrno - @return_null: - lda #$00 - tax - rts + jmp return0 : ; Store dir struct to pointer sta ptr1 stx ptr1+1 - ; Push ptr1, read will destroy it - jsr pushptr1 - ; Save fd to dir struct lda #$00 ldy #DIR::FD + 1 @@ -84,49 +80,15 @@ pla ; Get fd back sta (ptr1),y - jsr pusha0 ; push fd for read - lda #<DIR::BYTES - clc - adc ptr1 - pha - lda #>DIR::BYTES - adc ptr1+1 - tax - pla - jsr pushax ; Push dir->block.bytes for read + jsr read_dir_block_ptr1 + bcc @read_ok - lda #<.sizeof(DIR::BYTES) - ldx #>.sizeof(DIR::BYTES) - - jsr _read ; Read directory block - cpx #>.sizeof(DIR::BYTES) - bne @err_read - cmp #<.sizeof(DIR::BYTES) - beq @read_ok - -@err_read: - ; Read failed, exit - lda ___oserror - bne :+ - lda #EINVAL - jsr ___directerrno - -: ; Close fd - jsr popptr1 ; Restore our dir pointer - ldy #$00 - lda (ptr1),y ; Get fd - ldx #$00 - jsr _close - - ; Free dir structure - lda ptr1 - ldx ptr1+1 - jsr _free - jmp @return_null + ; Close directory, free it + jsr closedir_ptr1 + jmp return0 ; Return NULL @read_ok: ; Read succeeded, populate dir struct - jsr popptr1 ; Restore our dir pointer ; Get file_count to entry_length from block ldy #$26 + DIR::BYTES @@ -153,3 +115,45 @@ ldx ptr1+1 rts .endproc + +; Read a directory for the DIR* pointer in ptr1 +; Return with carry clear on success +read_dir_block_ptr1: + ; Push ptr1, read will destroy it + jsr pushptr1 + + ldy #DIR::FD + lda (ptr1),y + + jsr pusha0 ; Push fd for read + lda #<DIR::BYTES + clc + adc ptr1 + pha + lda #>DIR::BYTES + adc ptr1+1 + tax + pla + jsr pushax ; Push dir->block.bytes for read + + lda #<.sizeof(DIR::BYTES) + ldx #>.sizeof(DIR::BYTES) + + jsr _read ; Read directory block + cpx #>.sizeof(DIR::BYTES) + bne @read_err + cmp #<.sizeof(DIR::BYTES) + beq @read_ok + +@read_err: + ; Read failed, exit + lda ___oserror + bne :+ + lda #EINVAL + jsr ___directerrno +: sec + bcs @out +@read_ok: + clc +@out: + jmp popptr1 diff --git a/libsrc/apple2/readdir.c b/libsrc/apple2/readdir.c deleted file mode 100644 index 8acfbbe8b..000000000 --- a/libsrc/apple2/readdir.c +++ /dev/null @@ -1,90 +0,0 @@ -/*****************************************************************************/ -/* */ -/* readdir.c */ -/* */ -/* Read directory entry */ -/* */ -/* */ -/* */ -/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include <stddef.h> -#include <unistd.h> -#include <dirent.h> -#include "dir.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -struct dirent* __fastcall__ readdir (register DIR* dir) -{ - register unsigned char* entry; - - /* Search for the next active directory entry */ - do { - - /* Read next directory block if necessary */ - if (dir->current_entry == dir->entries_per_block) { - if (read (dir->fd, - dir->block.bytes, - sizeof (dir->block)) != sizeof (dir->block)) { - - /* Just return failure as read() has */ - /* set errno if (and only if) no EOF */ - return NULL; - } - - /* Start with first entry in next block */ - dir->current_entry = 0; - } - - /* Compute pointer to current entry */ - entry = dir->block.content.entries + - dir->current_entry * dir->entry_length; - - /* Switch to next entry */ - ++dir->current_entry; - } while (entry[0x00] == 0); - - /* Move creation date/time to allow for next step below */ - *(unsigned long*)&entry[0x1A] = *(unsigned long*)&entry[0x18]; - - /* Feature unsigned long access to EOF by extension from 3 to 4 bytes */ - entry[0x18] = 0; - - /* Move file type to allow for next step below */ - entry[0x19] = entry[0x10]; - - /* Zero-terminate file name */ - entry[0x01 + (entry[0x00] & 0x0F)] = 0; - - /* Return success */ - return (struct dirent*)&entry[0x01]; -} diff --git a/libsrc/apple2/readdir.s b/libsrc/apple2/readdir.s new file mode 100644 index 000000000..e748055e1 --- /dev/null +++ b/libsrc/apple2/readdir.s @@ -0,0 +1,113 @@ +; +; Colin Leroy-Mira <colin@colino.net>, 2024 +; +; struct dirent * __fastcall__ readdir (DIR *dir) +; + .export _readdir + .import read_dir_block_ptr1 + + .import incax1, return0 + .import tosaddax, tosumula0, incaxy + .import pushax, pusha0, pushptr1, popptr1 + .importzp ptr1, ptr4 + + .include "dir.inc" + +.proc _readdir + sta ptr1 + stx ptr1+1 + +@next_entry: + ; Do we need to read the next directory block? + ldy #DIR::CURRENT_ENTRY + lda (ptr1),y + ldy #DIR::ENTRIES_PER_BLOCK + cmp (ptr1),y + bne @read_entry ; We don't + + jsr read_dir_block_ptr1 + bcc @read_ok + + ; We had a read error + jmp return0 + +@read_ok: + ldy #DIR::CURRENT_ENTRY + lda #$00 + sta (ptr1),y + +@read_entry: + ; Compute pointer to current entry: + ; entry = dir->block.content.entries + + ; dir->current_entry * dir->entry_length + + jsr pushptr1 ; Backup ptr1 + lda ptr1 + ldx ptr1+1 + ldy #DIR::BYTES + DIR::CONTENT::ENTRIES + jsr incaxy + jsr pushax + ldy #DIR::CURRENT_ENTRY + lda (ptr1),y + jsr pusha0 + ldy #DIR::ENTRY_LENGTH + lda (ptr1),y + jsr tosumula0 + jsr tosaddax + ; Store pointer to current entry + sta ptr4 + stx ptr4+1 + jsr popptr1 + + ; Switch to next entry + ldy #DIR::CURRENT_ENTRY + lda (ptr1),y + clc + adc #1 + sta (ptr1),y + + ; Check if entry[0] == 0 + ldy #$00 + lda (ptr4),y + beq @next_entry ; Yes, skip entry + + ; Move creation date/time to allow for next step below + ; 18-19-1A-1B => 1A-1B-1C-1D + ldy #$1B +: lda (ptr4),y + iny + iny + sta (ptr4),y + dey + dey + dey + cpy #$17 + bne :- + + ; Feature unsigned long access to EOF by extension from 3 to 4 bytes + ; entry[0x18] = 0 + iny + lda #$00 + sta (ptr4),y + + ; Move file type to allow for next step below + ; entry[0x19] = entry[0x10] + ldy #$10 + lda (ptr4),y + ldy #$19 + sta (ptr4),y + + ; Zero-terminate file name + ldy #$00 + lda (ptr4),y + and #$0F + tay + iny + lda #$00 + sta (ptr4),y + + ; Return pointer to entry+1 + lda ptr4 + ldx ptr4+1 + jmp incax1 +.endproc From 21030c22a06e57fe5346b490077057ed9273a67b Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Sat, 16 Nov 2024 22:01:11 +0100 Subject: [PATCH 290/707] Apple2: Rewrite rewinddir() in assembly --- libsrc/apple2/dir.h | 63 ----------------------------------- libsrc/apple2/rewinddir.c | 69 -------------------------------------- libsrc/apple2/rewinddir.s | 70 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 132 deletions(-) delete mode 100644 libsrc/apple2/dir.h delete mode 100644 libsrc/apple2/rewinddir.c create mode 100644 libsrc/apple2/rewinddir.s diff --git a/libsrc/apple2/dir.h b/libsrc/apple2/dir.h deleted file mode 100644 index ed44f08c6..000000000 --- a/libsrc/apple2/dir.h +++ /dev/null @@ -1,63 +0,0 @@ -/*****************************************************************************/ -/* */ -/* dir.h */ -/* */ -/* Apple ][ system specific DIR */ -/* */ -/* */ -/* */ -/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef _DIR_H -#define _DIR_H - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -struct DIR { - int fd; - unsigned char entry_length; - unsigned char entries_per_block; - unsigned int file_count; - unsigned char current_entry; - union { - unsigned char bytes[512]; - struct { - unsigned prev_block; - unsigned next_block; - unsigned char entries[1]; - } content; - } block; -}; - - - -/* End of dir.h */ -#endif diff --git a/libsrc/apple2/rewinddir.c b/libsrc/apple2/rewinddir.c deleted file mode 100644 index 3329852d8..000000000 --- a/libsrc/apple2/rewinddir.c +++ /dev/null @@ -1,69 +0,0 @@ -/*****************************************************************************/ -/* */ -/* rewinddir.c */ -/* */ -/* Reset directory stream */ -/* */ -/* */ -/* */ -/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <dirent.h> -#include "dir.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -void __fastcall__ rewinddir (register DIR* dir) -{ - /* Rewind directory file */ - if (lseek (dir->fd, 0, SEEK_SET)) { - - /* Read directory key block */ - if (read (dir->fd, - dir->block.bytes, - sizeof (dir->block)) == sizeof (dir->block)) { - - /* Skip directory header entry */ - dir->current_entry = 1; - - /* Return success */ - return; - } - } - - /* Assert that no subsequent readdir() finds an active entry */ - memset (dir->block.bytes, 0, sizeof (dir->block)); - - /* Return failure */ -} diff --git a/libsrc/apple2/rewinddir.s b/libsrc/apple2/rewinddir.s new file mode 100644 index 000000000..fd3e5738f --- /dev/null +++ b/libsrc/apple2/rewinddir.s @@ -0,0 +1,70 @@ +; +; Colin Leroy-Mira <colin@colino.net>, 2024 +; +; void __fastcall__ rewinddir (DIR* dir) +; + .export _rewinddir + .import read_dir_block_ptr1 + + .import pusha, pusha0, pushax + .import pushptr1, popptr1 + .import incaxy + .import _lseek, _memset + + .importzp ptr1, sreg + + .include "dir.inc" + .include "stdio.inc" + +.proc _rewinddir + sta ptr1 + stx ptr1+1 + jsr pushptr1 ; Backup ptr1, destroyed by _lseek + + ; Rewind directory file + ldy #DIR::FD + lda (ptr1),y + jsr pusha0 ; Push dir->fd + + tya ; Y = 0 here + jsr pusha0 + jsr pusha0 ; Push 0L + + lda #SEEK_SET ; X = 0 here + jsr _lseek + + ora sreg ; Check lseek returned 0L + ora sreg+1 + bne @rewind_err + txa + bne @rewind_err + + jsr popptr1 ; Restore ptr1 + + ; Read directory key block + jsr read_dir_block_ptr1 + bcs @rewind_err + + ; Skip directory header entry + lda #$01 + ldy #DIR::CURRENT_ENTRY + sta (ptr1),y + rts + +@rewind_err: + jsr popptr1 ; Restore ptr1 + + ; Assert that no subsequent readdir() finds an active entry + lda ptr1 + ldx ptr1+1 + ldy #DIR::BYTES + DIR::CONTENT::ENTRIES + jsr incaxy + jsr pushax + + lda #$00 + jsr pusha + + lda #<.sizeof(DIR::BYTES) + ldx #>.sizeof(DIR::BYTES) + jmp _memset +.endproc From 2abd66ea0ca1c89a9bd928196f74c435a11a123b Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Sat, 30 Nov 2024 12:36:35 +0100 Subject: [PATCH 291/707] Fixed the behavior of the JMP (ind) instruction in sim65 when it runs with the "6502X" CPU type. The JMP (ind) bug is present in the 6502 which is emulated by both the "6502" and "6502X" emulation targets of sim65; specifically, the OPC_6502_6C handler. In the old code, the bug-exhibiting code was not executed when the target was set to 6502X, which is incorrect. the patch removes the (CPU == CPU_6502) check, which made no sense. The JMP (ind) bug was actually fixed in the 65c02. Indeed, the OPC_65C02_6C opcode handler has code that implements the 'right' behavior. --- src/sim65/6502.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 448e81669..3f912b27e 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -1964,25 +1964,17 @@ static void OPC_6502_6C (void) PC = Regs.PC; Lo = MemReadWord (PC+1); - if (CPU == CPU_6502) - { - /* Emulate the 6502 bug */ - Cycles = 5; - Regs.PC = MemReadByte (Lo); - Hi = (Lo & 0xFF00) | ((Lo + 1) & 0xFF); - Regs.PC |= (MemReadByte (Hi) << 8); + /* Emulate the buggy 6502 behavior */ + Cycles = 5; + Regs.PC = MemReadByte (Lo); + Hi = (Lo & 0xFF00) | ((Lo + 1) & 0xFF); + Regs.PC |= (MemReadByte (Hi) << 8); - /* Output a warning if the bug is triggered */ - if (Hi != Lo + 1) - { - Warning ("6502 indirect jump bug triggered at $%04X, ind addr = $%04X", - PC, Lo); - } - } - else + /* Output a warning if the bug is triggered */ + if (Hi != Lo + 1) { - Cycles = 6; - Regs.PC = MemReadWord(Lo); + Warning ("6502 indirect jump bug triggered at $%04X, ind addr = $%04X", + PC, Lo); } ParaVirtHooks (&Regs); From 709d71ef704b51a5729318a9b839293a00b78590 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Sat, 30 Nov 2024 19:56:31 +0100 Subject: [PATCH 292/707] Fixed clock-cycle timing of branch (Bxx) instructions. Branch instructions, when taken, take three or four cycles, depending on whether a page is crossed by the branch. The proper check to determine whether the extra cycle must be added is the target address of the branch vs the address immediately following the branch. In the former version of the BRANCH instruction handler, the target address was incorrectly checked vs the address of the branch instruction itself. The corrected behavior was verified against a real 6502 (Atari) and the 65x02 testsuite. --- src/sim65/6502.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 448e81669..41ffc8329 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -707,8 +707,9 @@ static unsigned HaveIRQRequest; unsigned char OldPCH; \ ++Cycles; \ Offs = (signed char) MemReadByte (Regs.PC+1); \ + Regs.PC +=2; \ OldPCH = PCH; \ - Regs.PC = (Regs.PC + 2 + (int) Offs) & 0xFFFF; \ + Regs.PC = (Regs.PC + (int) Offs) & 0xFFFF; \ if (PCH != OldPCH) { \ ++Cycles; \ } \ From 12f63408789968acbc7ffe72a88227dce72b1f6e Mon Sep 17 00:00:00 2001 From: Clyde Shaffer <clydeshaffer@gmail.com> Date: Sat, 30 Nov 2024 16:09:50 -0500 Subject: [PATCH 293/707] Add section to ld65 doc about debug info --- doc/ld65.sgml | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 1ad04b395..66b8eedc7 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -1180,6 +1180,202 @@ The ZPSAVE segment contains the original values of the zeropage locations used by the ZEROPAGE segment. It is placed in its own segment because it must not be initialized. +<sect>Debug Info<p> + +The debug info and the API mirrors closely the items available in the sources +used to build an executable. To use the API efficiently, it is necessary to +understand from which blocks the information is built. + +<itemize> +<item> Libraries +<item> Lines +<item> Modules +<item> Scopes +<item> Segments +<item> Source files +<item> Spans +<item> Symbols +<item> Types +</itemize> + +Each item of each type has something like a primary index called an 'id'. +The ids can be thought of as array indices, so looking up something by its +id is fast. Invalid ids are marked with the special value CC65_INV_ID. +Data passed back for an item may contain ids of other objects. A scope for +example contains the id of the parent scope (or CC65_INV_ID if there is no +parent scope). Most API functions use ids to lookup related objects. + + +<sect1>Libraries<p> + +This information comes from the linker and is currently used in only one +place:To mark the origin of a module. The information available for a library +is its name including the path. + +<itemize> +<item> Library id +<item> Name and path of library +</itemize> + + +<sect1>Lines<p> + +A line is a location in a source file. It is module dependent, which means +that if two modules use the same source file, each one has its own line +information for this file. While the assembler has also column information, +it is dropped early because it would generate much more data. A line may have +one or more spans attached if code or data is generated. + +<itemize> +<item> Line id +<item> Id of the source file, the line is from +<item> The line number in the file (starting with 1) +<item> The type of the line: Assembler/C source or macro +<item> A count for recursive macros if the line comes from a macro +</itemize> + + +<sect1>Modules<p> + +A module is actually an object file. It is generated from one or more source +files and may come from a library. The assembler generates a main scope for +symbols declared outside user generated scopes. The main scope has an empty name. + +<itemize> +<item> Module id +<item> The name of the module including the path +<item> The id of the main source file (the one specified on the command line) +<item> The id of the library the module comes from, or CC65_INV_ID +<item> The id of the main scope for this module +</itemize> + + +<sect1>Scopes<p> + +Each module has a main scope where all symbols live, that are specified outside +other scopes. Additional nested scopes may be specified in the sources. So scopes +have a one to many relation: Each scope (with the exception of the main scope) has +exactly one parent and may have several child scopes. Scopes may not cross modules. + +<itemize> +<item> Scope id +<item> The name of the scope (may be empty) +<item> The type of the scope: Module, .SCOPE or .PROC, .STRUCT and .ENUM +<item> The size of the scope (the size of the span for the active segment) +<item> The id of the parent scope (CC65_INV_ID in case of the main scope) +<item> The id of the attached symbol for .PROC scopes +<item> The id of the module where the scope comes from +</itemize> + + +<sect1>Segments<p> + +<itemize> +<item> Segment id +<item> The name of the segment +<item> The start address of the segment +<item> The size of the segment +<item> The name of the output file, this segment was written to (may be empty) +<item> The offset of the segment in the output file (only if name not empty) +<item> The bank number of the segment's memory area +</itemize> + +It is also possible to retrieve the spans for sections (a section is the part of a +segment that comes from one module). Since the main scope covers a whole module, and +the main scope has spans assigned (if not empty), the spans for the main scope of a +module are also the spans for the sections in the segments. + + +<sect1>Source files<p> + +Modules are generated from source files. Since some source files are used several times +when generating a list of modules (header files for example), the linker will merge +duplicates to reduce redundant information. Source files are considered identical if the +full name including the path is identical, and the size and time of last modification +matches. Please note that there may be still duplicates if files are accessed using +different paths. + +<itemize> +<item> Source file id +<item> The name of the source file including the path +<item> The size of the file at the time when it was read +<item> The time of last modification at the time when the file was read +</itemize> + + +<sect1>Spans<p> + +A span is a small part of a segment. It has a start address and a size. Spans are used +to record sizes of other objects. Line infos and scopes may have spans attached, so it +is possible to lookup which data was generated for these items. + +<itemize> +<item> Span id +<item> The start address of the span. This is an absolute address +<item> The end address of the span. This is inclusive which means if start==end then => size==1 +<item> The id of the segment were the span is located +<item> The type of the data in the span (optional, maybe NULL) +<item> The number of line infos available for this span +<item> The number of scope infos available for this span +</itemize> + +The last two fields will save a call to cc65_line_byspan or cc65_scope_byspan by providing +information about the number of items that can be retrieved by these calls. + + +<sect1>Symbols<p> + +<itemize> +<item> Symbol id +<item> The name of the symbol +<item> The type of the symbol, which may be label, equate or import +<item> The size of the symbol (size of attached code or data). Only for labels. Zero if unknown +<item> The value of the symbol. For an import, this is taken from the corresponding export +<item> The id of the corresponding export. Only valid for imports, CC65_INV_ID for other symbols +<item> The segment id if the symbol is segment based. For an import, taken from the export +<item> The id of the scope this symbols was defined in +<item> The id of the parent symbol. This is only set for cheap locals and CC65_INV_ID otherwise +</itemize> + +Beware: Even for an import, the id of the corresponding export may be CC65_INV_ID. +This happens if the module with the export has no debug information. So make sure +that your application can handle it. + + +<sect1>Types<p> + +A type is somewhat special. You cannot retrieve data about it in a similar way as with the other +items. Instead you have to call a special routine that parses the type data and returns it +in a set of data structures that can be processed by a C or C++ program. + +The type information is language independent and doesn't encode things like 'const' or +'volatile'. Instead it defines a set of simple data types and a few ways to aggregate +them (arrays, structs and unions). + +Type information is currently generated by the assembler for storage allocating commands +like .BYTE or .WORD. For example, the assembler code + +<tscreen><verb> +foo: .byte $01, $02, $03 +</verb></tscreen> + +will assign the symbol foo a size of 3, but will also generate a span with a size of 3 +bytes and a type ARRAY[3] OF BYTE. +Evaluating the type of a span allows a debugger to display the data in the same way as it +was defined in the assembler source. + +<table> +<tabular ca="clc"> +<bf/Assembler Command/| <bf/Generated Type Information//@<hline> +.ADDR| ARRAY OF LITTLE ENDIAN POINTER WITH SIZE 2 TO VOID@ +.BYTE| ARRAY OF UNSIGNED WITH SIZE 1@ +.DBYT| ARRAY OF BIG ENDIAN UNSIGNED WITH SIZE 2@ +.DWORD| ARRAY OF LITTLE ENDIAN UNSIGNED WITH SIZE 4@ +.FARADDR| ARRAY OF LITTLE ENDIAN POINTER WITH SIZE 3 TO VOID@ +.WORD| ARRAY OF LITTLE ENDIAN UNSIGNED WITH SIZE 2@ +</tabular> +</table> + <sect>Copyright<p> From 3fdb1a516c57ee085aff9056d26e555f5ddf8c7a Mon Sep 17 00:00:00 2001 From: Clyde Shaffer <clydeshaffer@gmail.com> Date: Sat, 30 Nov 2024 16:56:25 -0500 Subject: [PATCH 294/707] small formatting fixes, and a section rename to get it to build --- doc/ld65.sgml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 66b8eedc7..b889645f5 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -1268,7 +1268,7 @@ exactly one parent and may have several child scopes. Scopes may not cross modul </itemize> -<sect1>Segments<p> +<sect1>Segment Info<p> <itemize> <item> Segment id @@ -1366,13 +1366,13 @@ was defined in the assembler source. <table> <tabular ca="clc"> -<bf/Assembler Command/| <bf/Generated Type Information//@<hline> +<bf/Assembler Command/| <bf/Generated Type Information/@<hline> .ADDR| ARRAY OF LITTLE ENDIAN POINTER WITH SIZE 2 TO VOID@ .BYTE| ARRAY OF UNSIGNED WITH SIZE 1@ .DBYT| ARRAY OF BIG ENDIAN UNSIGNED WITH SIZE 2@ .DWORD| ARRAY OF LITTLE ENDIAN UNSIGNED WITH SIZE 4@ .FARADDR| ARRAY OF LITTLE ENDIAN POINTER WITH SIZE 3 TO VOID@ -.WORD| ARRAY OF LITTLE ENDIAN UNSIGNED WITH SIZE 2@ +.WORD| ARRAY OF LITTLE ENDIAN UNSIGNED WITH SIZE 2 </tabular> </table> From 1d9d056da5f25c3cd684d7f570ee422bbd0d275d Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Sat, 30 Nov 2024 23:46:19 +0100 Subject: [PATCH 295/707] Fixed behavior of the 65C02 "BIT #imm" instruction. The BIT #imm instruction behaves differently from the BIT instruction with other addressing modes, in that it does /not/ set the N and V flags according to the value of its operand. It only sets the Z flag, in accordance to the value of (A & operand). This is corroborated in two ways: - The 65x02 test suite; - Documentation about BIT #imm such as http://www.6502.org/tutorials/65c02opcodes.html This patch implements the correct behavior for BIT with immediate addressing. The patched version passes the 65x02 test suite for 65C02 opcode 0x89. --- src/sim65/6502.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 448e81669..e15d53042 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -823,6 +823,12 @@ static unsigned HaveIRQRequest; SET_OF (Val & 0x40); \ SET_ZF ((Val & Regs.AC) == 0) +/* BITIMM */ +/* The BIT instruction with immediate mode addressing only sets + the zero flag; the sign and overflow flags are not changed. */ +#define BITIMM(Val) \ + SET_ZF ((Val & Regs.AC) == 0) + /* LDA */ #define LDA(Val) \ Regs.AC = Val; \ @@ -2257,7 +2263,9 @@ static void OPC_6502_88 (void) static void OPC_65SC02_89 (void) /* Opcode $89: BIT #imm */ { - ALU_OP_IMM (BIT); + /* Note: BIT #imm behaves differently from BIT with other addressing modes, + * hence the different 'op' argument to the macro. */ + ALU_OP_IMM (BITIMM); } From e26c17fd502068645c743abc5e6efdbcd5baad54 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Sun, 1 Dec 2024 09:59:10 +0100 Subject: [PATCH 296/707] Fixed wrong clearing of D-flag on interrupts for sim65 with 6502X CPU type. The 65C02 clears the D flag on interrupts while the 6502 does not. The old code cleared the D flag also for the 6502X CPU type, which was incorrect. --- src/sim65/6502.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 448e81669..09dc0ddea 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -4104,7 +4104,7 @@ unsigned ExecuteInsn (void) PUSH (PCL); PUSH (Regs.SR & ~BF); SET_IF (1); - if (CPU != CPU_6502) + if (CPU == CPU_65C02) { SET_DF (0); } @@ -4118,7 +4118,7 @@ unsigned ExecuteInsn (void) PUSH (PCL); PUSH (Regs.SR & ~BF); SET_IF (1); - if (CPU != CPU_6502) + if (CPU == CPU_65C02) { SET_DF (0); } From 3895caae90ffd8b4bdb51891cc01ecfb8a6b2e48 Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Mon, 2 Dec 2024 00:25:24 +0100 Subject: [PATCH 297/707] Style fix --- src/sim65/6502.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 41ffc8329..fec730b46 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -707,7 +707,7 @@ static unsigned HaveIRQRequest; unsigned char OldPCH; \ ++Cycles; \ Offs = (signed char) MemReadByte (Regs.PC+1); \ - Regs.PC +=2; \ + Regs.PC += 2; \ OldPCH = PCH; \ Regs.PC = (Regs.PC + (int) Offs) & 0xFFFF; \ if (PCH != OldPCH) { \ From 84c4ea062dd0e7fd28145e318ed452f8359d21f0 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Tue, 3 Dec 2024 01:17:44 +0100 Subject: [PATCH 298/707] Sim65: removed ZR register from CPURegs type. --- src/sim65/6502.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sim65/6502.h b/src/sim65/6502.h index a7a702521..cab734c6a 100644 --- a/src/sim65/6502.h +++ b/src/sim65/6502.h @@ -60,7 +60,6 @@ struct CPURegs { unsigned AC; /* Accumulator */ unsigned XR; /* X register */ unsigned YR; /* Y register */ - unsigned ZR; /* Z register */ unsigned SR; /* Status register */ unsigned SP; /* Stackpointer */ unsigned PC; /* Program counter */ From fbd8961be1df70303bcfb35e7ba7f93671f29c42 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Tue, 3 Dec 2024 21:21:49 +0100 Subject: [PATCH 299/707] sim65: changing memory access types to uint8_t and uint16_t. In sim65, simulator memory access to a 64 KB array is implemented via functions defined in src/sim65/memory.h and src/sim65/memory.c. In the old version, the types for both content bytes (8 bits), content words (16 bits), regular addresses (16 bits), and zero-page addresses (8 bits) were all given as bare 'unsigned'. This lead to several cases of address overrun (e.g., when an instruction wraps around from address 0xffff to 0x0000) when running the simulator against a stress test (specifically, the 65x02 test suite). To protect from this, and to more properly express the bit width of the types involved which is a good idea anyway, we start using the fixed-width types provided by 'stdint.h'. In the process, we also change the MemReadByte macro to a full function call. This may impact performance (by a small amount), but it improves memory safety, as cases where the address is accidentally expressed as a value exceeding 0xffff are handled by wrap-around (as it is in the actual hardware), rather than causing access outside of the Mem[] array where the 64 KB of simulated RAM resides. The reason for this patch is twofold. (1) It is a partial patch for issue #2539. Several issues brought to the surface by running the 65x02 testsuite are eliminated by these changes. In the discussion about this issue, it was concluded that it is a Good Idea to use the stdint-types, both for the simulated CPU registers and for the memory. This patch addresses the memory-part of that change. (2) It is a precursor patch for issue #2355. For that issue, we will implement a memory-mapped timer register. This will make handling of memory access in the simulator a bit more complex. Having proper functions with the proper types in place will help to make the timer register patch easier. --- src/sim65/memory.c | 24 ++++++++++++++++-------- src/sim65/memory.h | 21 +++++++-------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/sim65/memory.c b/src/sim65/memory.c index 68e7bb93b..b93693b91 100644 --- a/src/sim65/memory.c +++ b/src/sim65/memory.c @@ -45,8 +45,8 @@ -/* THE memory */ -unsigned char Mem[0x10000]; +/* The memory */ +uint8_t Mem[0x10000]; @@ -56,7 +56,7 @@ unsigned char Mem[0x10000]; -void MemWriteByte (unsigned Addr, unsigned char Val) +void MemWriteByte (uint16_t Addr, uint8_t Val) /* Write a byte to a memory location */ { Mem[Addr] = Val; @@ -64,7 +64,7 @@ void MemWriteByte (unsigned Addr, unsigned char Val) -void MemWriteWord (unsigned Addr, unsigned Val) +void MemWriteWord (uint16_t Addr, uint16_t Val) /* Write a word to a memory location */ { MemWriteByte (Addr, Val & 0xFF); @@ -73,22 +73,30 @@ void MemWriteWord (unsigned Addr, unsigned Val) -unsigned MemReadWord (unsigned Addr) +uint8_t MemReadByte (uint16_t Addr) +/* Read a byte from a memory location */ +{ + return Mem[Addr]; +} + + + +uint16_t MemReadWord (uint16_t Addr) /* Read a word from a memory location */ { - unsigned W = MemReadByte (Addr++); + uint8_t W = MemReadByte (Addr++); return (W | (MemReadByte (Addr) << 8)); } -unsigned MemReadZPWord (unsigned char Addr) +uint16_t MemReadZPWord (uint8_t Addr) /* Read a word from the zero page. This function differs from MemReadWord in that ** the read will always be in the zero page, even in case of an address ** overflow. */ { - unsigned W = MemReadByte (Addr++); + uint8_t W = MemReadByte (Addr++); return (W | (MemReadByte (Addr) << 8)); } diff --git a/src/sim65/memory.h b/src/sim65/memory.h index cef786aaa..b70c5bd05 100644 --- a/src/sim65/memory.h +++ b/src/sim65/memory.h @@ -36,9 +36,9 @@ #ifndef MEMORY_H #define MEMORY_H -#include "inline.h" +#include <stdint.h> -extern unsigned char Mem[0x10000]; +extern uint8_t Mem[0x10000]; /*****************************************************************************/ /* Code */ @@ -46,26 +46,19 @@ extern unsigned char Mem[0x10000]; -void MemWriteByte (unsigned Addr, unsigned char Val); +void MemWriteByte (uint16_t Addr, uint8_t Val); /* Write a byte to a memory location */ -void MemWriteWord (unsigned Addr, unsigned Val); +void MemWriteWord (uint16_t Addr, uint16_t Val); /* Write a word to a memory location */ -#if defined(HAVE_INLINE) -INLINE unsigned char MemReadByte (unsigned Addr) +uint8_t MemReadByte (uint16_t Addr); /* Read a byte from a memory location */ -{ - return Mem[Addr]; -} -#else -#define MemReadByte(Addr) Mem[Addr] -#endif -unsigned MemReadWord (unsigned Addr); +uint16_t MemReadWord (uint16_t Addr); /* Read a word from a memory location */ -unsigned MemReadZPWord (unsigned char Addr); +uint16_t MemReadZPWord (uint8_t Addr); /* Read a word from the zero page. This function differs from MemReadWord in that ** the read will always be in the zero page, even in case of an address ** overflow. From 05b3825683e065a40710bdad068a9ba62c33d70d Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Tue, 3 Dec 2024 23:33:57 +0100 Subject: [PATCH 300/707] sim65 : improve implementation of ROL and ROR operations Issue #2539 brings to light a number of issues in the sim65 simulator. Several issues can be traced back to undesirable side effects of the use of bare 'unsigned' types for the CPU registers in the 'CPURegs' type defined in src/sim65/6502.h. The intention is to tighten the types of the registers defined there to uint8_t and uint16_t, in accordance with the actual number of bits that those registers have in the 6502. However, it turns out that a handful of opcode implementations depend on the fact that the register types currently have more bits than the actual 6502 registers themselves for correct operation. This mostly involves operations that involve the carry bit (ROL, ROR, ADC, SBC). In preparation of fixing the CPURegs field types, we will first make sure that those opcode implementations are changed in such a way that they still work if the underlying register types are tightened to their actual bit width. This PR concerns this specific change for the ROL and ROR operations. The correct functioning of ROL and ROR after this patch has been verified by testing against the 65x02 test suite. --- src/sim65/6502.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index cb4e579eb..48a1d560d 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -737,23 +737,29 @@ static unsigned HaveIRQRequest; /* ROL */ #define ROL(Val) \ - Val <<= 1; \ - if (GET_CF ()) { \ - Val |= 0x01; \ - } \ - TEST_ZF (Val); \ - TEST_SF (Val); \ - TEST_CF (Val) + do { \ + unsigned ShiftOut = (Val & 0x80); \ + Val <<= 1; \ + if (GET_CF ()) { \ + Val |= 0x01; \ + } \ + TEST_ZF (Val); \ + TEST_SF (Val); \ + SET_CF (ShiftOut); \ + } while (0) /* ROR */ #define ROR(Val) \ - if (GET_CF ()) { \ - Val |= 0x100; \ - } \ - SET_CF (Val & 0x01); \ - Val >>= 1; \ - TEST_ZF (Val); \ - TEST_SF (Val) + do { \ + unsigned ShiftOut = (Val & 0x01); \ + Val >>= 1; \ + if (GET_CF ()) { \ + Val |= 0x80; \ + } \ + TEST_ZF (Val); \ + TEST_SF (Val); \ + SET_CF (ShiftOut); \ + } while(0) /* ASL */ #define ASL(Val) \ From 3612d90c8e9faa66c09d77e6cb88e967efb54ad3 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 9 Dec 2024 00:40:41 +0100 Subject: [PATCH 301/707] Update fire.c --- samples/cbm/fire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/cbm/fire.c b/samples/cbm/fire.c index 40eff0707..1eae086da 100644 --- a/samples/cbm/fire.c +++ b/samples/cbm/fire.c @@ -56,7 +56,7 @@ /* Use static local variables for speed */ -#pragma static-locals (1); +#pragma static-locals (1) From be6819ca1fc1fcd93159026ef4097a3987182122 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 9 Dec 2024 00:41:03 +0100 Subject: [PATCH 302/707] Update plasma.c --- samples/cbm/plasma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/cbm/plasma.c b/samples/cbm/plasma.c index f48d6dc77..5c0b901f7 100644 --- a/samples/cbm/plasma.c +++ b/samples/cbm/plasma.c @@ -51,7 +51,7 @@ /* Use static local variables for speed */ -#pragma static-locals (1); +#pragma static-locals (1) static const unsigned char sinustable[0x100] = { From 316ee4ad5bd862b8596002e7865b17debbfba53a Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 9 Dec 2024 00:42:28 +0100 Subject: [PATCH 303/707] Update overlay-demo.c --- samples/geos/overlay-demo.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/geos/overlay-demo.c b/samples/geos/overlay-demo.c index 73ab0e3c0..e3e92e6c2 100644 --- a/samples/geos/overlay-demo.c +++ b/samples/geos/overlay-demo.c @@ -27,7 +27,7 @@ void show(char *name) ** rather place the all the code of certain source files into the overlay by ** compiling them with --code-name OVERLAY1. */ -#pragma code-name(push, "OVERLAY1"); +#pragma code-name(push, "OVERLAY1") void foo(void) { @@ -39,27 +39,27 @@ void foo(void) show("One"); } -#pragma code-name(pop); +#pragma code-name(pop) -#pragma code-name(push, "OVERLAY2"); +#pragma code-name(push, "OVERLAY2") void bar(void) { show("Two"); } -#pragma code-name(pop); +#pragma code-name(pop) -#pragma code-name(push, "OVERLAY3"); +#pragma code-name(push, "OVERLAY3") void foobar (void) { show("Three"); } -#pragma code-name(pop); +#pragma code-name(pop) void main(int /*argc*/, char *argv[]) From 26e671710278948d23569b2bb947b222b6a9c29e Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 9 Dec 2024 00:43:05 +0100 Subject: [PATCH 304/707] Update mandelbrot.c --- samples/lynx/mandelbrot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/lynx/mandelbrot.c b/samples/lynx/mandelbrot.c index ce49fbf7a..27ac7d340 100644 --- a/samples/lynx/mandelbrot.c +++ b/samples/lynx/mandelbrot.c @@ -26,7 +26,7 @@ #define divfp(_a,_b) ((((signed long)_a)<<fpshift)/(_b)) /* Use static local variables for speed */ -#pragma static-locals (1); +#pragma static-locals (1) From 8b008052cbd7f3805e7af05ae694a2c24424c39c Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 9 Dec 2024 00:43:35 +0100 Subject: [PATCH 305/707] Update mandelbrot.c --- samples/mandelbrot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/mandelbrot.c b/samples/mandelbrot.c index 519f3d823..f4e7b83a8 100644 --- a/samples/mandelbrot.c +++ b/samples/mandelbrot.c @@ -41,7 +41,7 @@ #endif /* Use static local variables for speed */ -#pragma static-locals (1); +#pragma static-locals (1) From 5d2730f4b4aad47f2ea5152f7c71b03ef5c22895 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 9 Dec 2024 00:44:44 +0100 Subject: [PATCH 306/707] Update multidemo.c --- samples/multidemo.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/multidemo.c b/samples/multidemo.c index 02bb6fcac..435c1b985 100644 --- a/samples/multidemo.c +++ b/samples/multidemo.c @@ -64,34 +64,34 @@ void log (char *msg) ** rather place all the code of certain source files into the overlay by ** compiling them with --code-name OVERLAY1. */ -#pragma code-name (push, "OVERLAY1"); +#pragma code-name (push, "OVERLAY1") void foo (void) { log ("Calling main from overlay 1"); } -#pragma code-name (pop); +#pragma code-name (pop) -#pragma code-name (push, "OVERLAY2"); +#pragma code-name (push, "OVERLAY2") void bar (void) { log ("Calling main from overlay 2"); } -#pragma code-name (pop); +#pragma code-name (pop) -#pragma code-name (push, "OVERLAY3"); +#pragma code-name (push, "OVERLAY3") void foobar (void) { log ("Calling main from overlay 3"); } -#pragma code-name(pop); +#pragma code-name(pop) unsigned char loademdriver (void) From 5f2c5b58ab4611f13187754ce022255722b1d6fb Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 9 Dec 2024 18:25:34 +0100 Subject: [PATCH 307/707] Update overlaydemo.c --- samples/overlaydemo.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/overlaydemo.c b/samples/overlaydemo.c index dde6b70ab..a37b06d4f 100644 --- a/samples/overlaydemo.c +++ b/samples/overlaydemo.c @@ -39,7 +39,7 @@ void log (char *msg) ** rather place all the code of certain source files into the overlay by ** compiling them with --code-name OVERLAY1. */ -#pragma code-name (push, "OVERLAY1"); +#pragma code-name (push, "OVERLAY1") void foo (void) { @@ -51,27 +51,27 @@ void foo (void) log ("Calling main from overlay 1"); } -#pragma code-name (pop); +#pragma code-name (pop) -#pragma code-name (push, "OVERLAY2"); +#pragma code-name (push, "OVERLAY2") void bar (void) { log ("Calling main from overlay 2"); } -#pragma code-name (pop); +#pragma code-name (pop) -#pragma code-name (push, "OVERLAY3"); +#pragma code-name (push, "OVERLAY3") void foobar (void) { log ("Calling main from overlay 3"); } -#pragma code-name(pop); +#pragma code-name(pop) unsigned char loadfile (char *name, void *addr, void *size) From cf470dd0dff4622f14756bac13b78bbfb2ef692f Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 9 Dec 2024 18:26:00 +0100 Subject: [PATCH 308/707] Update sieve.c --- samples/sieve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/sieve.c b/samples/sieve.c index 8d0619888..7c3b9cd75 100644 --- a/samples/sieve.c +++ b/samples/sieve.c @@ -38,7 +38,7 @@ static unsigned char Sieve[COUNT]; -#pragma static-locals(1); +#pragma static-locals(1) From d993f3a7663780d41ee4d41186dde56cee23a496 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 9 Dec 2024 18:36:05 +0100 Subject: [PATCH 309/707] Update cc65.sgml --- doc/cc65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index d08e8418d..781e460a8 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1370,7 +1370,7 @@ sequences of the input. Example: <tscreen><verb> /* Use a space wherever an 'a' occurs in ISO-8859-1 source */ - #pragma charmap (0x61, 0x20); + #pragma charmap (0x61, 0x20) </verb></tscreen> From 0f6b427170eb52cacec58ba11202b9fd009e432d Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 9 Dec 2024 18:37:02 +0100 Subject: [PATCH 310/707] Update strftime.c --- libsrc/common/strftime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/common/strftime.c b/libsrc/common/strftime.c index 38ea4850e..2f3cadc2e 100644 --- a/libsrc/common/strftime.c +++ b/libsrc/common/strftime.c @@ -40,7 +40,7 @@ /* Use static local variables for speed */ -#pragma static-locals (on); +#pragma static-locals (on) From 852b622c433f71f815f005e7e2d3e0409ca81e28 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Tue, 3 Dec 2024 09:01:04 +0100 Subject: [PATCH 311/707] Apple2: Don't forcefully re-enable IRQ Avoid enabling IRQ after disabling them in driver code, remember previous state instead (in case user had them disabled already). --- libsrc/apple2/mou/a2.stdmou.s | 19 +++++++++++++------ libsrc/apple2/ser/a2.gs.s | 12 +++++++----- libsrc/apple2/waitvsync.s | 5 +++-- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/libsrc/apple2/mou/a2.stdmou.s b/libsrc/apple2/mou/a2.stdmou.s index c54c09d34..9b84c2f53 100644 --- a/libsrc/apple2/mou/a2.stdmou.s +++ b/libsrc/apple2/mou/a2.stdmou.s @@ -155,6 +155,7 @@ next: inc ptr1+1 ; Disable interrupts now because setting the slot number makes ; the IRQ handler (maybe called due to some non-mouse IRQ) try ; calling the firmware which isn't correctly set up yet + php sei ; Convert to and save slot number @@ -211,7 +212,7 @@ next: inc ptr1+1 common: jsr firmware ; Enable interrupts and return success - cli + plp lda #<MOUSE_ERR_OK ldx #>MOUSE_ERR_OK rts @@ -220,6 +221,7 @@ common: jsr firmware ; No return code required (the driver is removed from memory on return). UNINSTALL: ; Hide cursor + php sei jsr CHIDE @@ -249,7 +251,8 @@ SETBOX: ; Apple II Mouse TechNote #1, Interrupt Environment with the Mouse: ; "Disable interrupts before placing position information in the ; screen holes." -: sei +: php + sei ; Set low clamp lda (ptr1),y @@ -298,6 +301,7 @@ GETBOX: ; the screen). No return code required. MOVE: ldy slot + php sei ; Set y @@ -328,9 +332,10 @@ MOVE: ; no special action is required besides hiding the mouse cursor. ; No return code required. HIDE: + php sei jsr CHIDE - cli + plp rts ; SHOW: Is called to show the mouse cursor. The mouse kernel manages a @@ -339,9 +344,10 @@ HIDE: ; no special action is required besides enabling the mouse cursor. ; No return code required. SHOW: + php sei jsr CSHOW - cli + plp rts ; BUTTONS: Return the button mask in A/X. @@ -360,12 +366,13 @@ POS: ; struct pointed to by ptr1. No return code required. INFO: ldy #.sizeof(MOUSE_INFO)-1 -copy: sei +copy: php + sei : lda info,y sta (ptr1),y dey bpl :- - cli + plp rts ; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl diff --git a/libsrc/apple2/ser/a2.gs.s b/libsrc/apple2/ser/a2.gs.s index e35c6156b..ea3e54cc1 100644 --- a/libsrc/apple2/ser/a2.gs.s +++ b/libsrc/apple2/ser/a2.gs.s @@ -304,8 +304,9 @@ IIgs: ldx Channel - ; Deactivate interrupts - sei + php ; Deactivate interrupts + sei ; if enabled + ldy #WR_MASTER_IRQ_RST lda #MASTER_IRQ_SHUTDOWN jsr writeSCCReg @@ -334,7 +335,7 @@ IIgs: ldx #$00 stx Opened ; Mark port as closed - cli + plp ; Reenable interrupts if needed : txa ; Promote char return value rts @@ -352,7 +353,8 @@ getClockSource: ; Must return an SER_ERR_xx code in a/x. SER_OPEN: - sei + php ; Deactivate interrupts + sei ; if enabled ; Check if the handshake setting is valid ldy #SER_PARAMS::HANDSHAKE ; Handshake @@ -497,9 +499,9 @@ BaudOK: lda #SER_ERR_OK SetupOut: + plp ; Reenable interrupts if needed ldx #$00 ; Promote char return value sty Opened - cli rts ;---------------------------------------------------------------------------- diff --git a/libsrc/apple2/waitvsync.s b/libsrc/apple2/waitvsync.s index 1697622de..486b93a53 100644 --- a/libsrc/apple2/waitvsync.s +++ b/libsrc/apple2/waitvsync.s @@ -29,7 +29,8 @@ iigs: bit RDVBLBAR rts ; Apple IIc TechNote #9, Detecting VBL -iic: sei +iic: php + sei sta IOUDISOFF lda RDVBLMSK bit ENVBL @@ -40,7 +41,7 @@ iic: sei bcs :+ ; VBL interrupts were already enabled bit DISVBL : sta IOUDISON ; IIc Tech Ref Man: The firmware normally leaves IOUDIS on. - cli + plp rts .endif ; __APPLE2ENH__ From 0e640877c2d1a6a5fdf9ce53e46e09d73c265c32 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 11 Dec 2024 14:30:56 +0100 Subject: [PATCH 312/707] Fixed colour #2540 --- include/cbm264.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cbm264.h b/include/cbm264.h index 4951df518..a6317f384 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -97,7 +97,7 @@ #define COLOR_WHITE (BCOLOR_WHITE | CATTR_LUMA7) #define COLOR_RED (BCOLOR_RED | CATTR_LUMA4) #define COLOR_CYAN (BCOLOR_CYAN | CATTR_LUMA7) -#define COLOR_PURPLE (BCOLOR_VIOLET | CATTR_LUMA7) +#define COLOR_PURPLE (BCOLOR_LIGHVIOLET | CATTR_LUMA7) #define COLOR_GREEN (BCOLOR_GREEN | CATTR_LUMA7) #define COLOR_BLUE (BCOLOR_BLUE | CATTR_LUMA7) #define COLOR_YELLOW (BCOLOR_YELLOW | CATTR_LUMA7) From 3933f329c23a479582808df9ff796d46914d16fa Mon Sep 17 00:00:00 2001 From: Sergio Lindo Mansilla <sergiolindo.empresa@gmail.com> Date: Sun, 15 Dec 2024 14:50:45 +0100 Subject: [PATCH 313/707] Improve description of namespace access in ca65 This avoid confusion with referencing global scope with the namespace token. --- doc/ca65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 2e63e0961..9c54dbb1a 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1059,7 +1059,7 @@ The namespace token (<tt/::/) is used to access other scopes: .endscope ... - lda foo::bar ; Access foo in scope bar + lda #foo::bar ; Access bar in scope foo </verb></tscreen> The only way to deny access to a scope from the outside is to declare a scope From 17e7e669c9cec299e71e0d5c408b6be4b1036f0b Mon Sep 17 00:00:00 2001 From: Sergio Lindo Mansilla <sergiolindo.empresa@gmail.com> Date: Sun, 15 Dec 2024 15:28:44 +0100 Subject: [PATCH 314/707] Fix typo in ca65 doc --- doc/ca65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 2e63e0961..d3905ab64 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3897,7 +3897,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" Reserve storage. The command is followed by one or two constant expressions. The first one is mandatory and defines, how many bytes of - storage should be defined. The second, optional expression must by a + storage should be defined. The second, optional expression must be a constant byte value that will be used as value of the data. If there is no fill value given, the linker will use the value defined in the linker configuration file (default: zero). From eda8774e08bc431d4683c97429b62b079223752f Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Mon, 16 Dec 2024 16:36:23 +0100 Subject: [PATCH 315/707] Fixed ADC/SBC for the 65C02. The current (before-this-patch) version of sim65.c does not correctly implement the ADC and SBC instructions in 65C02 mode. This PR fixes that. The 6502 and 65C02 behave identically in binary mode; in decimal behavior however they diverge, both in the handling of inputs that are not BCD values, and in the handling of processor flags. This fix restructures the original "ADC" and "SBC" macros in versions that are specific for the 6502 and the 65C02, and updates the opcode tables to ensure that they point to the correct implementations. Considering the ADC instruction for a moment, the original "ADC" macro was changed to two macros ADC_6502 and ADC_65C02. These check the D (decimal mode) bit, and defer their implementation to any of three macros ADC_BINARY_MODE, ADC_DECIMAL_MODE_6502, and ADC_DECIMAL_MODE_65C02. This is a bit verbose but it makes it very clear what's going on. (For the SBC changes, the analogous changes were made.) The correctness of the changes made is ensured as follows: First, an in-depth study was made how ADC and SBC work, both in the original 6502 and the later 65C02 processor. The actual behavior of both processors was captured on hardware (an Atari 800 XL with a 6502 and a Neo6502 equipped with a WDC 65C02 processor), and was analyzed. The results were cross-referenced with internet sources, leading to a C implementation that reproduces the exact result of the hardware processors. See: https://github.com/sidneycadot/6502-test/blob/main/functional_test/adc_sbc/c_and_python_implementations/6502_adc_sbc.c Next, these C implementations of ADC and SBC were fitted into sim65's macro- based implementation scheme, replacing the existing 6502-only implementation. Finally, the new sim65 implementation was tested against the 65x02 testsuite, showing that (1) the 6502 implementation was still correct; and (2) that the 65C02 implementation is now also correct. As an added bonus, this new implementation of ADC/SBC no longer relies on a dirty implementation detail in sim65: the previous implementation relied on the fact that currently, the A register in the simulator is implemented as an "unsigned", with more bits than the actual A register (8 bits). In the future we want to change the register width to 8 bits, and this updated ADC/SBC is a necessary precursor to that change. --- src/sim65/6502.c | 465 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 347 insertions(+), 118 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index cb4e579eb..a424736f3 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -37,10 +37,11 @@ /* Known bugs and limitations of the 65C02 simulation: * support currently only on the level of 65SC02: BBRx, BBSx, RMBx, SMBx, WAI, and STP are unsupported - * BCD flag handling equals 6502 (unchecked if bug is simulated or wrong for - 6502) */ +#include <stdbool.h> +#include <stdint.h> + #include "memory.h" #include "error.h" #include "6502.h" @@ -555,15 +556,15 @@ static unsigned HaveIRQRequest; /* #imm */ #define ALU_OP_IMM(op) \ unsigned char immediate; \ - MEM_AD_OP_IMM(immediate); \ - Cycles = 2; \ + MEM_AD_OP_IMM(immediate); \ + Cycles = 2; \ op (immediate) /* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y / (zp) */ #define ALU_OP(mode, op) \ unsigned address, operand; \ - Cycles = ALU_CY_##mode; \ - MEM_AD_OP (mode, address, operand); \ + Cycles = ALU_CY_##mode; \ + MEM_AD_OP (mode, address, operand); \ op (operand) /* Store opcode helpers */ @@ -662,40 +663,88 @@ static unsigned HaveIRQRequest; TEST_SF (Regs.AC) -/* ADC */ -#define ADC(v) \ +/* ADC, binary mode (6502 and 65C02) */ +/* TODO: once the Regs fields are properly sized, get rid of the + * "& 0xff" in the Regs.AC asignment. + */ +#define ADC_BINARY_MODE(v) \ do { \ - unsigned old = Regs.AC; \ - unsigned rhs = (v & 0xFF); \ - if (GET_DF ()) { \ - unsigned lo; \ - int res; \ - lo = (old & 0x0F) + (rhs & 0x0F) + GET_CF (); \ - if (lo >= 0x0A) { \ - lo = ((lo + 0x06) & 0x0F) + 0x10; \ - } \ - Regs.AC = (old & 0xF0) + (rhs & 0xF0) + lo; \ - res = (signed char)(old & 0xF0) + \ - (signed char)(rhs & 0xF0) + \ - (signed char)lo; \ - TEST_ZF (old + rhs + GET_CF ()); \ - TEST_SF (Regs.AC); \ - if (Regs.AC >= 0xA0) { \ - Regs.AC += 0x60; \ - } \ - TEST_CF (Regs.AC); \ - SET_OF ((res < -128) || (res > 127)); \ - if (CPU == CPU_65C02) { \ - ++Cycles; \ - } \ + const uint8_t op = v; \ + const uint8_t OldAC = Regs.AC; \ + bool carry = GET_CF(); \ + Regs.AC = (OldAC + op + carry) & 0xff; \ + const bool NV = Regs.AC >= 0x80; \ + carry = OldAC + op + carry >= 0x100; \ + SET_SF(NV); \ + SET_OF(((OldAC >= 0x80) ^ NV) & ((op >= 0x80) ^ NV)); \ + SET_ZF(Regs.AC == 0); \ + SET_CF(carry); \ + } while (0) + +/* ADC, decimal mode (6502 behavior) */ +#define ADC_DECIMAL_MODE_6502(v) \ + do { \ + const uint8_t op = v; \ + const uint8_t OldAC = Regs.AC; \ + bool carry = GET_CF(); \ + const uint8_t binary_result = OldAC + op + carry; \ + uint8_t low_nibble = (OldAC & 15) + (op & 15) + carry; \ + if ((carry = low_nibble > 9)) \ + low_nibble = (low_nibble - 10) & 15; \ + uint8_t high_nibble = (OldAC >> 4) + (op >> 4) + carry; \ + const bool NV = (high_nibble & 8) != 0; \ + if ((carry = high_nibble > 9)) \ + high_nibble = (high_nibble - 10) & 15; \ + Regs.AC = (high_nibble << 4) | low_nibble; \ + SET_SF(NV); \ + SET_OF(((OldAC >= 0x80) ^ NV) & ((op >= 0x80) ^ NV)); \ + SET_ZF(binary_result == 0); \ + SET_CF(carry); \ + } while (0) + +/* ADC, decimal mode (65C02 behavior) */ +#define ADC_DECIMAL_MODE_65C02(v) \ + do { \ + const uint8_t op = v; \ + const uint8_t OldAC = Regs.AC; \ + const bool OldCF = GET_CF(); \ + bool carry = OldCF; \ + uint8_t low_nibble = (OldAC & 15) + (op & 15) + carry; \ + if ((carry = low_nibble > 9)) \ + low_nibble = (low_nibble - 10) & 15; \ + uint8_t high_nibble = (OldAC >> 4) + (op >> 4) + carry; \ + const bool PrematureSF = (high_nibble & 8) != 0; \ + if ((carry = high_nibble > 9)) \ + high_nibble = (high_nibble - 10) & 15; \ + Regs.AC = (high_nibble << 4) | low_nibble; \ + const bool NewZF = Regs.AC == 0; \ + const bool NewSF = Regs.AC >= 0x80; \ + const bool NewOF = ((OldAC >= 0x80) ^ PrematureSF) & \ + ((op >= 0x80) ^ PrematureSF); \ + SET_SF(NewSF); \ + SET_OF(NewOF); \ + SET_ZF(NewZF); \ + SET_CF(carry); \ + ++Cycles; \ + } while (0) + +/* ADC, 6502 version */ +#define ADC_6502(v) \ + do { \ + if (GET_DF()) { \ + ADC_DECIMAL_MODE_6502(v); \ } else { \ - Regs.AC += rhs + GET_CF (); \ - TEST_ZF (Regs.AC); \ - TEST_SF (Regs.AC); \ - TEST_CF (Regs.AC); \ - SET_OF (!((old ^ rhs) & 0x80) && \ - ((old ^ Regs.AC) & 0x80)); \ - Regs.AC &= 0xFF; \ + ADC_BINARY_MODE(v); \ + } \ + } while (0) + +/* ADC, 65C02 version */ +#define ADC_65C02(v) \ + do { \ + if (GET_DF()) { \ + ADC_DECIMAL_MODE_65C02(v); \ + } else { \ + ADC_BINARY_MODE(v); \ } \ } while (0) @@ -737,23 +786,29 @@ static unsigned HaveIRQRequest; /* ROL */ #define ROL(Val) \ - Val <<= 1; \ - if (GET_CF ()) { \ - Val |= 0x01; \ - } \ - TEST_ZF (Val); \ - TEST_SF (Val); \ - TEST_CF (Val) + do { \ + unsigned ShiftOut = (Val & 0x80); \ + Val <<= 1; \ + if (GET_CF ()) { \ + Val |= 0x01; \ + } \ + TEST_ZF (Val); \ + TEST_SF (Val); \ + SET_CF (ShiftOut); \ + } while (0) /* ROR */ #define ROR(Val) \ - if (GET_CF ()) { \ - Val |= 0x100; \ - } \ - SET_CF (Val & 0x01); \ - Val >>= 1; \ - TEST_ZF (Val); \ - TEST_SF (Val) + do { \ + unsigned ShiftOut = (Val & 0x01); \ + Val >>= 1; \ + if (GET_CF ()) { \ + Val |= 0x80; \ + } \ + TEST_ZF (Val); \ + TEST_SF (Val); \ + SET_CF (ShiftOut); \ + } while(0) /* ASL */ #define ASL(Val) \ @@ -816,7 +871,7 @@ static unsigned HaveIRQRequest; } \ SET_CF (Val & 0x01); \ Val >>= 1; \ - ADC (Val) + ADC_6502 (Val) /* BIT */ #define BIT(Val) \ @@ -873,7 +928,7 @@ static unsigned HaveIRQRequest; /* ISC */ #define ISC(Val) \ Val = (Val + 1) & 0xFF; \ - SBC(Val) + SBC_6502(Val) /* ASR */ #define ASR(Val) \ @@ -971,33 +1026,88 @@ static unsigned HaveIRQRequest; TEST_SF (Val); \ TEST_ZF (Val) - -/* SBC */ -#define SBC(v) \ +/* SBC, binary mode (6502 and 65C02) */ +/* TODO: once the Regs fields are properly sized, get rid of the + * "& 0xff" in the Regs.AC asignment. + */ +#define SBC_BINARY_MODE(v) \ do { \ - unsigned r_a = Regs.AC; \ - unsigned src = (v) & 0xFF; \ - unsigned ccc = (Regs.SR & CF) ^ CF; \ - unsigned tmp = r_a - src - ccc; \ - \ - SET_CF(tmp < 0x100); \ - TEST_SF(tmp); \ - TEST_ZF(tmp); \ - SET_OF((r_a ^ tmp) & (r_a ^ src) & 0x80); \ - \ - if (GET_DF ()) { \ - unsigned low = (r_a & 0x0f) - (src & 0x0f) - ccc; \ - tmp = (r_a & 0xf0) - (src & 0xf0); \ - if (low & 0x10) { \ - low -= 6; \ - tmp -= 0x10; \ - } \ - tmp = (low & 0xf) | tmp; \ - if (tmp & 0x100) { \ - tmp -= 0x60; \ - } \ + const uint8_t op = v; \ + const uint8_t OldAC = Regs.AC; \ + const bool borrow = !GET_CF(); \ + Regs.AC = (OldAC - op - borrow) & 0xff; \ + const bool NV = Regs.AC >= 0x80; \ + SET_SF(NV); \ + SET_OF(((OldAC >= 0x80) ^ NV) & ((op < 0x80) ^ NV)); \ + SET_ZF(Regs.AC == 0); \ + SET_CF(OldAC >= op + borrow); \ + } while (0) + +/* SBC, decimal mode (6502 behavior) */ +#define SBC_DECIMAL_MODE_6502(v) \ + do { \ + const uint8_t op = v; \ + const uint8_t OldAC = Regs.AC; \ + bool borrow = !GET_CF(); \ + const uint8_t binary_result = OldAC - op - borrow; \ + const bool NV = binary_result >= 0x80; \ + uint8_t low_nibble = (OldAC & 15) - (op & 15) - borrow; \ + if ((borrow = low_nibble >= 0x80)) \ + low_nibble = (low_nibble + 10) & 15; \ + uint8_t high_nibble = (OldAC >> 4) - (op >> 4) - borrow;\ + if ((borrow = high_nibble >= 0x80)) \ + high_nibble = (high_nibble + 10) & 15; \ + Regs.AC = (high_nibble << 4) | low_nibble; \ + SET_SF(NV); \ + SET_OF(((OldAC >= 0x80) ^ NV) & ((op < 0x80) ^ NV)); \ + SET_ZF(binary_result == 0); \ + SET_CF(!borrow); \ + } while (0) + +/* SBC, decimal mode (65C02 behavior) */ +#define SBC_DECIMAL_MODE_65C02(v) \ + do { \ + const uint8_t op = v; \ + const uint8_t OldAC = Regs.AC; \ + bool borrow = !GET_CF(); \ + uint8_t low_nibble = (OldAC & 15) - (op & 15) - borrow; \ + if ((borrow = low_nibble >= 0x80)) \ + low_nibble += 10; \ + const bool low_nibble_still_negative = \ + (low_nibble >= 0x80); \ + low_nibble &= 15; \ + uint8_t high_nibble = (OldAC >> 4) - (op >> 4) - borrow;\ + const bool PN = (high_nibble & 8) != 0; \ + if ((borrow = high_nibble >= 0x80)) \ + high_nibble += 10; \ + high_nibble -= low_nibble_still_negative; \ + high_nibble &= 15; \ + Regs.AC = (high_nibble << 4) | low_nibble; \ + SET_SF(Regs.AC >= 0x80); \ + SET_OF(((OldAC >= 0x80) ^ PN) & ((op < 0x80) ^ PN)); \ + SET_ZF(Regs.AC == 0x00); \ + SET_CF(!borrow); \ + ++Cycles; \ + } while (0) + +/* SBC, 6502 version */ +#define SBC_6502(v) \ + do { \ + if (GET_DF()) { \ + SBC_DECIMAL_MODE_6502(v); \ + } else { \ + SBC_BINARY_MODE(v); \ + } \ + } while (0) + +/* SBC, 65C02 version */ +#define SBC_65C02(v) \ + do { \ + if (GET_DF()) { \ + SBC_DECIMAL_MODE_65C02(v); \ + } else { \ + SBC_BINARY_MODE(v); \ } \ - Regs.AC = tmp & 0xFF; \ } while (0) @@ -1881,11 +1991,17 @@ static void OPC_6502_60 (void) static void OPC_6502_61 (void) /* Opcode $61: ADC (zp,x) */ { - ALU_OP (ZPXIND, ADC); + ALU_OP (ZPXIND, ADC_6502); } +static void OPC_65C02_61 (void) +/* Opcode $61: ADC (zp,x) */ +{ + ALU_OP (ZPXIND, ADC_65C02); +} + static void OPC_6502_63 (void) /* Opcode $63: RRA (zp,x) */ { @@ -1905,7 +2021,15 @@ static void OPC_65SC02_64 (void) static void OPC_6502_65 (void) /* Opcode $65: ADC zp */ { - ALU_OP (ZP, ADC); + ALU_OP (ZP, ADC_6502); +} + + + +static void OPC_65C02_65 (void) +/* Opcode $65: ADC zp */ +{ + ALU_OP (ZP, ADC_65C02); } @@ -1941,11 +2065,17 @@ static void OPC_6502_68 (void) static void OPC_6502_69 (void) /* Opcode $69: ADC #imm */ { - ALU_OP_IMM (ADC); + ALU_OP_IMM (ADC_6502); } +static void OPC_65C02_69 (void) +/* Opcode $69: ADC #imm */ +{ + ALU_OP_IMM (ADC_65C02); +} + static void OPC_6502_6A (void) /* Opcode $6A: ROR a */ { @@ -2004,7 +2134,15 @@ static void OPC_65C02_6C (void) static void OPC_6502_6D (void) /* Opcode $6D: ADC abs */ { - ALU_OP (ABS, ADC); + ALU_OP (ABS, ADC_6502); +} + + + +static void OPC_65C02_6D (void) +/* Opcode $6D: ADC abs */ +{ + ALU_OP (ABS, ADC_65C02); } @@ -2036,15 +2174,23 @@ static void OPC_6502_70 (void) static void OPC_6502_71 (void) /* Opcode $71: ADC (zp),y */ { - ALU_OP (ZPINDY, ADC); + ALU_OP (ZPINDY, ADC_6502); } -static void OPC_65SC02_72 (void) +static void OPC_65C02_71 (void) +/* Opcode $71: ADC (zp),y */ +{ + ALU_OP (ZPINDY, ADC_65C02); +} + + + +static void OPC_65C02_72 (void) /* Opcode $72: ADC (zp) */ { - ALU_OP (ZPIND, ADC); + ALU_OP (ZPIND, ADC_65C02); } @@ -2068,11 +2214,17 @@ static void OPC_65SC02_74 (void) static void OPC_6502_75 (void) /* Opcode $75: ADC zp,x */ { - ALU_OP (ZPX, ADC); + ALU_OP (ZPX, ADC_6502); } +static void OPC_65C02_75 (void) +/* Opcode $75: ADC zp,x */ +{ + ALU_OP (ZPX, ADC_65C02); +} + static void OPC_6502_76 (void) /* Opcode $76: ROR zp,x */ { @@ -2102,7 +2254,15 @@ static void OPC_6502_78 (void) static void OPC_6502_79 (void) /* Opcode $79: ADC abs,y */ { - ALU_OP (ABSY, ADC); + ALU_OP (ABSY, ADC_6502); +} + + + +static void OPC_65C02_79 (void) +/* Opcode $79: ADC abs,y */ +{ + ALU_OP (ABSY, ADC_65C02); } @@ -2144,7 +2304,15 @@ static void OPC_65SC02_7C (void) static void OPC_6502_7D (void) /* Opcode $7D: ADC abs,x */ { - ALU_OP (ABSX, ADC); + ALU_OP (ABSX, ADC_6502); +} + + + +static void OPC_65C02_7D (void) +/* Opcode $7D: ADC abs,x */ +{ + ALU_OP (ABSX, ADC_65C02); } @@ -2986,11 +3154,17 @@ static void OPC_6502_E0 (void) static void OPC_6502_E1 (void) /* Opcode $E1: SBC (zp,x) */ { - ALU_OP (ZPXIND, SBC); + ALU_OP (ZPXIND, SBC_6502); } +static void OPC_65C02_E1 (void) +/* Opcode $E1: SBC (zp,x) */ +{ + ALU_OP (ZPXIND, SBC_65C02); +} + static void OPC_6502_E3 (void) /* Opcode $E3: ISC (zp,x) */ { @@ -3010,7 +3184,15 @@ static void OPC_6502_E4 (void) static void OPC_6502_E5 (void) /* Opcode $E5: SBC zp */ { - ALU_OP (ZP, SBC); + ALU_OP (ZP, SBC_6502); +} + + + +static void OPC_65C02_E5 (void) +/* Opcode $E5: SBC zp */ +{ + ALU_OP (ZP, SBC_65C02); } @@ -3041,17 +3223,23 @@ static void OPC_6502_E8 (void) -/* Aliases of opcode $EA */ +/* Aliases of opcode $E9 */ #define OPC_6502_EB OPC_6502_E9 static void OPC_6502_E9 (void) /* Opcode $E9: SBC #imm */ { - ALU_OP_IMM (SBC); + ALU_OP_IMM (SBC_6502); } +static void OPC_65C02_E9 (void) +/* Opcode $E9: SBC #imm */ +{ + ALU_OP_IMM (SBC_65C02); +} + /* Aliases of opcode $EA */ #define OPC_6502_1A OPC_6502_EA #define OPC_6502_3A OPC_6502_EA @@ -3117,7 +3305,15 @@ static void OPC_6502_EC (void) static void OPC_6502_ED (void) /* Opcode $ED: SBC abs */ { - ALU_OP (ABS, SBC); + ALU_OP (ABS, SBC_6502); +} + + + +static void OPC_65C02_ED (void) +/* Opcode $ED: SBC abs */ +{ + ALU_OP (ABS, SBC_65C02); } @@ -3148,15 +3344,24 @@ static void OPC_6502_F0 (void) static void OPC_6502_F1 (void) /* Opcode $F1: SBC (zp),y */ { - ALU_OP (ZPINDY, SBC); + ALU_OP (ZPINDY, SBC_6502); } -static void OPC_65SC02_F2 (void) + +static void OPC_65C02_F1 (void) +/* Opcode $F1: SBC (zp),y */ +{ + ALU_OP (ZPINDY, SBC_65C02); +} + + + +static void OPC_65C02_F2 (void) /* Opcode $F2: SBC (zp) */ { - ALU_OP (ZPIND, SBC); + ALU_OP (ZPIND, SBC_65C02); } @@ -3172,7 +3377,15 @@ static void OPC_6502_F3 (void) static void OPC_6502_F5 (void) /* Opcode $F5: SBC zp,x */ { - ALU_OP (ZPX, SBC); + ALU_OP (ZPX, SBC_6502); +} + + + +static void OPC_65C02_F5 (void) +/* Opcode $F5: SBC zp,x */ +{ + ALU_OP (ZPX, SBC_65C02); } @@ -3206,7 +3419,15 @@ static void OPC_6502_F8 (void) static void OPC_6502_F9 (void) /* Opcode $F9: SBC abs,y */ { - ALU_OP (ABSY, SBC); + ALU_OP (ABSY, SBC_6502); +} + + + +static void OPC_65C02_F9 (void) +/* Opcode $F9: SBC abs,y */ +{ + ALU_OP (ABSY, SBC_65C02); } @@ -3234,7 +3455,15 @@ static void OPC_6502_FB (void) static void OPC_6502_FD (void) /* Opcode $FD: SBC abs,x */ { - ALU_OP (ABSX, SBC); + ALU_OP (ABSX, SBC_6502); +} + + + +static void OPC_65C02_FD (void) +/* Opcode $FD: SBC abs,x */ +{ + ALU_OP (ABSX, SBC_65C02); } @@ -3884,35 +4113,35 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_5E, OPC_Illegal, // $5F: BBR5 currently unsupported OPC_6502_60, - OPC_6502_61, + OPC_65C02_61, OPC_65C02_NOP22, // $62 OPC_65C02_NOP11, // $63 OPC_65SC02_64, - OPC_6502_65, + OPC_65C02_65, OPC_6502_66, OPC_Illegal, // $67: RMB6 currently unsupported OPC_6502_68, - OPC_6502_69, + OPC_65C02_69, OPC_6502_6A, OPC_65C02_NOP11, // $6B OPC_65C02_6C, - OPC_6502_6D, + OPC_65C02_6D, OPC_6502_6E, OPC_Illegal, // $6F: BBR6 currently unsupported OPC_6502_70, - OPC_6502_71, - OPC_65SC02_72, + OPC_65C02_71, + OPC_65C02_72, OPC_65C02_NOP11, // $73 OPC_65SC02_74, - OPC_6502_75, + OPC_65C02_75, OPC_6502_76, OPC_Illegal, // $77: RMB7 currently unsupported OPC_6502_78, - OPC_6502_79, + OPC_65C02_79, OPC_65SC02_7A, OPC_65C02_NOP11, // $7B OPC_65SC02_7C, - OPC_6502_7D, + OPC_65C02_7D, OPC_65C02_7E, OPC_Illegal, // $7F: BBR7 currently unsupported OPC_65SC02_80, @@ -4012,35 +4241,35 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_DE, OPC_Illegal, // $DF: BBS5 currently unsupported OPC_6502_E0, - OPC_6502_E1, + OPC_65C02_E1, OPC_65C02_NOP22, // $E2 OPC_65C02_NOP11, // $E3 OPC_6502_E4, - OPC_6502_E5, + OPC_65C02_E5, OPC_6502_E6, OPC_Illegal, // $E7: SMB6 currently unsupported OPC_6502_E8, - OPC_6502_E9, + OPC_65C02_E9, OPC_6502_EA, OPC_65C02_NOP11, // $EB OPC_6502_EC, - OPC_6502_ED, + OPC_65C02_ED, OPC_6502_EE, OPC_Illegal, // $EF: BBS6 currently unsupported OPC_6502_F0, - OPC_6502_F1, - OPC_65SC02_F2, + OPC_65C02_F1, + OPC_65C02_F2, OPC_65C02_NOP11, // $F3 OPC_65C02_NOP24, // $F4 - OPC_6502_F5, + OPC_65C02_F5, OPC_6502_F6, OPC_Illegal, // $F7: SMB7 currently unsupported OPC_6502_F8, - OPC_6502_F9, + OPC_65C02_F9, OPC_65SC02_FA, OPC_65C02_NOP11, // $FB OPC_65C02_NOP34, // $FC - OPC_6502_FD, + OPC_65C02_FD, OPC_6502_FE, OPC_Illegal, // $FF: BBS7 currently unsupported }; From fb6745573eb0a063f61417e87807becee03348db Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Mon, 16 Dec 2024 16:55:26 +0100 Subject: [PATCH 316/707] Fixed whitespace. --- src/sim65/6502.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index a424736f3..c114c0c89 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -556,15 +556,15 @@ static unsigned HaveIRQRequest; /* #imm */ #define ALU_OP_IMM(op) \ unsigned char immediate; \ - MEM_AD_OP_IMM(immediate); \ - Cycles = 2; \ + MEM_AD_OP_IMM(immediate); \ + Cycles = 2; \ op (immediate) /* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y / (zp) */ #define ALU_OP(mode, op) \ unsigned address, operand; \ - Cycles = ALU_CY_##mode; \ - MEM_AD_OP (mode, address, operand); \ + Cycles = ALU_CY_##mode; \ + MEM_AD_OP (mode, address, operand); \ op (operand) /* Store opcode helpers */ From 86ccf25e81032bcc9a221c775a7dd26b29f132a6 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Mon, 16 Dec 2024 17:12:07 +0100 Subject: [PATCH 317/707] CPU registers can be accessed from outside 6502.c. The linkage of the 'Regs' variable in 6502.c was changed from static to extern. This makes the Regs type visible (and even alterable) from the outside. This change helps tools to inspect the CPU state. In particular, it was implemented to facilitate a tool that verifies opcode functionality using the '65x02' testsuite. But the change is also potentially useful for e.g. an online debugger that wants to inspect the CPU state while the 6502 is neing simulated. --- src/sim65/6502.c | 2 +- src/sim65/6502.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 48a1d560d..9d857a8ed 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -391,7 +391,7 @@ CPUType CPU; typedef void (*OPFunc) (void); /* The CPU registers */ -static CPURegs Regs; +CPURegs Regs; /* Cycles for the current insn */ static unsigned Cycles; diff --git a/src/sim65/6502.h b/src/sim65/6502.h index cab734c6a..b6b621823 100644 --- a/src/sim65/6502.h +++ b/src/sim65/6502.h @@ -65,6 +65,9 @@ struct CPURegs { unsigned PC; /* Program counter */ }; +/* Current CPU registers */ +extern CPURegs Regs; + /* Status register bits */ #define CF 0x01 /* Carry flag */ #define ZF 0x02 /* Zero flag */ From 6f9406bbe3a91ec2b291a4b087390b38807f2997 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Tue, 17 Dec 2024 23:24:35 +0100 Subject: [PATCH 318/707] This adds timer functionality to sim65. It provides access to a handful of 64-bit counters that count different things: - clock cycles - instructions - number of IRQ processed - number of NMIs processed - nanoseconds since 1-1-1970. This in not ready yet to be pushed as a merge request into the upstream CC65 repository. What's lacking: - documentation - tests And to be discussed: - do we agree on this implementation direction and interface in principe? - can I include inttypes.h for printing a 64-bit unsigned value? - will clock_gettime() work on a Windows build? --- cfg/sim6502.cfg | 2 +- cfg/sim65c02.cfg | 2 +- src/sim65/6502.c | 13 +++- src/sim65/error.c | 8 +- src/sim65/main.c | 6 +- src/sim65/memory.c | 20 ++++- src/sim65/peripherals.c | 159 ++++++++++++++++++++++++++++++++++++++++ src/sim65/peripherals.h | 98 +++++++++++++++++++++++++ 8 files changed, 293 insertions(+), 15 deletions(-) create mode 100644 src/sim65/peripherals.c create mode 100644 src/sim65/peripherals.h diff --git a/cfg/sim6502.cfg b/cfg/sim6502.cfg index 39c33581c..d393a4aee 100644 --- a/cfg/sim6502.cfg +++ b/cfg/sim6502.cfg @@ -5,7 +5,7 @@ SYMBOLS { MEMORY { ZP: file = "", start = $0000, size = $0100; HEADER: file = %O, start = $0000, size = $000C; - MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $0200, size = $FDC0 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; diff --git a/cfg/sim65c02.cfg b/cfg/sim65c02.cfg index 39c33581c..d393a4aee 100644 --- a/cfg/sim65c02.cfg +++ b/cfg/sim65c02.cfg @@ -5,7 +5,7 @@ SYMBOLS { MEMORY { ZP: file = "", start = $0000, size = $0100; HEADER: file = %O, start = $0000, size = $000C; - MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $0200, size = $FDC0 - __STACKSIZE__; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 48a1d560d..f48ba8fee 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -42,6 +42,7 @@ */ #include "memory.h" +#include "peripherals.h" #include "error.h" #include "6502.h" #include "paravirt.h" @@ -391,7 +392,7 @@ CPUType CPU; typedef void (*OPFunc) (void); /* The CPU registers */ -static CPURegs Regs; +CPURegs Regs; /* Cycles for the current insn */ static unsigned Cycles; @@ -4107,6 +4108,8 @@ unsigned ExecuteInsn (void) if (HaveNMIRequest) { HaveNMIRequest = 0; + PRegs.counter_nmi_events += 1; + PUSH (PCH); PUSH (PCL); PUSH (Regs.SR & ~BF); @@ -4121,6 +4124,8 @@ unsigned ExecuteInsn (void) } else if (HaveIRQRequest && GET_IF () == 0) { HaveIRQRequest = 0; + PRegs.counter_irq_events += 1; + PUSH (PCH); PUSH (PCL); PUSH (Regs.SR & ~BF); @@ -4139,8 +4144,14 @@ unsigned ExecuteInsn (void) /* Execute it */ Handlers[CPU][OPC] (); + + /* Increment the instruction counter by one.NMIs and IRQs are counted separately. */ + PRegs.counter_instructions += 1; } + /* Increment the 64-bit clock cycle counter with the cycle count for the instruction that we just executed */ + PRegs.counter_clock_cycles += Cycles; + /* Return the number of clock cycles needed by this insn */ return Cycles; } diff --git a/src/sim65/error.c b/src/sim65/error.c index fc24ca006..3618d660f 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -36,9 +36,10 @@ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> +#include <inttypes.h> #include "error.h" - +#include "peripherals.h" /*****************************************************************************/ @@ -50,9 +51,6 @@ /* flag to print cycles at program termination */ int PrintCycles = 0; -/* cycles are counted by main.c */ -extern unsigned long long TotalCycles; - /*****************************************************************************/ @@ -120,7 +118,7 @@ void SimExit (int Code) /* Exit the simulation with an exit code */ { if (PrintCycles) { - fprintf (stdout, "%llu cycles\n", TotalCycles); + fprintf (stdout, PRIu64 " cycles\n", PRegs.counter_clock_cycles); } exit (Code); } diff --git a/src/sim65/main.c b/src/sim65/main.c index 76c912c6b..8b41fcc0f 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -47,6 +47,7 @@ #include "6502.h" #include "error.h" #include "memory.h" +#include "peripherals.h" #include "paravirt.h" @@ -60,9 +61,6 @@ /* Name of program file */ const char* ProgramFile; -/* count of total cycles executed */ -unsigned long long TotalCycles = 0; - /* exit simulator after MaxCycles Cccles */ unsigned long long MaxCycles = 0; @@ -309,6 +307,7 @@ int main (int argc, char* argv[]) } MemInit (); + PeripheralsInit (); SPAddr = ReadProgramFile (); ParaVirtInit (I, SPAddr); @@ -318,7 +317,6 @@ int main (int argc, char* argv[]) RemainCycles = MaxCycles; while (1) { Cycles = ExecuteInsn (); - TotalCycles += Cycles; if (MaxCycles) { if (Cycles > RemainCycles) { ErrorCode (SIM65_ERROR_TIMEOUT, "Maximum number of cycles reached."); diff --git a/src/sim65/memory.c b/src/sim65/memory.c index b93693b91..c4b6bb220 100644 --- a/src/sim65/memory.c +++ b/src/sim65/memory.c @@ -36,7 +36,7 @@ #include <string.h> #include "memory.h" - +#include "peripherals.h" /*****************************************************************************/ @@ -59,7 +59,14 @@ uint8_t Mem[0x10000]; void MemWriteByte (uint16_t Addr, uint8_t Val) /* Write a byte to a memory location */ { - Mem[Addr] = Val; + if ((PERIPHERALS_APERTURE_BASE_ADDRESS <= Addr) && (Addr <= PERIPHERALS_APERTURE_LAST_ADDRESS)) + { + /* Defer the the memory-mapped peripherals handler for this write. */ + PeripheralWriteByte (Addr - PERIPHERALS_APERTURE_BASE_ADDRESS, Val); + } else { + /* Write to the Mem array. */ + Mem[Addr] = Val; + } } @@ -76,7 +83,14 @@ void MemWriteWord (uint16_t Addr, uint16_t Val) uint8_t MemReadByte (uint16_t Addr) /* Read a byte from a memory location */ { - return Mem[Addr]; + if ((PERIPHERALS_APERTURE_BASE_ADDRESS <= Addr) && (Addr <= PERIPHERALS_APERTURE_LAST_ADDRESS)) + { + /* Defer the the memory-mapped peripherals handler for this read. */ + return PeripheralReadByte (Addr - PERIPHERALS_APERTURE_BASE_ADDRESS); + } else { + /* Read from the Mem array. */ + return Mem[Addr]; + } } diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c new file mode 100644 index 000000000..edf401b02 --- /dev/null +++ b/src/sim65/peripherals.c @@ -0,0 +1,159 @@ +/*****************************************************************************/ +/* */ +/* peripherals.c */ +/* */ +/* Memory-mapped peripheral subsystem for the 6502 simulator */ +/* */ +/* */ +/* */ +/* (C) 2024-2025, Sidney Cadot */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include <time.h> +#include "peripherals.h" + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* The peripheral registers. */ +PeripheralRegs PRegs; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static uint64_t get_uint64_wallclock_time(void) +{ + struct timespec ts; + int result = clock_gettime(CLOCK_REALTIME, &ts); + if (result != 0) + { + // On failure, time will be set to the max value. + return 0xffffffffffffffff; + } + + /* Return time since the 1-1-1970 epoch, in nanoseconds. + * Note that this time may be off by an integer number of seconds, as POSIX + * maintaines that all days are 86,400 seconds long, which is not true due to + * leap seconds. + */ + return ts.tv_sec * 1000000000 + ts.tv_nsec; +} + + + +void PeripheralWriteByte (uint8_t Addr, uint8_t Val) +/* Write a byte to a memory location in the peripheral address aperture. */ +{ + switch (Addr) { + case PERIPHERALS_ADDRESS_OFFSET_LATCH: { + /* A write to the "latch" register performs a simultaneous latch of all registers */ + + /* Latch the current wallclock time first. */ + PRegs.latched_wallclock_time = get_uint64_wallclock_time(); + + /* Now latch all the cycles maintained by the processor. */ + PRegs.latched_counter_clock_cycles = PRegs.latched_counter_clock_cycles; + PRegs.latched_counter_instructions = PRegs.latched_counter_instructions; + PRegs.latched_counter_irq_events = PRegs.latched_counter_irq_events; + PRegs.latched_counter_nmi_events = PRegs.latched_counter_nmi_events; + break; + } + case PERIPHERALS_ADDRESS_OFFSET_SELECT: { + /* Set the value of the visibility-selection register. */ + PRegs.visible_latch_register = Val; + break; + } + default: { + /* Any other write is ignored */ + } + } +} + + + +uint8_t PeripheralReadByte (uint8_t Addr) +/* Read a byte from a memory location in the peripheral address aperture. */ +{ + switch (Addr) { + case PERIPHERALS_ADDRESS_OFFSET_SELECT: { + return PRegs.visible_latch_register; + } + case PERIPHERALS_ADDRESS_OFFSET_REG64 + 0: + case PERIPHERALS_ADDRESS_OFFSET_REG64 + 1: + case PERIPHERALS_ADDRESS_OFFSET_REG64 + 2: + case PERIPHERALS_ADDRESS_OFFSET_REG64 + 3: + case PERIPHERALS_ADDRESS_OFFSET_REG64 + 4: + case PERIPHERALS_ADDRESS_OFFSET_REG64 + 5: + case PERIPHERALS_ADDRESS_OFFSET_REG64 + 6: + case PERIPHERALS_ADDRESS_OFFSET_REG64 + 7: { + /* Read from any of the eight counter bytes. + * The first byte is the 64 bit value's LSB, the seventh byte is its MSB. + */ + unsigned byte_select = Addr - PERIPHERALS_ADDRESS_OFFSET_REG64; /* 0 .. 7 */ + uint64_t value; + switch (PRegs.visible_latch_register) { + case PERIPHERALS_REG64_SELECT_CLOCKCYCLE_COUNTER: value = PRegs.latched_counter_clock_cycles; break; + case PERIPHERALS_REG64_SELECT_INSTRUCTION_COUNTER: value = PRegs.latched_counter_instructions; break; + case PERIPHERALS_REG64_SELECT_IRQ_COUNTER: value = PRegs.latched_counter_irq_events; break; + case PERIPHERALS_REG64_SELECT_NMI_COUNTER: value = PRegs.latched_counter_nmi_events; break; + case PERIPHERALS_REG64_SELECT_WALLCLOCK_TIME: value = PRegs.latched_wallclock_time; break; + default: value = 0; /* Reading from a non-supported register will yield 0. */ + } + /* Return the desired byte of the latched counter. 0==LSB, 7==MSB. */ + return value >> (byte_select * 8); + } + default: { + /* Any other read yields a zero value. */ + return 0; + } + } +} + + + +void PeripheralsInit (void) +/* Initialize the peripheral registers */ +{ + PRegs.counter_clock_cycles = 0; + PRegs.counter_instructions = 0; + PRegs.counter_irq_events = 0; + PRegs.counter_nmi_events = 0; + + PRegs.latched_counter_clock_cycles = 0; + PRegs.latched_counter_instructions = 0; + PRegs.latched_counter_irq_events = 0; + PRegs.latched_counter_nmi_events = 0; + PRegs.latched_wallclock_time = 0; + + PRegs.visible_latch_register = 0; +} diff --git a/src/sim65/peripherals.h b/src/sim65/peripherals.h new file mode 100644 index 000000000..76da6e2f8 --- /dev/null +++ b/src/sim65/peripherals.h @@ -0,0 +1,98 @@ +/*****************************************************************************/ +/* */ +/* peripherals.h */ +/* */ +/* Memory-mapped peripheral subsystem for the 6502 simulator */ +/* */ +/* */ +/* */ +/* (C) 2024-2025, Sidney Cadot */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef PERIPHERALS_H +#define PERIPHERALS_H + +#include <stdint.h> + +#define PERIPHERALS_APERTURE_BASE_ADDRESS 0xffc0 +#define PERIPHERALS_APERTURE_LAST_ADDRESS 0xffc9 + +#define PERIPHERALS_ADDRESS_OFFSET_LATCH 0x00 +#define PERIPHERALS_ADDRESS_OFFSET_SELECT 0x01 +#define PERIPHERALS_ADDRESS_OFFSET_REG64 0x02 + +#define PERIPHERALS_LATCH (PERIPHERALS_APERTURE_BASE_ADDRESS + PERIPHERALS_ADDRESS_OFFSET_LATCH) +#define PERIPHERALS_SELECT (PERIPHERALS_APERTURE_BASE_ADDRESS + PERIPHERALS_ADDRESS_OFFSET_SELECT) +#define PERIPHERALS_REG64 (PERIPHERALS_APERTURE_BASE_ADDRESS + PERIPHERALS_ADDRESS_OFFSET_REG64) + +#define PERIPHERALS_REG64_SELECT_CLOCKCYCLE_COUNTER 0x00 +#define PERIPHERALS_REG64_SELECT_INSTRUCTION_COUNTER 0x01 +#define PERIPHERALS_REG64_SELECT_IRQ_COUNTER 0x02 +#define PERIPHERALS_REG64_SELECT_NMI_COUNTER 0x03 +#define PERIPHERALS_REG64_SELECT_WALLCLOCK_TIME 0x80 + +typedef struct { + /* the invisible counters that are continuously updated */ + uint64_t counter_clock_cycles; + uint64_t counter_instructions; + uint64_t counter_irq_events; + uint64_t counter_nmi_events; + /* latched counters upon a write to the 'latch' address. + * One of these will be visible (read only) through an each-byte aperture. */ + uint64_t latched_counter_clock_cycles; + uint64_t latched_counter_instructions; + uint64_t latched_counter_irq_events; + uint64_t latched_counter_nmi_events; + uint64_t latched_wallclock_time; + /* Select which of the five latched registers will be visible. + * This is a Read/Write byte-wide register. + * If a non-existent register is selected, the 8-byte aperture will read as zero. + */ + uint8_t visible_latch_register; +} PeripheralRegs; + +extern PeripheralRegs PRegs; + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void PeripheralWriteByte (uint8_t Addr, uint8_t Val); +/* Write a byte to a memory location in the peripheral address aperture. */ + + +uint8_t PeripheralReadByte (uint8_t Addr); +/* Read a byte from a memory location in the peripheral address aperture. */ + + +void PeripheralsInit (void); +/* Initialize the peripheral registers */ + + + +/* End of peripherals.h */ + +#endif From ceac9f87ba639c83139422d5cd93623f774826fb Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Tue, 17 Dec 2024 21:34:05 +0100 Subject: [PATCH 319/707] Temporary fix for fgets() not using target-specific newline. This patch provides a temporary fix for the issue where the fgets() function did not use the target-specific newline character to decide if it has reached the end of the line. It defaulted to the value $0a, which is the newline character on only some targets. The Atari, for example, has newline character $9b instead. This patch is ugly, because the ca65 assembler that is used for fgets doesn't currently accept C-type character escape sequences as values. Ideally we'd be able to write: cmp #'\n' And this would end up being translated to a compare-immediate to the target-specific newline character. Since that is impossible, this patch substitutes the equivalent, but ugly, code: .byte $c9, "\n" This works because $c9 is the opcode for cmp #imm, and the "\n" string /is/ translated to the platform-specific newline character, at least when the 'string_escapes' feature is enabled. --- libsrc/common/fgets.s | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libsrc/common/fgets.s b/libsrc/common/fgets.s index 172ca10dd..671136be2 100644 --- a/libsrc/common/fgets.s +++ b/libsrc/common/fgets.s @@ -8,6 +8,8 @@ .import _fgetc, popptr1, pushptr1, popax, pushax, return0, ___errno .importzp ptr1, ptr4 + .feature string_escapes + .include "errno.inc" .include "stdio.inc" .include "_file.inc" @@ -88,7 +90,22 @@ read_loop: bne :+ inc ptr4+1 -: cmp #$0A ; Stop at \n + ; The next code line: + ; + ; .byte $c9, "\n" + ; + ; corresponds to a CMP #imm with the target-specific newline value as its operand. + ; This works because (with the 'string_escapes' feature enabled), the "\n" string + ; assembles to the target-specific value for the newline character. + ; + ; It would be better if we could just write: + ; + ; cmp #'\n' + ; + ; Unfortunately, ca65 doesn't currently handle escape characters in character + ; constants. In the longer term, fixing that would be the preferred solution. + +: .byte $c9, "\n" ; cmp #'\n' beq done bne read_loop From a3cc9b47571c885f590ec73692f8027870a79222 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Wed, 18 Dec 2024 08:55:30 +0100 Subject: [PATCH 320/707] Fixed mistake in the latching code. --- src/sim65/peripherals.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index edf401b02..6ff420a24 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -82,10 +82,10 @@ void PeripheralWriteByte (uint8_t Addr, uint8_t Val) PRegs.latched_wallclock_time = get_uint64_wallclock_time(); /* Now latch all the cycles maintained by the processor. */ - PRegs.latched_counter_clock_cycles = PRegs.latched_counter_clock_cycles; - PRegs.latched_counter_instructions = PRegs.latched_counter_instructions; - PRegs.latched_counter_irq_events = PRegs.latched_counter_irq_events; - PRegs.latched_counter_nmi_events = PRegs.latched_counter_nmi_events; + PRegs.latched_counter_clock_cycles = PRegs.counter_clock_cycles; + PRegs.latched_counter_instructions = PRegs.counter_instructions; + PRegs.latched_counter_irq_events = PRegs.counter_irq_events; + PRegs.latched_counter_nmi_events = PRegs.counter_nmi_events; break; } case PERIPHERALS_ADDRESS_OFFSET_SELECT: { From 8ee93f7e5f726c0a39aa9a4ee396955718c0b6df Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Wed, 18 Dec 2024 09:04:20 +0100 Subject: [PATCH 321/707] Fixed indentation inside comment. --- libsrc/common/fgets.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/common/fgets.s b/libsrc/common/fgets.s index 671136be2..d5ea900d0 100644 --- a/libsrc/common/fgets.s +++ b/libsrc/common/fgets.s @@ -100,7 +100,7 @@ read_loop: ; ; It would be better if we could just write: ; - ; cmp #'\n' + ; cmp #'\n' ; ; Unfortunately, ca65 doesn't currently handle escape characters in character ; constants. In the longer term, fixing that would be the preferred solution. From 8a7cd9c632c6090f52aee7925b7611093a73aa73 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Thu, 19 Dec 2024 03:04:55 +0100 Subject: [PATCH 322/707] Fixed format string. --- src/sim65/error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim65/error.c b/src/sim65/error.c index 3618d660f..58c188676 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -118,7 +118,7 @@ void SimExit (int Code) /* Exit the simulation with an exit code */ { if (PrintCycles) { - fprintf (stdout, PRIu64 " cycles\n", PRegs.counter_clock_cycles); + fprintf (stdout, "%" PRIu64 " cycles\n", PRegs.counter_clock_cycles); } exit (Code); } From 5239d3a11b11619d6fb65f2691cea7ac92c136f7 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Thu, 19 Dec 2024 03:48:15 +0100 Subject: [PATCH 323/707] Polishing the peripherals (and counter) interface. --- src/sim65/6502.c | 8 +-- src/sim65/error.c | 2 +- src/sim65/memory.c | 4 +- src/sim65/peripherals.c | 123 +++++++++++++++++++--------------------- src/sim65/peripherals.h | 82 +++++++++++++++++---------- 5 files changed, 117 insertions(+), 102 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index f48ba8fee..7e993a59c 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -4108,7 +4108,7 @@ unsigned ExecuteInsn (void) if (HaveNMIRequest) { HaveNMIRequest = 0; - PRegs.counter_nmi_events += 1; + Peripherals.Counter.nmi_events += 1; PUSH (PCH); PUSH (PCL); @@ -4124,7 +4124,7 @@ unsigned ExecuteInsn (void) } else if (HaveIRQRequest && GET_IF () == 0) { HaveIRQRequest = 0; - PRegs.counter_irq_events += 1; + Peripherals.Counter.irq_events += 1; PUSH (PCH); PUSH (PCL); @@ -4146,11 +4146,11 @@ unsigned ExecuteInsn (void) Handlers[CPU][OPC] (); /* Increment the instruction counter by one.NMIs and IRQs are counted separately. */ - PRegs.counter_instructions += 1; + Peripherals.Counter.cpu_instructions += 1; } /* Increment the 64-bit clock cycle counter with the cycle count for the instruction that we just executed */ - PRegs.counter_clock_cycles += Cycles; + Peripherals.Counter.clock_cycles += Cycles; /* Return the number of clock cycles needed by this insn */ return Cycles; diff --git a/src/sim65/error.c b/src/sim65/error.c index 58c188676..45fb243d8 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -118,7 +118,7 @@ void SimExit (int Code) /* Exit the simulation with an exit code */ { if (PrintCycles) { - fprintf (stdout, "%" PRIu64 " cycles\n", PRegs.counter_clock_cycles); + fprintf (stdout, "%" PRIu64 " cycles\n", Peripherals.Counter.clock_cycles); } exit (Code); } diff --git a/src/sim65/memory.c b/src/sim65/memory.c index c4b6bb220..c80bf0f93 100644 --- a/src/sim65/memory.c +++ b/src/sim65/memory.c @@ -62,7 +62,7 @@ void MemWriteByte (uint16_t Addr, uint8_t Val) if ((PERIPHERALS_APERTURE_BASE_ADDRESS <= Addr) && (Addr <= PERIPHERALS_APERTURE_LAST_ADDRESS)) { /* Defer the the memory-mapped peripherals handler for this write. */ - PeripheralWriteByte (Addr - PERIPHERALS_APERTURE_BASE_ADDRESS, Val); + PeripheralsWriteByte (Addr - PERIPHERALS_APERTURE_BASE_ADDRESS, Val); } else { /* Write to the Mem array. */ Mem[Addr] = Val; @@ -86,7 +86,7 @@ uint8_t MemReadByte (uint16_t Addr) if ((PERIPHERALS_APERTURE_BASE_ADDRESS <= Addr) && (Addr <= PERIPHERALS_APERTURE_LAST_ADDRESS)) { /* Defer the the memory-mapped peripherals handler for this read. */ - return PeripheralReadByte (Addr - PERIPHERALS_APERTURE_BASE_ADDRESS); + return PeripheralsReadByte (Addr - PERIPHERALS_APERTURE_BASE_ADDRESS); } else { /* Read from the Mem array. */ return Mem[Addr]; diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 6ff420a24..cc2eb6528 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -40,8 +40,8 @@ -/* The peripheral registers. */ -PeripheralRegs PRegs; +/* The system-wide state of the peripherals */ +Sim65Peripherals Peripherals; @@ -51,46 +51,37 @@ PeripheralRegs PRegs; -static uint64_t get_uint64_wallclock_time(void) -{ - struct timespec ts; - int result = clock_gettime(CLOCK_REALTIME, &ts); - if (result != 0) - { - // On failure, time will be set to the max value. - return 0xffffffffffffffff; - } - - /* Return time since the 1-1-1970 epoch, in nanoseconds. - * Note that this time may be off by an integer number of seconds, as POSIX - * maintaines that all days are 86,400 seconds long, which is not true due to - * leap seconds. - */ - return ts.tv_sec * 1000000000 + ts.tv_nsec; -} - - - -void PeripheralWriteByte (uint8_t Addr, uint8_t Val) -/* Write a byte to a memory location in the peripheral address aperture. */ +void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) +/* Write a byte to a memory location in the peripherals address aperture. */ { switch (Addr) { - case PERIPHERALS_ADDRESS_OFFSET_LATCH: { - /* A write to the "latch" register performs a simultaneous latch of all registers */ + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_LATCH: { + /* A write to the "latch" register performs a simultaneous latch of all registers. */ /* Latch the current wallclock time first. */ - PRegs.latched_wallclock_time = get_uint64_wallclock_time(); + struct timespec ts; + int result = clock_gettime(CLOCK_REALTIME, &ts); + if (result != 0) { + /* Unable to read time. Report max uint64 value for both fields. */ + Peripherals.Counter.latched_wallclock_time = 0xffffffffffffffff; + Peripherals.Counter.latched_wallclock_time_split = 0xffffffffffffffff; + } else { + /* Number of nanoseconds since 1-1-1970. */ + Peripherals.Counter.latched_wallclock_time = 1000000000u * ts.tv_sec + ts.tv_nsec; + /* High word is number of seconds, low word is number of nanoseconds. */ + Peripherals.Counter.latched_wallclock_time_split = (ts.tv_sec << 32) | ts.tv_nsec; + } - /* Now latch all the cycles maintained by the processor. */ - PRegs.latched_counter_clock_cycles = PRegs.counter_clock_cycles; - PRegs.latched_counter_instructions = PRegs.counter_instructions; - PRegs.latched_counter_irq_events = PRegs.counter_irq_events; - PRegs.latched_counter_nmi_events = PRegs.counter_nmi_events; + /* Latch the counters that reflect the state of the processor. */ + Peripherals.Counter.latched_clock_cycles = Peripherals.Counter.clock_cycles; + Peripherals.Counter.latched_cpu_instructions = Peripherals.Counter.cpu_instructions; + Peripherals.Counter.latched_irq_events = Peripherals.Counter.irq_events; + Peripherals.Counter.latched_nmi_events = Peripherals.Counter.nmi_events; break; } - case PERIPHERALS_ADDRESS_OFFSET_SELECT: { + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_SELECT: { /* Set the value of the visibility-selection register. */ - PRegs.visible_latch_register = Val; + Peripherals.Counter.visible_latch_register = Val; break; } default: { @@ -101,33 +92,34 @@ void PeripheralWriteByte (uint8_t Addr, uint8_t Val) -uint8_t PeripheralReadByte (uint8_t Addr) -/* Read a byte from a memory location in the peripheral address aperture. */ +uint8_t PeripheralsReadByte (uint8_t Addr) +/* Read a byte from a memory location in the peripherals address aperture. */ { switch (Addr) { - case PERIPHERALS_ADDRESS_OFFSET_SELECT: { - return PRegs.visible_latch_register; + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_SELECT: { + return Peripherals.Counter.visible_latch_register; } - case PERIPHERALS_ADDRESS_OFFSET_REG64 + 0: - case PERIPHERALS_ADDRESS_OFFSET_REG64 + 1: - case PERIPHERALS_ADDRESS_OFFSET_REG64 + 2: - case PERIPHERALS_ADDRESS_OFFSET_REG64 + 3: - case PERIPHERALS_ADDRESS_OFFSET_REG64 + 4: - case PERIPHERALS_ADDRESS_OFFSET_REG64 + 5: - case PERIPHERALS_ADDRESS_OFFSET_REG64 + 6: - case PERIPHERALS_ADDRESS_OFFSET_REG64 + 7: { + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE + 0: + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE + 1: + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE + 2: + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE + 3: + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE + 4: + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE + 5: + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE + 6: + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE + 7: { /* Read from any of the eight counter bytes. * The first byte is the 64 bit value's LSB, the seventh byte is its MSB. */ - unsigned byte_select = Addr - PERIPHERALS_ADDRESS_OFFSET_REG64; /* 0 .. 7 */ + unsigned byte_select = Addr - PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE; /* 0 .. 7 */ uint64_t value; - switch (PRegs.visible_latch_register) { - case PERIPHERALS_REG64_SELECT_CLOCKCYCLE_COUNTER: value = PRegs.latched_counter_clock_cycles; break; - case PERIPHERALS_REG64_SELECT_INSTRUCTION_COUNTER: value = PRegs.latched_counter_instructions; break; - case PERIPHERALS_REG64_SELECT_IRQ_COUNTER: value = PRegs.latched_counter_irq_events; break; - case PERIPHERALS_REG64_SELECT_NMI_COUNTER: value = PRegs.latched_counter_nmi_events; break; - case PERIPHERALS_REG64_SELECT_WALLCLOCK_TIME: value = PRegs.latched_wallclock_time; break; - default: value = 0; /* Reading from a non-supported register will yield 0. */ + switch (Peripherals.Counter.visible_latch_register) { + case PERIPHERALS_COUNTER_SELECT_CLOCKCYCLE_COUNTER: value = Peripherals.Counter.latched_clock_cycles; break; + case PERIPHERALS_COUNTER_SELECT_INSTRUCTION_COUNTER: value = Peripherals.Counter.latched_cpu_instructions; break; + case PERIPHERALS_COUNTER_SELECT_IRQ_COUNTER: value = Peripherals.Counter.latched_irq_events; break; + case PERIPHERALS_COUNTER_SELECT_NMI_COUNTER: value = Peripherals.Counter.latched_nmi_events; break; + case PERIPHERALS_COUNTER_SELECT_WALLCLOCK_TIME: value = Peripherals.Counter.latched_wallclock_time; break; + case PERIPHERALS_COUNTER_SELECT_WALLCLOCK_TIME_SPLIT: value = Peripherals.Counter.latched_wallclock_time_split; break; + default: value = 0; /* Reading from a non-existent register will yield 0. */ } /* Return the desired byte of the latched counter. 0==LSB, 7==MSB. */ return value >> (byte_select * 8); @@ -144,16 +136,19 @@ uint8_t PeripheralReadByte (uint8_t Addr) void PeripheralsInit (void) /* Initialize the peripheral registers */ { - PRegs.counter_clock_cycles = 0; - PRegs.counter_instructions = 0; - PRegs.counter_irq_events = 0; - PRegs.counter_nmi_events = 0; + /* Initialize the COUNTER peripheral */ - PRegs.latched_counter_clock_cycles = 0; - PRegs.latched_counter_instructions = 0; - PRegs.latched_counter_irq_events = 0; - PRegs.latched_counter_nmi_events = 0; - PRegs.latched_wallclock_time = 0; + Peripherals.Counter.clock_cycles = 0; + Peripherals.Counter.cpu_instructions = 0; + Peripherals.Counter.irq_events = 0; + Peripherals.Counter.nmi_events = 0; - PRegs.visible_latch_register = 0; + Peripherals.Counter.latched_clock_cycles = 0; + Peripherals.Counter.latched_cpu_instructions = 0; + Peripherals.Counter.latched_irq_events = 0; + Peripherals.Counter.latched_nmi_events = 0; + Peripherals.Counter.latched_wallclock_time = 0; + Peripherals.Counter.latched_wallclock_time_split = 0; + + Peripherals.Counter.visible_latch_register = 0; } diff --git a/src/sim65/peripherals.h b/src/sim65/peripherals.h index 76da6e2f8..988fd2460 100644 --- a/src/sim65/peripherals.h +++ b/src/sim65/peripherals.h @@ -35,44 +35,64 @@ #include <stdint.h> -#define PERIPHERALS_APERTURE_BASE_ADDRESS 0xffc0 -#define PERIPHERALS_APERTURE_LAST_ADDRESS 0xffc9 +/* The memory range where the memory-mapped peripherals can be accessed. */ -#define PERIPHERALS_ADDRESS_OFFSET_LATCH 0x00 -#define PERIPHERALS_ADDRESS_OFFSET_SELECT 0x01 -#define PERIPHERALS_ADDRESS_OFFSET_REG64 0x02 +#define PERIPHERALS_APERTURE_BASE_ADDRESS 0xffc0 +#define PERIPHERALS_APERTURE_LAST_ADDRESS 0xffc9 -#define PERIPHERALS_LATCH (PERIPHERALS_APERTURE_BASE_ADDRESS + PERIPHERALS_ADDRESS_OFFSET_LATCH) -#define PERIPHERALS_SELECT (PERIPHERALS_APERTURE_BASE_ADDRESS + PERIPHERALS_ADDRESS_OFFSET_SELECT) -#define PERIPHERALS_REG64 (PERIPHERALS_APERTURE_BASE_ADDRESS + PERIPHERALS_ADDRESS_OFFSET_REG64) +/* Declarations for the COUNTER peripheral (currently the only peripheral). */ -#define PERIPHERALS_REG64_SELECT_CLOCKCYCLE_COUNTER 0x00 -#define PERIPHERALS_REG64_SELECT_INSTRUCTION_COUNTER 0x01 -#define PERIPHERALS_REG64_SELECT_IRQ_COUNTER 0x02 -#define PERIPHERALS_REG64_SELECT_NMI_COUNTER 0x03 -#define PERIPHERALS_REG64_SELECT_WALLCLOCK_TIME 0x80 +#define PERIPHERALS_COUNTER_ADDRESS_OFFSET_LATCH 0x00 +#define PERIPHERALS_COUNTER_ADDRESS_OFFSET_SELECT 0x01 +#define PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE 0x02 + +#define PERIPHERALS_COUNTER_LATCH (PERIPHERALS_APERTURE_BASE_ADDRESS + PERIPHERALS_ADDRESS_OFFSET_COUNTER_LATCH) +#define PERIPHERALS_COUNTER_SELECT (PERIPHERALS_APERTURE_BASE_ADDRESS + PERIPHERALS_ADDRESS_OFFSET_COUNTER_SELECT) +#define PERIPHERALS_COUNTER_VALUE (PERIPHERALS_APERTURE_BASE_ADDRESS + PERIPHERALS_ADDRESS_OFFSET_COUNTER) + +#define PERIPHERALS_COUNTER_SELECT_CLOCKCYCLE_COUNTER 0x00 +#define PERIPHERALS_COUNTER_SELECT_INSTRUCTION_COUNTER 0x01 +#define PERIPHERALS_COUNTER_SELECT_IRQ_COUNTER 0x02 +#define PERIPHERALS_COUNTER_SELECT_NMI_COUNTER 0x03 +#define PERIPHERALS_COUNTER_SELECT_WALLCLOCK_TIME 0x80 +#define PERIPHERALS_COUNTER_SELECT_WALLCLOCK_TIME_SPLIT 0x81 typedef struct { - /* the invisible counters that are continuously updated */ - uint64_t counter_clock_cycles; - uint64_t counter_instructions; - uint64_t counter_irq_events; - uint64_t counter_nmi_events; - /* latched counters upon a write to the 'latch' address. - * One of these will be visible (read only) through an each-byte aperture. */ - uint64_t latched_counter_clock_cycles; - uint64_t latched_counter_instructions; - uint64_t latched_counter_irq_events; - uint64_t latched_counter_nmi_events; + /* The invisible counters that keep processor state. */ + uint64_t clock_cycles; + uint64_t cpu_instructions; + uint64_t irq_events; + uint64_t nmi_events; + /* Latched counters upon a write to the PERIPHERALS_COUNTER_LATCH address. + * One of these will be visible (read only) through an eight-byte aperture. + * The purpose of these latched registers is to read 64-bit values one byte + * at a time, without having to worry that their content will change along + * the way. + */ + uint64_t latched_clock_cycles; + uint64_t latched_cpu_instructions; + uint64_t latched_irq_events; + uint64_t latched_nmi_events; uint64_t latched_wallclock_time; - /* Select which of the five latched registers will be visible. - * This is a Read/Write byte-wide register. - * If a non-existent register is selected, the 8-byte aperture will read as zero. + uint64_t latched_wallclock_time_split; + /* Select which of the six latched registers will be visible. + * This is a single byte, read/write register, accessible via address PERIPHERALS_COUNTER_SELECT. + * If a non-existent latch register is selected, the PERIPHERALS_REGS64 value will be zero. */ uint8_t visible_latch_register; -} PeripheralRegs; +} CounterPeripheral; -extern PeripheralRegs PRegs; + + +/* Declare the 'Sim65Peripherals' type and its single instance 'Peripherals'. */ + +typedef struct { + /* State of the peripherals simulated by sim65. + * Currently, there is only one: the COUNTER peripheral. */ + CounterPeripheral Counter; +} Sim65Peripherals; + +extern Sim65Peripherals Peripherals; /*****************************************************************************/ /* Code */ @@ -80,11 +100,11 @@ extern PeripheralRegs PRegs; -void PeripheralWriteByte (uint8_t Addr, uint8_t Val); +void PeripheralsWriteByte (uint8_t Addr, uint8_t Val); /* Write a byte to a memory location in the peripheral address aperture. */ -uint8_t PeripheralReadByte (uint8_t Addr); +uint8_t PeripheralsReadByte (uint8_t Addr); /* Read a byte from a memory location in the peripheral address aperture. */ From 3cd7548b59bef554c1ae7c412c3849019691099b Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Thu, 19 Dec 2024 03:50:44 +0100 Subject: [PATCH 324/707] Cosmetic fixes. --- src/sim65/peripherals.c | 16 ++++++++-------- src/sim65/peripherals.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index cc2eb6528..74fc49d89 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -59,16 +59,16 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* A write to the "latch" register performs a simultaneous latch of all registers. */ /* Latch the current wallclock time first. */ - struct timespec ts; + struct timespec ts; int result = clock_gettime(CLOCK_REALTIME, &ts); - if (result != 0) { - /* Unable to read time. Report max uint64 value for both fields. */ - Peripherals.Counter.latched_wallclock_time = 0xffffffffffffffff; + if (result != 0) { + /* Unable to read time. Report max uint64 value for both fields. */ + Peripherals.Counter.latched_wallclock_time = 0xffffffffffffffff; Peripherals.Counter.latched_wallclock_time_split = 0xffffffffffffffff; - } else { - /* Number of nanoseconds since 1-1-1970. */ + } else { + /* Number of nanoseconds since 1-1-1970. */ Peripherals.Counter.latched_wallclock_time = 1000000000u * ts.tv_sec + ts.tv_nsec; - /* High word is number of seconds, low word is number of nanoseconds. */ + /* High word is number of seconds, low word is number of nanoseconds. */ Peripherals.Counter.latched_wallclock_time_split = (ts.tv_sec << 32) | ts.tv_nsec; } @@ -134,7 +134,7 @@ uint8_t PeripheralsReadByte (uint8_t Addr) void PeripheralsInit (void) -/* Initialize the peripheral registers */ +/* Initialize the peripherals. */ { /* Initialize the COUNTER peripheral */ diff --git a/src/sim65/peripherals.h b/src/sim65/peripherals.h index 988fd2460..517931d85 100644 --- a/src/sim65/peripherals.h +++ b/src/sim65/peripherals.h @@ -109,7 +109,7 @@ uint8_t PeripheralsReadByte (uint8_t Addr); void PeripheralsInit (void); -/* Initialize the peripheral registers */ +/* Initialize the peripherals. */ From 743a3dc73518cf862c38df4a88c1e78fe2966358 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Thu, 19 Dec 2024 07:44:01 +0100 Subject: [PATCH 325/707] Changed nameing convention of fields (now CamelCase), and improved comments. --- src/sim65/6502.c | 10 ++--- src/sim65/error.c | 2 +- src/sim65/peripherals.c | 87 +++++++++++++++++++++++------------------ src/sim65/peripherals.h | 34 ++++++++-------- 4 files changed, 74 insertions(+), 59 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 7e993a59c..84360bad4 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -4108,7 +4108,7 @@ unsigned ExecuteInsn (void) if (HaveNMIRequest) { HaveNMIRequest = 0; - Peripherals.Counter.nmi_events += 1; + Peripherals.Counter.NmiEvents += 1; PUSH (PCH); PUSH (PCL); @@ -4124,7 +4124,7 @@ unsigned ExecuteInsn (void) } else if (HaveIRQRequest && GET_IF () == 0) { HaveIRQRequest = 0; - Peripherals.Counter.irq_events += 1; + Peripherals.Counter.IrqEvents += 1; PUSH (PCH); PUSH (PCL); @@ -4146,11 +4146,11 @@ unsigned ExecuteInsn (void) Handlers[CPU][OPC] (); /* Increment the instruction counter by one.NMIs and IRQs are counted separately. */ - Peripherals.Counter.cpu_instructions += 1; + Peripherals.Counter.CpuInstructions += 1; } - /* Increment the 64-bit clock cycle counter with the cycle count for the instruction that we just executed */ - Peripherals.Counter.clock_cycles += Cycles; + /* Increment the 64-bit clock cycle counter with the cycle count for the instruction that we just executed. */ + Peripherals.Counter.ClockCycles += Cycles; /* Return the number of clock cycles needed by this insn */ return Cycles; diff --git a/src/sim65/error.c b/src/sim65/error.c index 45fb243d8..af8e88413 100644 --- a/src/sim65/error.c +++ b/src/sim65/error.c @@ -118,7 +118,7 @@ void SimExit (int Code) /* Exit the simulation with an exit code */ { if (PrintCycles) { - fprintf (stdout, "%" PRIu64 " cycles\n", Peripherals.Counter.clock_cycles); + fprintf (stdout, "%" PRIu64 " cycles\n", Peripherals.Counter.ClockCycles); } exit (Code); } diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 74fc49d89..fbd4159e3 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -55,6 +55,9 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* Write a byte to a memory location in the peripherals address aperture. */ { switch (Addr) { + + /* Handle writes to the Counter peripheral. */ + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_LATCH: { /* A write to the "latch" register performs a simultaneous latch of all registers. */ @@ -63,29 +66,33 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) int result = clock_gettime(CLOCK_REALTIME, &ts); if (result != 0) { /* Unable to read time. Report max uint64 value for both fields. */ - Peripherals.Counter.latched_wallclock_time = 0xffffffffffffffff; - Peripherals.Counter.latched_wallclock_time_split = 0xffffffffffffffff; + Peripherals.Counter.LatchedWallclockTime = 0xffffffffffffffff; + Peripherals.Counter.LatchedWallclockTimeSplit = 0xffffffffffffffff; } else { - /* Number of nanoseconds since 1-1-1970. */ - Peripherals.Counter.latched_wallclock_time = 1000000000u * ts.tv_sec + ts.tv_nsec; - /* High word is number of seconds, low word is number of nanoseconds. */ - Peripherals.Counter.latched_wallclock_time_split = (ts.tv_sec << 32) | ts.tv_nsec; + /* Wallclock time: number of nanoseconds since 1-1-1970. */ + Peripherals.Counter.LatchedWallclockTime = 1000000000u * ts.tv_sec + ts.tv_nsec; + /* Wallclock time, split: high word is number of seconds since 1-1-1970, + * low word is number of nanoseconds since the start of that second. */ + Peripherals.Counter.LatchedWallclockTimeSplit = (ts.tv_sec << 32) | ts.tv_nsec; } /* Latch the counters that reflect the state of the processor. */ - Peripherals.Counter.latched_clock_cycles = Peripherals.Counter.clock_cycles; - Peripherals.Counter.latched_cpu_instructions = Peripherals.Counter.cpu_instructions; - Peripherals.Counter.latched_irq_events = Peripherals.Counter.irq_events; - Peripherals.Counter.latched_nmi_events = Peripherals.Counter.nmi_events; + Peripherals.Counter.LatchedClockCycles = Peripherals.Counter.ClockCycles; + Peripherals.Counter.LatchedCpuInstructions = Peripherals.Counter.CpuInstructions; + Peripherals.Counter.LatchedIrqEvents = Peripherals.Counter.IrqEvents; + Peripherals.Counter.LatchedNmiEvents = Peripherals.Counter.NmiEvents; break; } case PERIPHERALS_COUNTER_ADDRESS_OFFSET_SELECT: { /* Set the value of the visibility-selection register. */ - Peripherals.Counter.visible_latch_register = Val; + Peripherals.Counter.LatchedValueSelected = Val; break; } + + /* Handle writes to unused and read-only peripheral addresses. */ + default: { - /* Any other write is ignored */ + /* No action. */ } } } @@ -96,8 +103,11 @@ uint8_t PeripheralsReadByte (uint8_t Addr) /* Read a byte from a memory location in the peripherals address aperture. */ { switch (Addr) { + + /* Handle reads from the Counter peripheral. */ + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_SELECT: { - return Peripherals.Counter.visible_latch_register; + return Peripherals.Counter.LatchedValueSelected; } case PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE + 0: case PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE + 1: @@ -110,22 +120,25 @@ uint8_t PeripheralsReadByte (uint8_t Addr) /* Read from any of the eight counter bytes. * The first byte is the 64 bit value's LSB, the seventh byte is its MSB. */ - unsigned byte_select = Addr - PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE; /* 0 .. 7 */ - uint64_t value; - switch (Peripherals.Counter.visible_latch_register) { - case PERIPHERALS_COUNTER_SELECT_CLOCKCYCLE_COUNTER: value = Peripherals.Counter.latched_clock_cycles; break; - case PERIPHERALS_COUNTER_SELECT_INSTRUCTION_COUNTER: value = Peripherals.Counter.latched_cpu_instructions; break; - case PERIPHERALS_COUNTER_SELECT_IRQ_COUNTER: value = Peripherals.Counter.latched_irq_events; break; - case PERIPHERALS_COUNTER_SELECT_NMI_COUNTER: value = Peripherals.Counter.latched_nmi_events; break; - case PERIPHERALS_COUNTER_SELECT_WALLCLOCK_TIME: value = Peripherals.Counter.latched_wallclock_time; break; - case PERIPHERALS_COUNTER_SELECT_WALLCLOCK_TIME_SPLIT: value = Peripherals.Counter.latched_wallclock_time_split; break; - default: value = 0; /* Reading from a non-existent register will yield 0. */ + unsigned ByteIndex = Addr - PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE; /* 0 .. 7 */ + uint64_t Value; + switch (Peripherals.Counter.LatchedValueSelected) { + case PERIPHERALS_COUNTER_SELECT_CLOCKCYCLE_COUNTER: Value = Peripherals.Counter.LatchedClockCycles; break; + case PERIPHERALS_COUNTER_SELECT_INSTRUCTION_COUNTER: Value = Peripherals.Counter.LatchedCpuInstructions; break; + case PERIPHERALS_COUNTER_SELECT_IRQ_COUNTER: Value = Peripherals.Counter.LatchedIrqEvents; break; + case PERIPHERALS_COUNTER_SELECT_NMI_COUNTER: Value = Peripherals.Counter.LatchedNmiEvents; break; + case PERIPHERALS_COUNTER_SELECT_WALLCLOCK_TIME: Value = Peripherals.Counter.LatchedWallclockTime; break; + case PERIPHERALS_COUNTER_SELECT_WALLCLOCK_TIME_SPLIT: Value = Peripherals.Counter.LatchedWallclockTimeSplit; break; + default: Value = 0; /* Reading from a non-existent latch register will yield 0. */ } /* Return the desired byte of the latched counter. 0==LSB, 7==MSB. */ - return value >> (byte_select * 8); + return Value >> (ByteIndex * 8); } + + /* Handle reads from unused peripheral and write-only addresses. */ + default: { - /* Any other read yields a zero value. */ + /* Return zero value. */ return 0; } } @@ -136,19 +149,19 @@ uint8_t PeripheralsReadByte (uint8_t Addr) void PeripheralsInit (void) /* Initialize the peripherals. */ { - /* Initialize the COUNTER peripheral */ + /* Initialize the Counter peripheral */ - Peripherals.Counter.clock_cycles = 0; - Peripherals.Counter.cpu_instructions = 0; - Peripherals.Counter.irq_events = 0; - Peripherals.Counter.nmi_events = 0; + Peripherals.Counter.ClockCycles = 0; + Peripherals.Counter.CpuInstructions = 0; + Peripherals.Counter.IrqEvents = 0; + Peripherals.Counter.NmiEvents = 0; - Peripherals.Counter.latched_clock_cycles = 0; - Peripherals.Counter.latched_cpu_instructions = 0; - Peripherals.Counter.latched_irq_events = 0; - Peripherals.Counter.latched_nmi_events = 0; - Peripherals.Counter.latched_wallclock_time = 0; - Peripherals.Counter.latched_wallclock_time_split = 0; + Peripherals.Counter.LatchedClockCycles = 0; + Peripherals.Counter.LatchedCpuInstructions = 0; + Peripherals.Counter.LatchedIrqEvents = 0; + Peripherals.Counter.LatchedNmiEvents = 0; + Peripherals.Counter.LatchedWallclockTime = 0; + Peripherals.Counter.LatchedWallclockTimeSplit = 0; - Peripherals.Counter.visible_latch_register = 0; + Peripherals.Counter.LatchedValueSelected = 0; } diff --git a/src/sim65/peripherals.h b/src/sim65/peripherals.h index 517931d85..16ea83782 100644 --- a/src/sim65/peripherals.h +++ b/src/sim65/peripherals.h @@ -59,27 +59,29 @@ typedef struct { /* The invisible counters that keep processor state. */ - uint64_t clock_cycles; - uint64_t cpu_instructions; - uint64_t irq_events; - uint64_t nmi_events; - /* Latched counters upon a write to the PERIPHERALS_COUNTER_LATCH address. + uint64_t ClockCycles; + uint64_t CpuInstructions; + uint64_t IrqEvents; + uint64_t NmiEvents; + /* The 'latched_...' fields below hold values that are sampled upon a write + * to the PERIPHERALS_COUNTER_LATCH address. * One of these will be visible (read only) through an eight-byte aperture. * The purpose of these latched registers is to read 64-bit values one byte * at a time, without having to worry that their content will change along * the way. */ - uint64_t latched_clock_cycles; - uint64_t latched_cpu_instructions; - uint64_t latched_irq_events; - uint64_t latched_nmi_events; - uint64_t latched_wallclock_time; - uint64_t latched_wallclock_time_split; + uint64_t LatchedClockCycles; + uint64_t LatchedCpuInstructions; + uint64_t LatchedIrqEvents; + uint64_t LatchedNmiEvents; + uint64_t LatchedWallclockTime; + uint64_t LatchedWallclockTimeSplit; /* Select which of the six latched registers will be visible. - * This is a single byte, read/write register, accessible via address PERIPHERALS_COUNTER_SELECT. - * If a non-existent latch register is selected, the PERIPHERALS_REGS64 value will be zero. + * This is a single byte, read/write register, accessible via address + * PERIPHERALS_COUNTER_SELECT. If a non-existent latch register is selected, + * the PERIPHERALS_COUNTER_VALUE will be zero. */ - uint8_t visible_latch_register; + uint8_t LatchedValueSelected; } CounterPeripheral; @@ -87,8 +89,8 @@ typedef struct { /* Declare the 'Sim65Peripherals' type and its single instance 'Peripherals'. */ typedef struct { - /* State of the peripherals simulated by sim65. - * Currently, there is only one: the COUNTER peripheral. */ + /* State of the peripherals available in sim65. + * Currently, there is only one peripheral: the Counter. */ CounterPeripheral Counter; } Sim65Peripherals; From eb8ea0f2c41841a5fe44ea1a40027f90d2dda85e Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Thu, 19 Dec 2024 20:57:34 +0100 Subject: [PATCH 326/707] Replaced incidental tab by spaces. --- src/sim65/peripherals.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index fbd4159e3..33e206ff3 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -29,7 +29,6 @@ /*****************************************************************************/ - #include <time.h> #include "peripherals.h" @@ -72,7 +71,7 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* Wallclock time: number of nanoseconds since 1-1-1970. */ Peripherals.Counter.LatchedWallclockTime = 1000000000u * ts.tv_sec + ts.tv_nsec; /* Wallclock time, split: high word is number of seconds since 1-1-1970, - * low word is number of nanoseconds since the start of that second. */ + * low word is number of nanoseconds since the start of that second. */ Peripherals.Counter.LatchedWallclockTimeSplit = (ts.tv_sec << 32) | ts.tv_nsec; } @@ -105,7 +104,7 @@ uint8_t PeripheralsReadByte (uint8_t Addr) switch (Addr) { /* Handle reads from the Counter peripheral. */ - + case PERIPHERALS_COUNTER_ADDRESS_OFFSET_SELECT: { return Peripherals.Counter.LatchedValueSelected; } From bad2f54f75e6b4688b3ffd20ee4c77115d1feac3 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Thu, 19 Dec 2024 22:35:15 +0100 Subject: [PATCH 327/707] Fix memory access order of the JSR instruction. The obvious way to implement JSR for the 6502 is to (a) read the target address, and then (b) push the return address minus one. Or do (b) first, then (a). However, there is a non-obvious case where this conflicts with the actual order of operations that the 6502 does, which is: (a) Load the LSB of the target address. (b) Push the MSB of the return address, minus one. (c) Push the LSB of the return address, minus one. (d) Load the MSB of the target address. This can make a difference in a pretty esoteric case, if the JSR target is located, wholly or in part, inside the stack page (!). This won't happen in normal code but it can happen in specifically constructed examples. To deal with this, we load the LSB and MSB of the target address separately, with the pushing of the return address sandwiched in between, to mimic the order of the bus operations on a real 6502. --- src/sim65/6502.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index cb3270185..bae23d9c0 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -1456,13 +1456,37 @@ static void OPC_6502_1F (void) static void OPC_6502_20 (void) /* Opcode $20: JSR */ { - unsigned Addr; + /* The obvious way to implement JSR for the 6502 is to (a) read the target address, + * and then (b) push the return address minus one. Or do (b) first, then (a). + * + * However, there is a non-obvious case where this conflicts with the actual order + * of operations that the 6502 does, which is: + * + * (a) Load the LSB of the target address. + * (b) Push the MSB of the return address, minus one. + * (c) Push the LSB of the return address, minus one. + * (d) Load the MSB of the target address. + * + * This can make a difference in a pretty esoteric case, if the JSR target is located, + * wholly or in part, inside the stack page (!). This won't happen in normal code + * but it can happen in specifically constructed examples. + * + * To deal with this, we load the LSB and MSB of the target address separately, + * with the pushing of the return address sandwiched in between, to mimic + * the order of the bus operations on a real 6502. + */ + + unsigned AddrLo, AddrHi; + Cycles = 6; - Addr = MemReadWord (Regs.PC+1); - Regs.PC += 2; + Regs.PC += 1; + AddrLo = MemReadByte(Regs.PC); + Regs.PC += 1; PUSH (PCH); PUSH (PCL); - Regs.PC = Addr; + AddrHi = MemReadByte(Regs.PC); + + Regs.PC = AddrLo + (AddrHi << 8); ParaVirtHooks (&Regs); } From b14f883e7339a0edbd734939cf910b2a5838f8b2 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Thu, 19 Dec 2024 22:58:42 +0100 Subject: [PATCH 328/707] sim65: changes constant of the unstable "ANE" instruction to comply with 65x02 test suite. ANE (0x8b) is an unstable illegal opcode that depends on a "constant" value that isn't really constant. It varies between machines, with temperature, and so on. Original sim65 behavior was to use the constant value 0xEF. To get the behavior in line with the 65x02 testsuite, we now use the value 0xEE instead, which is also a reasonable choice that can be observed in practice. --- src/sim65/6502.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index cb3270185..166d54e2e 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -969,8 +969,14 @@ static unsigned HaveIRQRequest; } while (0); /* ANE */ +/* An "unstable" illegal opcode that depends on a "constant" value that isn't + * really constant. It varies between machines, with temperature, and so on. + * Original sim65 behavior was to use the constant 0xEF here. To get behavior + * in line with the 65x02 testsuite, we now use the value 0xEE instead, + * which is also a reasonable choice that can be observed in practice. + */ #define ANE(Val) \ - Val = (Regs.AC | 0xEF) & Regs.XR & Val; \ + Val = (Regs.AC | 0xEE) & Regs.XR & Val; \ Regs.AC = Val; \ TEST_SF (Val); \ TEST_ZF (Val) From 8cb941985dec9d7cf275fa29a0ceb0b45da75b3c Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Thu, 19 Dec 2024 23:13:20 +0100 Subject: [PATCH 329/707] sim65: tighten 6502 register types After a lot of preparatory work, we are now in position to finally tighten the types of the 6502 registers defined in the CPURegs struct of sim65. All registers were previously defined as bare 'unsigned', leading to subtle bugs where the bits beyond the 8 or 16 "true" bits in the register could become non-zero. Tightening the types of the registers to uint8_t and uint16_t as appropriate gets rid of these subtle bugs once and for all, assisted by the semantics of C when assigning an unsigned value to an unsigned type with less bits: the high-order bits are simply discarded, which is precisely what we'd want to happen. This change cleans up a lot of spurious failures of sim65 against the 65x02 test-set. For the 6502 and 65C02, we're now *functionally* compliant. For timing (i.e., clock cycle counts for each instruction), some work remains. --- src/sim65/6502.c | 10 ++-------- src/sim65/6502.h | 14 ++++++++------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index cb3270185..8b16da2b8 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -664,15 +664,12 @@ static unsigned HaveIRQRequest; /* ADC, binary mode (6502 and 65C02) */ -/* TODO: once the Regs fields are properly sized, get rid of the - * "& 0xff" in the Regs.AC asignment. - */ #define ADC_BINARY_MODE(v) \ do { \ const uint8_t op = v; \ const uint8_t OldAC = Regs.AC; \ bool carry = GET_CF(); \ - Regs.AC = (OldAC + op + carry) & 0xff; \ + Regs.AC = (OldAC + op + carry); \ const bool NV = Regs.AC >= 0x80; \ carry = OldAC + op + carry >= 0x100; \ SET_SF(NV); \ @@ -1027,15 +1024,12 @@ static unsigned HaveIRQRequest; TEST_ZF (Val) /* SBC, binary mode (6502 and 65C02) */ -/* TODO: once the Regs fields are properly sized, get rid of the - * "& 0xff" in the Regs.AC asignment. - */ #define SBC_BINARY_MODE(v) \ do { \ const uint8_t op = v; \ const uint8_t OldAC = Regs.AC; \ const bool borrow = !GET_CF(); \ - Regs.AC = (OldAC - op - borrow) & 0xff; \ + Regs.AC = (OldAC - op - borrow); \ const bool NV = Regs.AC >= 0x80; \ SET_SF(NV); \ SET_OF(((OldAC >= 0x80) ^ NV) & ((op < 0x80) ^ NV)); \ diff --git a/src/sim65/6502.h b/src/sim65/6502.h index b6b621823..0f4d066d0 100644 --- a/src/sim65/6502.h +++ b/src/sim65/6502.h @@ -37,6 +37,8 @@ #define _6502_H +#include <stdint.h> + /*****************************************************************************/ /* Data */ @@ -57,12 +59,12 @@ extern CPUType CPU; /* 6502 CPU registers */ typedef struct CPURegs CPURegs; struct CPURegs { - unsigned AC; /* Accumulator */ - unsigned XR; /* X register */ - unsigned YR; /* Y register */ - unsigned SR; /* Status register */ - unsigned SP; /* Stackpointer */ - unsigned PC; /* Program counter */ + uint8_t AC; /* Accumulator */ + uint8_t XR; /* X register */ + uint8_t YR; /* Y register */ + uint8_t SR; /* Status register */ + uint8_t SP; /* Stackpointer */ + uint16_t PC; /* Program counter */ }; /* Current CPU registers */ From 178ab08fe2d090ef5005277cac716754e8d0dd59 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Fri, 20 Dec 2024 21:47:01 +0100 Subject: [PATCH 330/707] Test to demonstrate issue #2566. --- test/todo/bug2566.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 test/todo/bug2566.c diff --git a/test/todo/bug2566.c b/test/todo/bug2566.c new file mode 100644 index 000000000..29292c3dd --- /dev/null +++ b/test/todo/bug2566.c @@ -0,0 +1,49 @@ + +/* Regression test for https://github.com/cc65/cc65/issues/2566 + * + * The issue was introduced in an innocious-looking commit back in 2020: + * + * https://github.com/cc65/cc65/commit/c3a6b399456937093eda9994f19b7f722731528d + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> + +typedef struct { + unsigned long Field1; + unsigned long Field2; +} RecordType; + +typedef struct { + char dummy; // -- Offsets the Rec field by 1 byte. + RecordType Rec; +} StructTypeA; + +typedef struct { + RecordType Rec; +} StructTypeB; + +int main(void) +{ + StructTypeA A, *Aptr; + StructTypeB B; + bool ok; + + A.Rec.Field1 = 0x11111111; + A.Rec.Field2 = 0x22222222; + + Aptr = &A; + B.Rec = Aptr->Rec; + + /* These print statements give some clues as to what's going on. */ + /* + printf("A.Rec: %lx, %lx\n", A.Rec.Field1, A.Rec.Field2); + printf("B.Rec: %lx, %lx\n", B.Rec.Field1, B.Rec.Field2); + */ + + ok = (A.Rec.Field1 == B.Rec.Field1 && A.Rec.Field2 == B.Rec.Field2); + + return ok ? EXIT_SUCCESS : EXIT_FAILURE; +} From d064ca424fe2aaea19725ac2cd32d40100ff23c9 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Sun, 22 Dec 2024 19:15:20 +0100 Subject: [PATCH 331/707] sim65: implemented missing 65C02 instructions This PR implements support for 32 65C02-specific instructions to sim65: BBRx, BBSx, RMBx, SMBx, with x = 0..7. These instructions are implemented using two macros: * The "ZP_BITOP" macro implements the RMBx and SMBx isntructions. * The "ZP_BIT_BRANCH" macro implements the BBRx abd BBSx instructions. The implementation of these instructions has been verified usingthe 65x02 test suite. --- src/sim65/6502.c | 386 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 341 insertions(+), 45 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index bfb3f3e9b..1c915e618 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -35,9 +35,8 @@ /*****************************************************************************/ /* Known bugs and limitations of the 65C02 simulation: - * support currently only on the level of 65SC02: - BBRx, BBSx, RMBx, SMBx, WAI, and STP are unsupported -*/ + * the WAI ($CB) and STP ($DB) instructions are unsupported. + */ #include <stdbool.h> #include <stdint.h> @@ -623,14 +622,14 @@ static unsigned HaveIRQRequest; /* 2 x Read-Modify-Write opcode helpers (illegal opcodes) */ /* Execution cycles for 2 x R-M-W opcodes */ -#define RMW2_CY_ZP 5 -#define RMW2_CY_ZPX 6 +#define RMW2_CY_ZP 5 +#define RMW2_CY_ZPX 6 #define RMW2_CY_ZPY 6 -#define RMW2_CY_ABS 6 -#define RMW2_CY_ABSX 7 -#define RMW2_CY_ABSY 7 -#define RMW2_CY_ZPXIND 8 -#define RMW2_CY_ZPINDY 8 +#define RMW2_CY_ABS 6 +#define RMW2_CY_ABSX 7 +#define RMW2_CY_ABSY 7 +#define RMW2_CY_ZPXIND 8 +#define RMW2_CY_ZPINDY 8 /* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y */ #define ILLx2_OP(mode, op) \ @@ -1112,6 +1111,46 @@ static unsigned HaveIRQRequest; +/* Set/reset a specific bit in a zero-page byte. This macro + * macro is used to implement the 65C02 RMBx and SMBx instructions. + */ +#define ZP_BITOP(bitnr, bitval) \ + do { \ + uint8_t zp_address = MemReadByte (Regs.PC + 1); \ + uint8_t zp_value = MemReadByte (zp_address); \ + if (bitval) { \ + zp_value |= (1 << bitnr); \ + } else { \ + zp_value &= ~(1 << bitnr); \ + } \ + MemWriteByte (zp_address, zp_value); \ + Regs.PC += 2; \ + Cycles = 5; \ + } while (0) + +/* Branch depending on the state of a specific bit of a zero page + * address. This macro is used to implement the 65C02 BBRx and + * BBSx instructions. + */ +#define ZP_BIT_BRANCH(bitnr, bitval) \ + do { \ + uint8_t zp_address = MemReadByte (Regs.PC + 1); \ + uint8_t zp_value = MemReadByte (zp_address); \ + int displacement = (int8_t)MemReadByte (Regs.PC + 2); \ + if (((zp_value & (1 << bitnr)) != 0) == bitval) { \ + Regs.PC += 3; \ + uint8_t OldPCH = PCH; \ + Regs.PC += displacement; \ + Cycles = 6; \ + if (PCH != OldPCH) { \ + Cycles += 1; \ + } \ + } else { \ + Regs.PC += 3; \ + Cycles = 5; \ + } \ + } while (0) + /*****************************************************************************/ /* Opcode handling functions */ /*****************************************************************************/ @@ -1204,6 +1243,14 @@ static void OPC_6502_07 (void) +static void OPC_65C02_07 (void) +/* Opcode $07: RMB0 zp */ +{ + ZP_BITOP(0, 0); +} + + + static void OPC_6502_08 (void) /* Opcode $08: PHP */ { @@ -1283,6 +1330,14 @@ static void OPC_6502_0F (void) +static void OPC_65C02_0F (void) +/* Opcode $0F: BBR0 zp, rel */ +{ + ZP_BIT_BRANCH (0, 0); +} + + + static void OPC_6502_10 (void) /* Opcode $10: BPL */ { @@ -1362,6 +1417,14 @@ static void OPC_6502_17 (void) +static void OPC_65C02_17 (void) +/* Opcode $17: RMB1 zp */ +{ + ZP_BITOP(1, 0); +} + + + static void OPC_6502_18 (void) /* Opcode $18: CLC */ { @@ -1453,6 +1516,15 @@ static void OPC_6502_1F (void) + +static void OPC_65C02_1F (void) +/* Opcode $1F: BBR1 zp, rel */ +{ + ZP_BIT_BRANCH (1, 0); +} + + + static void OPC_6502_20 (void) /* Opcode $20: JSR */ { @@ -1541,6 +1613,14 @@ static void OPC_6502_27 (void) +static void OPC_65C02_27 (void) +/* Opcode $27: RMB2 zp */ +{ + ZP_BITOP(2, 0); +} + + + static void OPC_6502_28 (void) /* Opcode $28: PLP */ { @@ -1604,6 +1684,14 @@ static void OPC_6502_2F (void) +static void OPC_65C02_2F (void) +/* Opcode $2F: BBR2 zp, rel */ +{ + ZP_BIT_BRANCH (2, 0); +} + + + static void OPC_6502_30 (void) /* Opcode $30: BMI */ { @@ -1668,6 +1756,14 @@ static void OPC_6502_37 (void) +static void OPC_65C02_37 (void) +/* Opcode $37: RMB3 zp */ +{ + ZP_BITOP(3, 0); +} + + + static void OPC_6502_38 (void) /* Opcode $38: SEC */ { @@ -1744,6 +1840,14 @@ static void OPC_6502_3F (void) +static void OPC_65C02_3F (void) +/* Opcode $3F: BBR3 zp, rel */ +{ + ZP_BIT_BRANCH (3, 0); +} + + + static void OPC_6502_40 (void) /* Opcode $40: RTI */ { @@ -1797,6 +1901,14 @@ static void OPC_6502_47 (void) +static void OPC_65C02_47 (void) +/* Opcode $47: RMB4 zp */ +{ + ZP_BITOP(4, 0); +} + + + static void OPC_6502_48 (void) /* Opcode $48: PHA */ { @@ -1868,6 +1980,14 @@ static void OPC_6502_4F (void) +static void OPC_65C02_4F (void) +/* Opcode $4F: BBR4 zp, rel */ +{ + ZP_BIT_BRANCH (4, 0); +} + + + static void OPC_6502_50 (void) /* Opcode $50: BVC */ { @@ -1924,6 +2044,14 @@ static void OPC_6502_57 (void) +static void OPC_65C02_57 (void) +/* Opcode $57: RMB5 zp */ +{ + ZP_BITOP(5, 0); +} + + + static void OPC_6502_58 (void) /* Opcode $58: CLI */ { @@ -2001,6 +2129,14 @@ static void OPC_6502_5F (void) +static void OPC_65C02_5F (void) +/* Opcode $5F: BBR5 zp, rel */ +{ + ZP_BIT_BRANCH (5, 0); +} + + + static void OPC_6502_60 (void) /* Opcode $60: RTS */ { @@ -2074,6 +2210,14 @@ static void OPC_6502_67 (void) +static void OPC_65C02_67 (void) +/* Opcode $67: RMB6 zp */ +{ + ZP_BITOP(6, 0); +} + + + static void OPC_6502_68 (void) /* Opcode $68: PLA */ { @@ -2187,6 +2331,14 @@ static void OPC_6502_6F (void) +static void OPC_65C02_6F (void) +/* Opcode $6F: BBR6 zp, rel */ +{ + ZP_BIT_BRANCH (6, 0); +} + + + static void OPC_6502_70 (void) /* Opcode $70: BVS */ { @@ -2265,6 +2417,14 @@ static void OPC_6502_77 (void) +static void OPC_65C02_77 (void) +/* Opcode $77: RMB7 zp */ +{ + ZP_BITOP(7, 0); +} + + + static void OPC_6502_78 (void) /* Opcode $78: SEI */ { @@ -2365,6 +2525,14 @@ static void OPC_6502_7F (void) +static void OPC_65C02_7F (void) +/* Opcode $7F: BBR7 zp, rel */ +{ + ZP_BIT_BRANCH (7, 0); +} + + + /* Aliases of opcode $80 */ #define OPC_6502_82 OPC_6502_80 #define OPC_6502_C2 OPC_6502_80 @@ -2435,6 +2603,14 @@ static void OPC_6502_87 (void) +static void OPC_65C02_87 (void) +/* Opcode $87: SMB0 zp */ +{ + ZP_BITOP(0, 1); +} + + + static void OPC_6502_88 (void) /* Opcode $88: DEY */ { @@ -2507,6 +2683,14 @@ static void OPC_6502_8F (void) +static void OPC_65C02_8F (void) +/* Opcode $8F: BBS0 zp, rel */ +{ + ZP_BIT_BRANCH (0, 1); +} + + + static void OPC_6502_90 (void) /* Opcode $90: BCC */ { @@ -2571,6 +2755,14 @@ static void OPC_6502_97 (void) +static void OPC_65C02_97 (void) +/* Opcode $97: SMB1 zp */ +{ + ZP_BITOP(1, 1); +} + + + static void OPC_6502_98 (void) /* Opcode $98: TYA */ { @@ -2641,6 +2833,14 @@ static void OPC_6502_9E (void) +static void OPC_65SC02_9E (void) +/* Opcode $9E: STZ abs,x */ +{ + STO_OP (ABSX, 0); +} + + + static void OPC_6502_9F (void) /* Opcode $9F: SHA abs,y */ { @@ -2649,10 +2849,10 @@ static void OPC_6502_9F (void) -static void OPC_65SC02_9E (void) -/* Opcode $9E: STZ abs,x */ +static void OPC_65C02_9F (void) +/* Opcode $9F: BBS1 zp, rel */ { - STO_OP (ABSX, 0); + ZP_BIT_BRANCH (1, 1); } @@ -2721,6 +2921,14 @@ static void OPC_6502_A7 (void) +static void OPC_65C02_A7 (void) +/* Opcode $A7: SMB2 zp */ +{ + ZP_BITOP(2, 1); +} + + + static void OPC_6502_A8 (void) /* Opcode $A8: TAY */ { @@ -2793,6 +3001,14 @@ static void OPC_6502_AF (void) +static void OPC_65C02_AF (void) +/* Opcode $AF: BBS2 zp, rel */ +{ + ZP_BIT_BRANCH (2, 1); +} + + + static void OPC_6502_B0 (void) /* Opcode $B0: BCS */ { @@ -2857,6 +3073,14 @@ static void OPC_6502_B7 (void) +static void OPC_65C02_B7 (void) +/* Opcode $B7: SMB3 zp */ +{ + ZP_BITOP(3, 1); +} + + + static void OPC_6502_B8 (void) /* Opcode $B8: CLV */ { @@ -2927,6 +3151,14 @@ static void OPC_6502_BF (void) +static void OPC_65C02_BF (void) +/* Opcode $BF: BBS3 zp, rel */ +{ + ZP_BIT_BRANCH (3, 1); +} + + + static void OPC_6502_C0 (void) /* Opcode $C0: CPY #imm */ { @@ -2983,6 +3215,14 @@ static void OPC_6502_C7 (void) +static void OPC_65C02_C7 (void) +/* Opcode $C7: SMB4 zp */ +{ + ZP_BITOP(4, 1); +} + + + static void OPC_6502_C8 (void) /* Opcode $C8: INY */ { @@ -3051,6 +3291,14 @@ static void OPC_6502_CF (void) +static void OPC_65C02_CF (void) +/* Opcode $CF: BBS4 zp, rel */ +{ + ZP_BIT_BRANCH (4, 1); +} + + + static void OPC_6502_D0 (void) /* Opcode $D0: BNE */ { @@ -3107,6 +3355,14 @@ static void OPC_6502_D7 (void) +static void OPC_65C02_D7 (void) +/* Opcode $D7: SMB5 zp */ +{ + ZP_BITOP(5, 1); +} + + + static void OPC_6502_D8 (void) /* Opcode $D8: CLD */ { @@ -3167,6 +3423,14 @@ static void OPC_6502_DF (void) +static void OPC_65C02_DF (void) +/* Opcode $DF: BBS5 zp, rel */ +{ + ZP_BIT_BRANCH (5, 1); +} + + + static void OPC_6502_E0 (void) /* Opcode $E0: CPX #imm */ { @@ -3237,6 +3501,14 @@ static void OPC_6502_E7 (void) +static void OPC_65C02_E7 (void) +/* Opcode $E7: SMB6 zp */ +{ + ZP_BITOP(6, 1); +} + + + static void OPC_6502_E8 (void) /* Opcode $E8: INX */ { @@ -3357,6 +3629,14 @@ static void OPC_6502_EF (void) +static void OPC_65C02_EF (void) +/* Opcode $EF: BBS6 zp, rel */ +{ + ZP_BIT_BRANCH (6, 1); +} + + + static void OPC_6502_F0 (void) /* Opcode $F0: BEQ */ { @@ -3430,6 +3710,14 @@ static void OPC_6502_F7 (void) +static void OPC_65C02_F7 (void) +/* Opcode $F7: SMB7 zp */ +{ + ZP_BITOP(7, 1); +} + + + static void OPC_6502_F8 (void) /* Opcode $F8: SED */ { @@ -3508,6 +3796,14 @@ static void OPC_6502_FF (void) +static void OPC_65C02_FF (void) +/* Opcode $FF: BBS7 zp, rel */ +{ + ZP_BIT_BRANCH (7, 1); +} + + + /*****************************************************************************/ /* Opcode handler tables */ /*****************************************************************************/ @@ -4047,7 +4343,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65SC02_04, OPC_6502_05, OPC_6502_06, - OPC_Illegal, // $07: RMB0 currently unsupported + OPC_65C02_07, OPC_6502_08, OPC_6502_09, OPC_6502_0A, @@ -4055,7 +4351,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65SC02_0C, OPC_6502_0D, OPC_6502_0E, - OPC_Illegal, // $0F: BBR0 currently unsupported + OPC_65C02_0F, OPC_6502_10, OPC_6502_11, OPC_65SC02_12, @@ -4063,7 +4359,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65SC02_14, OPC_6502_15, OPC_6502_16, - OPC_Illegal, // $17: RMB1 currently unsupported + OPC_65C02_17, OPC_6502_18, OPC_6502_19, OPC_65SC02_1A, @@ -4071,7 +4367,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65SC02_1C, OPC_6502_1D, OPC_65C02_1E, - OPC_Illegal, // $1F: BBR1 currently unsupported + OPC_65C02_1F, OPC_6502_20, OPC_6502_21, OPC_65C02_NOP22, // $22 @@ -4079,7 +4375,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_24, OPC_6502_25, OPC_6502_26, - OPC_Illegal, // $27: RMB2 currently unsupported + OPC_65C02_27, OPC_6502_28, OPC_6502_29, OPC_6502_2A, @@ -4087,7 +4383,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_2C, OPC_6502_2D, OPC_6502_2E, - OPC_Illegal, // $2F: BBR2 currently unsupported + OPC_65C02_2F, OPC_6502_30, OPC_6502_31, OPC_65SC02_32, @@ -4095,7 +4391,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65SC02_34, OPC_6502_35, OPC_6502_36, - OPC_Illegal, // $37: RMB3 currently unsupported + OPC_65C02_37, OPC_6502_38, OPC_6502_39, OPC_65SC02_3A, @@ -4103,7 +4399,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65SC02_3C, OPC_6502_3D, OPC_65C02_3E, - OPC_Illegal, // $3F: BBR3 currently unsupported + OPC_65C02_3F, OPC_6502_40, OPC_6502_41, OPC_65C02_NOP22, // $42 @@ -4111,7 +4407,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_44, // $44 OPC_6502_45, OPC_6502_46, - OPC_Illegal, // $47: RMB4 currently unsupported + OPC_65C02_47, OPC_6502_48, OPC_6502_49, OPC_6502_4A, @@ -4119,7 +4415,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_4C, OPC_6502_4D, OPC_6502_4E, - OPC_Illegal, // $4F: BBR4 currently unsupported + OPC_65C02_4F, OPC_6502_50, OPC_6502_51, OPC_65SC02_52, @@ -4127,7 +4423,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_NOP24, // $54 OPC_6502_55, OPC_6502_56, - OPC_Illegal, // $57: RMB5 currently unsupported + OPC_65C02_57, OPC_6502_58, OPC_6502_59, OPC_65SC02_5A, @@ -4135,7 +4431,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_5C, OPC_6502_5D, OPC_65C02_5E, - OPC_Illegal, // $5F: BBR5 currently unsupported + OPC_65C02_5F, OPC_6502_60, OPC_65C02_61, OPC_65C02_NOP22, // $62 @@ -4143,7 +4439,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65SC02_64, OPC_65C02_65, OPC_6502_66, - OPC_Illegal, // $67: RMB6 currently unsupported + OPC_65C02_67, OPC_6502_68, OPC_65C02_69, OPC_6502_6A, @@ -4151,7 +4447,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_6C, OPC_65C02_6D, OPC_6502_6E, - OPC_Illegal, // $6F: BBR6 currently unsupported + OPC_65C02_6F, OPC_6502_70, OPC_65C02_71, OPC_65C02_72, @@ -4159,7 +4455,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65SC02_74, OPC_65C02_75, OPC_6502_76, - OPC_Illegal, // $77: RMB7 currently unsupported + OPC_65C02_77, OPC_6502_78, OPC_65C02_79, OPC_65SC02_7A, @@ -4167,7 +4463,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65SC02_7C, OPC_65C02_7D, OPC_65C02_7E, - OPC_Illegal, // $7F: BBR7 currently unsupported + OPC_65C02_7F, OPC_65SC02_80, OPC_6502_81, OPC_65C02_NOP22, // $82 @@ -4175,7 +4471,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_84, OPC_6502_85, OPC_6502_86, - OPC_Illegal, // $87: SMB0 currently unsupported + OPC_65C02_87, OPC_6502_88, OPC_65SC02_89, OPC_6502_8A, @@ -4183,7 +4479,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_8C, OPC_6502_8D, OPC_6502_8E, - OPC_Illegal, // $8F: BBS0 currently unsupported + OPC_65C02_8F, OPC_6502_90, OPC_6502_91, OPC_65SC02_92, @@ -4191,7 +4487,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_94, OPC_6502_95, OPC_6502_96, - OPC_Illegal, // $97: SMB1 currently unsupported + OPC_65C02_97, OPC_6502_98, OPC_6502_99, OPC_6502_9A, @@ -4199,7 +4495,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65SC02_9C, OPC_6502_9D, OPC_65SC02_9E, - OPC_Illegal, // $9F: BBS1 currently unsupported + OPC_65C02_9F, OPC_6502_A0, OPC_6502_A1, OPC_6502_A2, @@ -4207,7 +4503,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_A4, OPC_6502_A5, OPC_6502_A6, - OPC_Illegal, // $A7: SMB2 currently unsupported + OPC_65C02_A7, OPC_6502_A8, OPC_6502_A9, OPC_6502_AA, @@ -4215,7 +4511,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_AC, OPC_6502_AD, OPC_6502_AE, - OPC_Illegal, // $AF: BBS2 currently unsupported + OPC_65C02_AF, OPC_6502_B0, OPC_6502_B1, OPC_65SC02_B2, @@ -4223,7 +4519,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_B4, OPC_6502_B5, OPC_6502_B6, - OPC_Illegal, // $B7: SMB3 currently unsupported + OPC_65C02_B7, OPC_6502_B8, OPC_6502_B9, OPC_6502_BA, @@ -4231,7 +4527,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_BC, OPC_6502_BD, OPC_6502_BE, - OPC_Illegal, // $BF: BBS3 currently unsupported + OPC_65C02_BF, OPC_6502_C0, OPC_6502_C1, OPC_65C02_NOP22, // $C2 @@ -4239,7 +4535,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_C4, OPC_6502_C5, OPC_6502_C6, - OPC_Illegal, // $C7: SMB4 currently unsupported + OPC_65C02_C7, OPC_6502_C8, OPC_6502_C9, OPC_6502_CA, @@ -4247,7 +4543,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_CC, OPC_6502_CD, OPC_6502_CE, - OPC_Illegal, // $CF: BBS4 currently unsupported + OPC_65C02_CF, OPC_6502_D0, OPC_6502_D1, OPC_65SC02_D2, @@ -4255,7 +4551,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_NOP24, // $D4 OPC_6502_D5, OPC_6502_D6, - OPC_Illegal, // $D7: SMB5 currently unsupported + OPC_65C02_D7, OPC_6502_D8, OPC_6502_D9, OPC_65SC02_DA, @@ -4263,7 +4559,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_NOP34, // $DC OPC_6502_DD, OPC_6502_DE, - OPC_Illegal, // $DF: BBS5 currently unsupported + OPC_65C02_DF, OPC_6502_E0, OPC_65C02_E1, OPC_65C02_NOP22, // $E2 @@ -4271,7 +4567,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_E4, OPC_65C02_E5, OPC_6502_E6, - OPC_Illegal, // $E7: SMB6 currently unsupported + OPC_65C02_E7, OPC_6502_E8, OPC_65C02_E9, OPC_6502_EA, @@ -4279,7 +4575,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_EC, OPC_65C02_ED, OPC_6502_EE, - OPC_Illegal, // $EF: BBS6 currently unsupported + OPC_65C02_EF, OPC_6502_F0, OPC_65C02_F1, OPC_65C02_F2, @@ -4287,7 +4583,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_NOP24, // $F4 OPC_65C02_F5, OPC_6502_F6, - OPC_Illegal, // $F7: SMB7 currently unsupported + OPC_65C02_F7, OPC_6502_F8, OPC_65C02_F9, OPC_65SC02_FA, @@ -4295,7 +4591,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_NOP34, // $FC OPC_65C02_FD, OPC_6502_FE, - OPC_Illegal, // $FF: BBS7 currently unsupported + OPC_65C02_FF }; From fbf3bde97c1e4d33df72d50db9ff8004afcfa83b Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Sun, 22 Dec 2024 19:48:41 +0100 Subject: [PATCH 332/707] sim65: properly implement 5 'illegal' 6502X opcodes. This PR fixes the implementation of 5 illegal opcodes in the 6502, which the 6502X supports: * $93 SHA (zp),y * $9B TAS abs,y * $9C SHY abs,x * $9E SHX abs,x * $9F SHA abs,y The common denominator of the previous implementation was that it didn't correctly handle the case when the Y or X indexing induced a page crossing. In those cases, the effective address calculation of the instructions becomes truly messed up (with the high byte of the address equal to the value being written). The correctness of the implementations in this PR was verified using the 65x02 test suite, and corresponds to a (detailed) reading of the "No More Secrets" document. Stylistically, there is room for improvement in these implementations, specifically in factoring out common behavior into macros. However, for now the "explicit" coding style will suffice. It is clear enough, and we want to reach a situation soon where the sim65 code is able to pass the full '65x02' testsuite. Once we get to that point, we can refactor this code with a lot more confidence, since we will have the benefit of a working exhaustive test to make sure we don't break stuff. --- src/sim65/6502.c | 72 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 5 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index bfb3f3e9b..fe3489d85 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -2534,7 +2534,20 @@ static void OPC_65SC02_92 (void) static void OPC_6502_93 (void) /* Opcode $93: SHA (zp),y */ { - STO_CB (ZPINDY, SHA); + ++Regs.PC; + uint8_t zp_ptr_lo = MemReadByte(Regs.PC); + ++Regs.PC; + uint8_t zp_ptr_hi = zp_ptr_lo + 1; + uint8_t baselo = MemReadByte(zp_ptr_lo); + uint8_t basehi = MemReadByte(zp_ptr_hi); + uint8_t basehi_incremented = basehi + 1; + uint8_t write_value = Regs.AC & Regs.XR & basehi_incremented; + uint8_t write_address_lo = (baselo + Regs.YR); + bool pagecross = (baselo + Regs.YR) > 0xff; + uint8_t write_address_hi = pagecross ? write_value : basehi; + uint16_t write_address = write_address_lo + (write_address_hi << 8); + MemWriteByte(write_address, write_value); + Cycles=6; } @@ -2604,7 +2617,20 @@ static void OPC_6502_9A (void) static void OPC_6502_9B (void) /* Opcode $9B: TAS abs,y */ { - STO_CB (ABSY, TAS); + ++Regs.PC; + uint8_t baselo = MemReadByte(Regs.PC); + ++Regs.PC; + uint8_t basehi = MemReadByte(Regs.PC); + ++Regs.PC; + uint8_t basehi_incremented = basehi + 1; + uint8_t write_value = Regs.AC & Regs.XR & basehi_incremented; + uint8_t write_address_lo = (baselo + Regs.YR); + bool pagecross = (baselo + Regs.YR) > 0xff; + uint8_t write_address_hi = pagecross ? write_value : basehi; + uint16_t write_address = write_address_lo + (write_address_hi << 8); + MemWriteByte(write_address, write_value); + Regs.SP = Regs.AC & Regs.XR; + Cycles=5; } @@ -2612,7 +2638,19 @@ static void OPC_6502_9B (void) static void OPC_6502_9C (void) /* Opcode $9D: SHY abs,x */ { - STO_OP (ABSX, Regs.YR & ((address >> 8) + 1)); + ++Regs.PC; + uint8_t baselo = MemReadByte(Regs.PC); + ++Regs.PC; + uint8_t basehi = MemReadByte(Regs.PC); + ++Regs.PC; + uint8_t basehi_incremented = basehi + 1; + uint8_t write_value = Regs.YR & basehi_incremented; + uint8_t write_address_lo = (baselo + Regs.XR); + bool pagecross = (baselo + Regs.XR) > 0xff; + uint8_t write_address_hi = pagecross ? write_value : basehi; + uint16_t write_address = write_address_lo + (write_address_hi << 8); + MemWriteByte(write_address, write_value); + Cycles=5; } @@ -2636,7 +2674,19 @@ static void OPC_6502_9D (void) static void OPC_6502_9E (void) /* Opcode $9E: SHX abs,x */ { - STO_OP (ABSY, Regs.XR & ((address >> 8) + 1)); + ++Regs.PC; + uint8_t baselo = MemReadByte(Regs.PC); + ++Regs.PC; + uint8_t basehi = MemReadByte(Regs.PC); + ++Regs.PC; + uint8_t basehi_incremented = basehi + 1; + uint8_t write_value = Regs.XR & basehi_incremented; + uint8_t write_address_lo = (baselo + Regs.YR); + bool pagecross = (baselo + Regs.YR) > 0xff; + uint8_t write_address_hi = pagecross ? write_value : basehi; + uint16_t write_address = write_address_lo + (write_address_hi << 8); + MemWriteByte(write_address, write_value); + Cycles=5; } @@ -2644,7 +2694,19 @@ static void OPC_6502_9E (void) static void OPC_6502_9F (void) /* Opcode $9F: SHA abs,y */ { - STO_CB (ABSY, SHA); + ++Regs.PC; + uint8_t baselo = MemReadByte(Regs.PC); + ++Regs.PC; + uint8_t basehi = MemReadByte(Regs.PC); + ++Regs.PC; + uint8_t basehi_incremented = basehi + 1; + uint8_t write_value = Regs.AC & Regs.XR & basehi_incremented; + uint8_t write_address_lo = (baselo + Regs.YR); + bool pagecross = (baselo + Regs.YR) > 0xff; + uint8_t write_address_hi = pagecross ? write_value : basehi; + uint16_t write_address = write_address_lo + (write_address_hi << 8); + MemWriteByte(write_address, write_value); + Cycles=5; } From 7980b81ddbb2c3c5e538395f8d01d8b4c2cf1e39 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Tue, 24 Dec 2024 09:24:02 +0100 Subject: [PATCH 333/707] sim65: Fix instruction timings for 6502 and 65C02. This PR fixes all discrepancies of sim65 instruction timings, for both the 6502 and the 65C02 processors. The timings as implemented in this PR have been verified against actual hardware (Atari 800 XL for 6502; and WDC 65C02 for 65C02). These timings can also be verified against the 65x02 test suite. However, in this case, a single discrepancy arises; the 65x02 testsuite suggests that the 65C02 opcode 0x5c should take 4 clocks. However, tests on a hardware 65C02 have conclusively shown that this instruction takes 8 clock cycles. The 8 clock cycles duration for the 65C02 0xfc opcode is also confirmed by other sources, e.g. Section 9 of http://www.6502.org/tutorials/65c02opcodes.html. This test makes sim65 correct both in terms of functionality (all opcodes now do what they do on hardware) and in terms of timing (all instructions take as long as they would on real hardware). The one discrepancy that remains, is that on a real 6502/65C02, some instructions issue R or W cycles on the bus while the instruction processing is being done. Those spurious bus cycles are not replicated in sim65. Sim65 is thus an instruction-level simulator, rather than a bus-cycle level simulator. In other words, while the clock cycle counts for each instruction are now correct, not all clock cycles are individually simulated. --- src/sim65/6502.c | 98 ++++++++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 41 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index b891bd3e8..6d83ef07b 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -579,6 +579,10 @@ static unsigned HaveIRQRequest; #define STO_CY_ZPINDY 6 #define STO_CY_ZPIND 5 +#define STO_CY_ABSX_NP STO_CY_ABSX +#define STO_CY_ABSY_NP STO_CY_ABSY +#define STO_CY_ZPINDY_NP STO_CY_ZPINDY + /* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y / (zp) */ #define STO_OP(mode, op) \ unsigned address; \ @@ -599,13 +603,11 @@ static unsigned HaveIRQRequest; /* Execution cycles for R-M-W opcodes */ #define RMW_CY_ZP 5 #define RMW_CY_ZPX 6 -#define RMW_CY_ZPY 6 #define RMW_CY_ABS 6 #define RMW_CY_ABSX 7 #define RMW_CY_ABSY 7 -#define RMW_CY_ZPXIND 6 -#define RMW_CY_ZPINDY 5 -#define RMW_CY_ZPIND 5 +#define RMW_CY_ZPXIND 8 +#define RMW_CY_ZPINDY 8 #define RMW_CY_ABSX_NP RMW_CY_ABSX #define RMW_CY_ABSY_NP RMW_CY_ABSY @@ -624,13 +626,16 @@ static unsigned HaveIRQRequest; /* Execution cycles for 2 x R-M-W opcodes */ #define RMW2_CY_ZP 5 #define RMW2_CY_ZPX 6 -#define RMW2_CY_ZPY 6 #define RMW2_CY_ABS 6 #define RMW2_CY_ABSX 7 #define RMW2_CY_ABSY 7 #define RMW2_CY_ZPXIND 8 #define RMW2_CY_ZPINDY 8 +#define RMW2_CY_ZPINDY_NP RMW2_CY_ZPINDY +#define RMW2_CY_ABSY_NP RMW2_CY_ABSY +#define RMW2_CY_ABSX_NP RMW2_CY_ABSX + /* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y */ #define ILLx2_OP(mode, op) \ unsigned address; \ @@ -1365,7 +1370,7 @@ static void OPC_65SC02_12 (void) static void OPC_6502_13 (void) /* Opcode $03: SLO (zp),y */ { - ILLx2_OP (ZPINDY, SLO); + ILLx2_OP (ZPINDY_NP, SLO); } @@ -1456,7 +1461,7 @@ static void OPC_65SC02_1A (void) static void OPC_6502_1B (void) /* Opcode $1B: SLO abs,y */ { - ILLx2_OP (ABSY, SLO); + ILLx2_OP (ABSY_NP, SLO); } @@ -1495,7 +1500,7 @@ static void OPC_6502_1D (void) static void OPC_6502_1E (void) /* Opcode $1E: ASL abs,x */ { - MEM_OP (ABSX, ASL); + MEM_OP (ABSX_NP, ASL); } @@ -1503,7 +1508,8 @@ static void OPC_6502_1E (void) static void OPC_65C02_1E (void) /* Opcode $1E: ASL abs,x */ { - MEM_OP (ABSX_NP, ASL); + MEM_OP (ABSX, ASL); + --Cycles; } @@ -1511,12 +1517,11 @@ static void OPC_65C02_1E (void) static void OPC_6502_1F (void) /* Opcode $1F: SLO abs,x */ { - ILLx2_OP (ABSX, SLO); + ILLx2_OP (ABSX_NP, SLO); } - static void OPC_65C02_1F (void) /* Opcode $1F: BBR1 zp, rel */ { @@ -1719,7 +1724,7 @@ static void OPC_65SC02_32 (void) static void OPC_6502_33 (void) /* Opcode $33: RLA (zp),y */ { - ILLx2_OP (ZPINDY, RLA); + ILLx2_OP (ZPINDY_NP, RLA); } @@ -1795,7 +1800,7 @@ static void OPC_65SC02_3A (void) static void OPC_6502_3B (void) /* Opcode $3B: RLA abs,y */ { - ILLx2_OP (ABSY, RLA); + ILLx2_OP (ABSY_NP, RLA); } @@ -1819,7 +1824,7 @@ static void OPC_6502_3D (void) static void OPC_6502_3E (void) /* Opcode $3E: ROL abs,x */ { - MEM_OP (ABSX, ROL); + MEM_OP (ABSX_NP, ROL); } @@ -1827,15 +1832,16 @@ static void OPC_6502_3E (void) static void OPC_65C02_3E (void) /* Opcode $3E: ROL abs,x */ { - MEM_OP (ABSX_NP, ROL); + MEM_OP (ABSX, ROL); + --Cycles; } static void OPC_6502_3F (void) -/* Opcode $3B: RLA abs,x */ +/* Opcode $3F: RLA abs,x */ { - ILLx2_OP (ABSX, RLA); + ILLx2_OP (ABSX_NP, RLA); } @@ -2015,7 +2021,7 @@ static void OPC_65SC02_52 (void) static void OPC_6502_53 (void) /* Opcode $43: SRE (zp),y */ { - ILLx2_OP (ZPINDY, SRE); + ILLx2_OP (ZPINDY_NP, SRE); } @@ -2083,7 +2089,7 @@ static void OPC_65SC02_5A (void) static void OPC_6502_5B (void) /* Opcode $5B: SRE abs,y */ { - ILLx2_OP (ABSY, SRE); + ILLx2_OP (ABSY_NP, SRE); } @@ -2091,6 +2097,14 @@ static void OPC_6502_5B (void) static void OPC_65C02_5C (void) /* Opcode $5C: 'Absolute' 8 cycle NOP */ { + /* This instruction takes 8 cycles, as per the following sources: + * + * - http://www.6502.org/tutorials/65c02opcodes.html + * - Tests on a WDC 65C02 in hardware. + * + * The 65x02 testsuite however claims that this instruction takes 4 cycles. + * See issue: https://github.com/SingleStepTests/65x02/issues/12 + */ Cycles = 8; Regs.PC += 3; } @@ -2108,7 +2122,7 @@ static void OPC_6502_5D (void) static void OPC_6502_5E (void) /* Opcode $5E: LSR abs,x */ { - MEM_OP (ABSX, LSR); + MEM_OP (ABSX_NP, LSR); } @@ -2116,7 +2130,8 @@ static void OPC_6502_5E (void) static void OPC_65C02_5E (void) /* Opcode $5E: LSR abs,x */ { - MEM_OP (ABSX_NP, LSR); + MEM_OP (ABSX, LSR); + --Cycles; } @@ -2124,7 +2139,7 @@ static void OPC_65C02_5E (void) static void OPC_6502_5F (void) /* Opcode $5F: SRE abs,x */ { - ILLx2_OP (ABSX, SRE); + ILLx2_OP (ABSX_NP, SRE); } @@ -2290,8 +2305,8 @@ static void OPC_6502_6C (void) static void OPC_65C02_6C (void) /* Opcode $6C: JMP (ind) */ { - /* 6502 bug fixed here */ - Cycles = 5; + /* The 6502 bug is fixed on the 65C02, at the cost of an extra cycle. */ + Cycles = 6; Regs.PC = MemReadWord (MemReadWord (Regs.PC+1)); ParaVirtHooks (&Regs); @@ -2374,7 +2389,7 @@ static void OPC_65C02_72 (void) static void OPC_6502_73 (void) /* Opcode $73: RRA (zp),y */ { - ILLx2_OP (ZPINDY, RRA); + ILLx2_OP (ZPINDY_NP, RRA); } @@ -2466,7 +2481,7 @@ static void OPC_65SC02_7A (void) static void OPC_6502_7B (void) /* Opcode $7B: RRA abs,y */ { - ILLx2_OP (ABSY, RRA); + ILLx2_OP (ABSY_NP, RRA); } @@ -2504,7 +2519,7 @@ static void OPC_65C02_7D (void) static void OPC_6502_7E (void) /* Opcode $7E: ROR abs,x */ { - MEM_OP (ABSX, ROR); + MEM_OP (ABSX_NP, ROR); } @@ -2512,7 +2527,8 @@ static void OPC_6502_7E (void) static void OPC_65C02_7E (void) /* Opcode $7E: ROR abs,x */ { - MEM_OP (ABSX_NP, ROR); + MEM_OP (ABSX, ROR); + --Cycles; } @@ -2520,7 +2536,7 @@ static void OPC_65C02_7E (void) static void OPC_6502_7F (void) /* Opcode $7F: RRA abs,x */ { - ILLx2_OP (ABSX, RRA); + ILLx2_OP (ABSX_NP, RRA); } @@ -2702,7 +2718,7 @@ static void OPC_6502_90 (void) static void OPC_6502_91 (void) /* Opcode $91: sta (zp),y */ { - STO_OP (ZPINDY, Regs.AC); + STO_OP (ZPINDY_NP, Regs.AC); } @@ -2791,7 +2807,7 @@ static void OPC_6502_98 (void) static void OPC_6502_99 (void) /* Opcode $99: STA abs,y */ { - STO_OP (ABSY, Regs.AC); + STO_OP (ABSY_NP, Regs.AC); } @@ -2858,7 +2874,7 @@ static void OPC_65SC02_9C (void) static void OPC_6502_9D (void) /* Opcode $9D: STA abs,x */ { - STO_OP (ABSX, Regs.AC); + STO_OP (ABSX_NP, Regs.AC); } @@ -2886,7 +2902,7 @@ static void OPC_6502_9E (void) static void OPC_65SC02_9E (void) /* Opcode $9E: STZ abs,x */ { - STO_OP (ABSX, 0); + STO_OP (ABSX_NP, 0); } @@ -3388,7 +3404,7 @@ static void OPC_65SC02_D2 (void) static void OPC_6502_D3 (void) /* Opcode $D3: DCP (zp),y */ { - MEM_OP (ZPINDY, DCP); + MEM_OP (ZPINDY_NP, DCP); } @@ -3456,7 +3472,7 @@ static void OPC_65SC02_DA (void) static void OPC_6502_DB (void) /* Opcode $DB: DCP abs,y */ { - MEM_OP (ABSY, DCP); + MEM_OP (ABSY_NP, DCP); } @@ -3472,7 +3488,7 @@ static void OPC_6502_DD (void) static void OPC_6502_DE (void) /* Opcode $DE: DEC abs,x */ { - MEM_OP (ABSX, DEC); + MEM_OP (ABSX_NP, DEC); } @@ -3480,7 +3496,7 @@ static void OPC_6502_DE (void) static void OPC_6502_DF (void) /* Opcode $DF: DCP abs,x */ { - MEM_OP (ABSX, DCP); + MEM_OP (ABSX_NP, DCP); } @@ -3735,7 +3751,7 @@ static void OPC_65C02_F2 (void) static void OPC_6502_F3 (void) /* Opcode $F3: ISC (zp),y */ { - MEM_OP (ZPINDY, ISC); + MEM_OP (ZPINDY_NP, ISC); } @@ -3821,7 +3837,7 @@ static void OPC_65SC02_FA (void) static void OPC_6502_FB (void) /* Opcode $FB: ISC abs,y */ { - MEM_OP (ABSY, ISC); + MEM_OP (ABSY_NP, ISC); } @@ -3845,7 +3861,7 @@ static void OPC_65C02_FD (void) static void OPC_6502_FE (void) /* Opcode $FE: INC abs,x */ { - MEM_OP (ABSX, INC); + MEM_OP (ABSX_NP, INC); } @@ -3853,7 +3869,7 @@ static void OPC_6502_FE (void) static void OPC_6502_FF (void) /* Opcode $FF: ISC abs,x */ { - MEM_OP (ABSX, ISC); + MEM_OP (ABSX_NP, ISC); } From e149d1dcf69278a47b9afdbc027cc5a3e2e819a9 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Tue, 24 Dec 2024 11:14:30 +0100 Subject: [PATCH 334/707] Disable the use of clock_gettime(), to see if this fixes the CC65 CI builds. --- src/sim65/peripherals.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 33e206ff3..516a827b0 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -61,6 +61,7 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* A write to the "latch" register performs a simultaneous latch of all registers. */ /* Latch the current wallclock time first. */ +#if 0 struct timespec ts; int result = clock_gettime(CLOCK_REALTIME, &ts); if (result != 0) { @@ -74,6 +75,11 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) * low word is number of nanoseconds since the start of that second. */ Peripherals.Counter.LatchedWallclockTimeSplit = (ts.tv_sec << 32) | ts.tv_nsec; } +#else + /* Temporarily skip call to clock_gettime() to check that we can build for Windows */ + Peripherals.Counter.LatchedWallclockTime = 0xffffffffffffffff; + Peripherals.Counter.LatchedWallclockTimeSplit = 0xffffffffffffffff; +#endif /* Latch the counters that reflect the state of the processor. */ Peripherals.Counter.LatchedClockCycles = Peripherals.Counter.ClockCycles; From d512954fe9ef8299d8982cf8f1dbb37d3f81787d Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Tue, 24 Dec 2024 11:23:05 +0100 Subject: [PATCH 335/707] Added peripherals.c and peripherals.h to sim65.vcxproj --- src/sim65.vcxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 7bc489398..b5b642d02 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -86,6 +86,7 @@ <ClInclude Include="sim65\error.h" /> <ClInclude Include="sim65\memory.h" /> <ClInclude Include="sim65\paravirt.h" /> + <ClInclude Include="sim65\peripherals.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="sim65\6502.c" /> @@ -93,8 +94,9 @@ <ClCompile Include="sim65\main.c" /> <ClCompile Include="sim65\memory.c" /> <ClCompile Include="sim65\paravirt.c" /> + <ClInclude Include="sim65\peripherals.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> \ No newline at end of file +</Project> From 073606b858f9858571f5d02028538c24484733c7 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Tue, 24 Dec 2024 11:30:34 +0100 Subject: [PATCH 336/707] Trying re-ordering of dependencies to get the Windows version to compile. --- src/sim65.vcxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index b5b642d02..46260e052 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -82,19 +82,19 @@ </Link> </ItemDefinitionGroup> <ItemGroup> + <ClInclude Include="sim65\peripherals.h" /> <ClInclude Include="sim65\6502.h" /> <ClInclude Include="sim65\error.h" /> <ClInclude Include="sim65\memory.h" /> <ClInclude Include="sim65\paravirt.h" /> - <ClInclude Include="sim65\peripherals.h" /> </ItemGroup> <ItemGroup> + <ClInclude Include="sim65\peripherals.c" /> <ClCompile Include="sim65\6502.c" /> <ClCompile Include="sim65\error.c" /> <ClCompile Include="sim65\main.c" /> <ClCompile Include="sim65\memory.c" /> <ClCompile Include="sim65\paravirt.c" /> - <ClInclude Include="sim65\peripherals.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> From ca76db1ee4402c3c54ae41146aef0aee4c070f36 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Tue, 24 Dec 2024 11:59:52 +0100 Subject: [PATCH 337/707] peripherals.c now at the back of the dependency list. --- src/sim65.vcxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 46260e052..b5b642d02 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -82,19 +82,19 @@ </Link> </ItemDefinitionGroup> <ItemGroup> - <ClInclude Include="sim65\peripherals.h" /> <ClInclude Include="sim65\6502.h" /> <ClInclude Include="sim65\error.h" /> <ClInclude Include="sim65\memory.h" /> <ClInclude Include="sim65\paravirt.h" /> + <ClInclude Include="sim65\peripherals.h" /> </ItemGroup> <ItemGroup> - <ClInclude Include="sim65\peripherals.c" /> <ClCompile Include="sim65\6502.c" /> <ClCompile Include="sim65\error.c" /> <ClCompile Include="sim65\main.c" /> <ClCompile Include="sim65\memory.c" /> <ClCompile Include="sim65\paravirt.c" /> + <ClInclude Include="sim65\peripherals.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> From 1096023e00b427bbee2cdf5d29990f636c3dc9c3 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Thu, 26 Dec 2024 22:48:42 +0100 Subject: [PATCH 338/707] Update src/sim65.vcxproj Co-authored-by: Matteo Pompili <6500688+matpompili@users.noreply.github.com> --- src/sim65.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index b5b642d02..07a9f7fb5 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -94,7 +94,7 @@ <ClCompile Include="sim65\main.c" /> <ClCompile Include="sim65\memory.c" /> <ClCompile Include="sim65\paravirt.c" /> - <ClInclude Include="sim65\peripherals.c" /> + <ClCompile Include="sim65\peripherals.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> From 9978600d28cc9e408ce0bf939cd8b45c5e1fcf6b Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Thu, 26 Dec 2024 22:55:32 +0100 Subject: [PATCH 339/707] Fixed erroneous ClInclude to ClCompile (thanks Matteo Pompili!) --- src/sim65.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index b5b642d02..07a9f7fb5 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -94,7 +94,7 @@ <ClCompile Include="sim65\main.c" /> <ClCompile Include="sim65\memory.c" /> <ClCompile Include="sim65\paravirt.c" /> - <ClInclude Include="sim65\peripherals.c" /> + <ClCompile Include="sim65\peripherals.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> From 61bedbdd55bcd8ede1b1488cba5cd4bd76e3d77b Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Thu, 26 Dec 2024 22:55:52 +0100 Subject: [PATCH 340/707] Added explicit cast to uint8_t, to make the Cisual Studio compiler happy. --- src/sim65/peripherals.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 516a827b0..d48cf7137 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -137,7 +137,7 @@ uint8_t PeripheralsReadByte (uint8_t Addr) default: Value = 0; /* Reading from a non-existent latch register will yield 0. */ } /* Return the desired byte of the latched counter. 0==LSB, 7==MSB. */ - return Value >> (ByteIndex * 8); + return (uint8_t)(Value >> (ByteIndex * 8)); } /* Handle reads from unused peripheral and write-only addresses. */ From a90640230855b6f33057ae4a3ef7c3537cf9e597 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Thu, 26 Dec 2024 23:15:41 +0100 Subject: [PATCH 341/707] Re-enabling the clock_gettime() code path. --- src/sim65/peripherals.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index d48cf7137..90156aa17 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -61,7 +61,8 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* A write to the "latch" register performs a simultaneous latch of all registers. */ /* Latch the current wallclock time first. */ -#if 0 +#if 1 + /* Enabling clock_gettime dependent codepath (expected to fail at least on Windows build.) */ struct timespec ts; int result = clock_gettime(CLOCK_REALTIME, &ts); if (result != 0) { From 8c40568566a8a27987c6208f34c2bc6644d84793 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Thu, 26 Dec 2024 23:32:00 +0100 Subject: [PATCH 342/707] Made wallclock time fail on Windows (due to lack of clock_gettime), succeed everywhere else. --- src/sim65/peripherals.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 90156aa17..ac11d7b73 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -58,28 +58,30 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* Handle writes to the Counter peripheral. */ case PERIPHERALS_COUNTER_ADDRESS_OFFSET_LATCH: { + /* A write to the "latch" register performs a simultaneous latch of all registers. */ - /* Latch the current wallclock time first. */ -#if 1 - /* Enabling clock_gettime dependent codepath (expected to fail at least on Windows build.) */ + /* Latch the current wallclock time first (if possible). */ + +#if defined(_WIN32) + /* clock_gettime() is not available on Windows. Report max uint64 value for both fields. */ + Peripherals.Counter.LatchedWallclockTime = 0xffffffffffffffff; + Peripherals.Counter.LatchedWallclockTimeSplit = 0xffffffffffffffff; +#else + /* Other targets are presumed to have it. */ struct timespec ts; int result = clock_gettime(CLOCK_REALTIME, &ts); if (result != 0) { - /* Unable to read time. Report max uint64 value for both fields. */ + /* Unable to get time. Report max uint64 value for both fields. */ Peripherals.Counter.LatchedWallclockTime = 0xffffffffffffffff; Peripherals.Counter.LatchedWallclockTimeSplit = 0xffffffffffffffff; } else { /* Wallclock time: number of nanoseconds since 1-1-1970. */ - Peripherals.Counter.LatchedWallclockTime = 1000000000u * ts.tv_sec + ts.tv_nsec; + Peripherals.Counter.LatchedWallclockTime = 1000000000 * (uint64_t)ts.tv_sec + ts.tv_nsec; /* Wallclock time, split: high word is number of seconds since 1-1-1970, * low word is number of nanoseconds since the start of that second. */ - Peripherals.Counter.LatchedWallclockTimeSplit = (ts.tv_sec << 32) | ts.tv_nsec; + Peripherals.Counter.LatchedWallclockTimeSplit = ((uint64_t)ts.tv_sec << 32) | ts.tv_nsec; } -#else - /* Temporarily skip call to clock_gettime() to check that we can build for Windows */ - Peripherals.Counter.LatchedWallclockTime = 0xffffffffffffffff; - Peripherals.Counter.LatchedWallclockTimeSplit = 0xffffffffffffffff; #endif /* Latch the counters that reflect the state of the processor. */ From 1f9e731fc9b16869ff466c77dba7dd7e344b802a Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Thu, 26 Dec 2024 23:48:34 +0100 Subject: [PATCH 343/707] Try if gettimeofday() will work in Windows. --- src/sim65/peripherals.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index ac11d7b73..143f72e76 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -29,6 +29,7 @@ /*****************************************************************************/ +#include <sys/time.h> #include <time.h> #include "peripherals.h" @@ -65,8 +66,19 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) #if defined(_WIN32) /* clock_gettime() is not available on Windows. Report max uint64 value for both fields. */ - Peripherals.Counter.LatchedWallclockTime = 0xffffffffffffffff; - Peripherals.Counter.LatchedWallclockTimeSplit = 0xffffffffffffffff; + struct timeval tv; + int result = gettimeofday(&tv, NULL); + if (result != 0) { + /* Unable to get time. Report max uint64 value for both fields. */ + Peripherals.Counter.LatchedWallclockTime = 0xffffffffffffffff; + Peripherals.Counter.LatchedWallclockTimeSplit = 0xffffffffffffffff; + } else { + /* Wallclock time: number of nanoseconds since 1-1-1970. */ + Peripherals.Counter.LatchedWallclockTime = 1000000000 * (uint64_t)ts.tv_sec + 1000 * ts.tv_usec; + /* Wallclock time, split: high word is number of seconds since 1-1-1970, + * low word is number of nanoseconds since the start of that second. */ + Peripherals.Counter.LatchedWallclockTimeSplit = ((uint64_t)ts.tv_sec << 32) | (1000 * ts.tv_usec); + } #else /* Other targets are presumed to have it. */ struct timespec ts; From ae3106af4aa84994f1021d841b4a52d35734edff Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 00:04:06 +0100 Subject: [PATCH 344/707] Windows version now uses timespec_get() as a substitute for clock_gettime(). --- src/sim65/peripherals.c | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 143f72e76..0ad11a5bf 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -28,8 +28,7 @@ /* */ /*****************************************************************************/ - -#include <sys/time.h> +#include <stdbool.h> #include <time.h> #include "peripherals.h" @@ -64,37 +63,25 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* Latch the current wallclock time first (if possible). */ -#if defined(_WIN32) - /* clock_gettime() is not available on Windows. Report max uint64 value for both fields. */ - struct timeval tv; - int result = gettimeofday(&tv, NULL); - if (result != 0) { - /* Unable to get time. Report max uint64 value for both fields. */ - Peripherals.Counter.LatchedWallclockTime = 0xffffffffffffffff; - Peripherals.Counter.LatchedWallclockTimeSplit = 0xffffffffffffffff; - } else { - /* Wallclock time: number of nanoseconds since 1-1-1970. */ - Peripherals.Counter.LatchedWallclockTime = 1000000000 * (uint64_t)ts.tv_sec + 1000 * ts.tv_usec; - /* Wallclock time, split: high word is number of seconds since 1-1-1970, - * low word is number of nanoseconds since the start of that second. */ - Peripherals.Counter.LatchedWallclockTimeSplit = ((uint64_t)ts.tv_sec << 32) | (1000 * ts.tv_usec); - } -#else - /* Other targets are presumed to have it. */ struct timespec ts; - int result = clock_gettime(CLOCK_REALTIME, &ts); - if (result != 0) { - /* Unable to get time. Report max uint64 value for both fields. */ - Peripherals.Counter.LatchedWallclockTime = 0xffffffffffffffff; - Peripherals.Counter.LatchedWallclockTimeSplit = 0xffffffffffffffff; - } else { + +#if defined(_WIN32) + /* clock_gettime() is not available on Windows. Use timespec_get() instead. */ + bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; +#else + bool time_valid = clock_gettime(CLOCK_REALTIME, &ts) == 0; +#endif + if (time_valid) { /* Wallclock time: number of nanoseconds since 1-1-1970. */ Peripherals.Counter.LatchedWallclockTime = 1000000000 * (uint64_t)ts.tv_sec + ts.tv_nsec; /* Wallclock time, split: high word is number of seconds since 1-1-1970, * low word is number of nanoseconds since the start of that second. */ Peripherals.Counter.LatchedWallclockTimeSplit = ((uint64_t)ts.tv_sec << 32) | ts.tv_nsec; + } else { + /* Unable to get time. Report max uint64 value for both fields. */ + Peripherals.Counter.LatchedWallclockTime = 0xffffffffffffffff; + Peripherals.Counter.LatchedWallclockTimeSplit = 0xffffffffffffffff; } -#endif /* Latch the counters that reflect the state of the processor. */ Peripherals.Counter.LatchedClockCycles = Peripherals.Counter.ClockCycles; From db0b8c2d2c9fcd1544b93822a676da9a0e252b8a Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 00:21:50 +0100 Subject: [PATCH 345/707] Check if we have it working now on the MinGW32 and 64 compilers. --- src/sim65/peripherals.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 0ad11a5bf..81d397c2f 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -65,10 +65,11 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) struct timespec ts; -#if defined(_WIN32) - /* clock_gettime() is not available on Windows. Use timespec_get() instead. */ +#if defined(_MSC_VER) + /* clock_gettime() is not available in the Visual Studio compiler. Use timespec_get() instead. */ bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; #else + /* clock_gettime() is available on Linux, MacOS, MinGW32, and MinGW64. bool time_valid = clock_gettime(CLOCK_REALTIME, &ts) == 0; #endif if (time_valid) { From f3e8f36f00b1f3363386b5033b28d3eba5c69a91 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 00:28:19 +0100 Subject: [PATCH 346/707] Corrected typo. --- src/sim65/peripherals.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 81d397c2f..22c0b8232 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -69,7 +69,7 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* clock_gettime() is not available in the Visual Studio compiler. Use timespec_get() instead. */ bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; #else - /* clock_gettime() is available on Linux, MacOS, MinGW32, and MinGW64. + /* clock_gettime() is available on Linux, MacOS, MinGW32, and MinGW64. */ bool time_valid = clock_gettime(CLOCK_REALTIME, &ts) == 0; #endif if (time_valid) { From 328006e5000a3835e7bc35e1d988d81fff89a9c7 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 00:42:29 +0100 Subject: [PATCH 347/707] Split out cases for MINGW32 and MINGW64 --- src/sim65/peripherals.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 22c0b8232..1606c19b9 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -65,7 +65,11 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) struct timespec ts; -#if defined(_MSC_VER) +#if defined(__MINGW64__) + bool time_valid = false; +#elif defined(__MINGW32__) + bool time_valid = false; +#elif defined(_MSC_VER) /* clock_gettime() is not available in the Visual Studio compiler. Use timespec_get() instead. */ bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; #else From 65d20eaab426f5120c59f1f0c109daaeca250920 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 00:55:13 +0100 Subject: [PATCH 348/707] Enable timespec_get in MINGW64 code path to see if that works. --- src/sim65/peripherals.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 1606c19b9..c7b465872 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -61,19 +61,25 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* A write to the "latch" register performs a simultaneous latch of all registers. */ - /* Latch the current wallclock time first (if possible). */ + /* Latch the current wallclock time before doing anything else. */ - struct timespec ts; + struct timespec ts; /* Available on all compilers we use. */ #if defined(__MINGW64__) + /* We check for MINGW64 before MINGW32, since MINGW64 also defines __MINGW32__. */ + /* does timespec_get work? */ + bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; + /* does clock_gettime work? */ bool time_valid = false; #elif defined(__MINGW32__) + /* does timespec_get work? */ + /* does clock_gettime work? */ bool time_valid = false; #elif defined(_MSC_VER) - /* clock_gettime() is not available in the Visual Studio compiler. Use timespec_get() instead. */ + /* clock_gettime() is not available when using the Microsoft compiler. Use timespec_get() instead. */ bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; #else - /* clock_gettime() is available on Linux, MacOS, MinGW32, and MinGW64. */ + /* clock_gettime() is available on Linux and MacOS. */ bool time_valid = clock_gettime(CLOCK_REALTIME, &ts) == 0; #endif if (time_valid) { From 74f12b449888de87396e2f456ce68cca7edca296 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 01:12:04 +0100 Subject: [PATCH 349/707] Enable timespec_get in MINGW64 code path to see if that works (2). --- src/sim65/peripherals.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index c7b465872..7d0df91bc 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -67,10 +67,10 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) #if defined(__MINGW64__) /* We check for MINGW64 before MINGW32, since MINGW64 also defines __MINGW32__. */ - /* does timespec_get work? */ + /* Using timespec_get() in the MinGW64 compiler makes the Linux workflow build fail. */ bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; /* does clock_gettime work? */ - bool time_valid = false; + //bool time_valid = false; #elif defined(__MINGW32__) /* does timespec_get work? */ /* does clock_gettime work? */ From 2743644b02fb106beeafcb3bc8cb4ccda1cf75b8 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 01:24:44 +0100 Subject: [PATCH 350/707] Enable timespec_get in MINGW64 code path to see if that works (3). --- src/sim65/peripherals.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 7d0df91bc..c5c42b87e 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -68,13 +68,14 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) #if defined(__MINGW64__) /* We check for MINGW64 before MINGW32, since MINGW64 also defines __MINGW32__. */ /* Using timespec_get() in the MinGW64 compiler makes the Linux workflow build fail. */ - bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; + //bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; /* does clock_gettime work? */ - //bool time_valid = false; + bool time_valid = false; #elif defined(__MINGW32__) /* does timespec_get work? */ /* does clock_gettime work? */ - bool time_valid = false; + //bool time_valid = false; + bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; #elif defined(_MSC_VER) /* clock_gettime() is not available when using the Microsoft compiler. Use timespec_get() instead. */ bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; From a94b389965d0c0392aa0f22a6717b6fad2f2e6e3 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 01:39:18 +0100 Subject: [PATCH 351/707] Enable timespec_get in MINGW64 code path to see if that works (4). --- src/sim65/peripherals.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index c5c42b87e..1c62b2bfb 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -70,12 +70,13 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* Using timespec_get() in the MinGW64 compiler makes the Linux workflow build fail. */ //bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; /* does clock_gettime work? */ - bool time_valid = false; -#elif defined(__MINGW32__) - /* does timespec_get work? */ - /* does clock_gettime work? */ + bool time_valid = clock_gettime(CLOCK_REALTIME, &ts) == 0; //bool time_valid = false; - bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; +#elif defined(__MINGW32__) + /* does timespec_get work? -- yes! */ + /* does clock_gettime work? */ + bool time_valid = false; + //bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; #elif defined(_MSC_VER) /* clock_gettime() is not available when using the Microsoft compiler. Use timespec_get() instead. */ bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; From 083c968885cad634df04a7f4b739241cc6078995 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 01:53:16 +0100 Subject: [PATCH 352/707] Enable timespec_get in MINGW64 code path to see if that works (5). --- src/sim65/peripherals.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 1c62b2bfb..ea402ccb6 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -68,14 +68,13 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) #if defined(__MINGW64__) /* We check for MINGW64 before MINGW32, since MINGW64 also defines __MINGW32__. */ /* Using timespec_get() in the MinGW64 compiler makes the Linux workflow build fail. */ - //bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; - /* does clock_gettime work? */ - bool time_valid = clock_gettime(CLOCK_REALTIME, &ts) == 0; - //bool time_valid = false; + /* Using clock_gettime() in the MinGW64 compiler makes the Linux workflow build fail. */ + bool time_valid = false; #elif defined(__MINGW32__) /* does timespec_get work? -- yes! */ /* does clock_gettime work? */ - bool time_valid = false; + //bool time_valid = false; + bool time_valid = clock_gettime(CLOCK_REALTIME, &ts) == 0; //bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; #elif defined(_MSC_VER) /* clock_gettime() is not available when using the Microsoft compiler. Use timespec_get() instead. */ From 6ccde66c863c0cad8593c0344567c95e55285219 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 02:06:15 +0100 Subject: [PATCH 353/707] Enable timespec_get in MINGW64 code path to see if that works (6). --- src/sim65/peripherals.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index ea402ccb6..20393cc1d 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -72,9 +72,10 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) bool time_valid = false; #elif defined(__MINGW32__) /* does timespec_get work? -- yes! */ - /* does clock_gettime work? */ + /* does clock_gettime work? -- yes! */ //bool time_valid = false; - bool time_valid = clock_gettime(CLOCK_REALTIME, &ts) == 0; + //bool time_valid = clock_gettime(CLOCK_REALTIME, &ts) == 0; + #error "MinGW32 compiler was used; we're not handling it." //bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; #elif defined(_MSC_VER) /* clock_gettime() is not available when using the Microsoft compiler. Use timespec_get() instead. */ From c735a83a98bd8577539e8ec4c57be174f953ec00 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 02:19:36 +0100 Subject: [PATCH 354/707] Enable timespec_get in MINGW64 code path to see if that works (7). --- src/sim65/peripherals.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 20393cc1d..012af3d30 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -32,6 +32,10 @@ #include <time.h> #include "peripherals.h" +#if defined(__MINGW64__) +/* For gettimeofday() */ +#include <sys/time.h> +#endif /*****************************************************************************/ /* Data */ @@ -66,17 +70,18 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) struct timespec ts; /* Available on all compilers we use. */ #if defined(__MINGW64__) - /* We check for MINGW64 before MINGW32, since MINGW64 also defines __MINGW32__. */ + /* Note: we check for MINGW64 before MINGW32, since MINGW64 also defines __MINGW32__. */ /* Using timespec_get() in the MinGW64 compiler makes the Linux workflow build fail. */ /* Using clock_gettime() in the MinGW64 compiler makes the Linux workflow build fail. */ - bool time_valid = false; + struct timeval tv; + bool time_valid = (gettimeofday(&tv, NULL) == 0); + if (time_valid) + { + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; + } #elif defined(__MINGW32__) - /* does timespec_get work? -- yes! */ - /* does clock_gettime work? -- yes! */ - //bool time_valid = false; - //bool time_valid = clock_gettime(CLOCK_REALTIME, &ts) == 0; - #error "MinGW32 compiler was used; we're not handling it." - //bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; + #error "MinGW32 compiler detected, but we're not handling it." #elif defined(_MSC_VER) /* clock_gettime() is not available when using the Microsoft compiler. Use timespec_get() instead. */ bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; From 58b8c147386093026bd7130401937d17150437e1 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 08:57:58 +0100 Subject: [PATCH 355/707] Split off the compiler-depended wallclock time function in a separate function. --- src/sim65/peripherals.c | 61 +++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 012af3d30..e155ba04c 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -52,6 +52,44 @@ Sim65Peripherals Peripherals; /* Code */ /*****************************************************************************/ +static bool GetWallclockTime (struct timespec * ts) +{ + /* Note: the 'struct timespec' type is supported on all compilers we want to support. */ + +#if defined(__MINGW64__) + /* This check comes before the check on symbol __MINGW32__, as MinGW64 defines both. + * + * When using the MinGW64 compiler, neither timespec_get() nor clock_gettime() + * are available; this makes the Linux workflow build fail. + * The gettimeofday() function works, so use that. + */ + struct timeval tv; + bool time_valid = (gettimeofday(&tv, NULL) == 0); + if (time_valid) + { + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; + } +#elif defined(__MINGW32__) + /* The MinGW32 compiler is not used in the build process. + * Support can be added when the need arises. + */ +#error "The MinGW32 compiler is not supported." +#elif defined(_MSC_VER) + /* Using the Microsoft C++ compiler. + * clock_gettime() is not available; use timespec_get() instead. + */ + bool time_valid = timespec_get(ts, TIME_UTC) == TIME_UTC; +#else + /* Other platforms (Linux, MacOS, ...): assume that clock_gettime() + * is available. + */ + bool time_valid = clock_gettime(CLOCK_REALTIME, ts) == 0; +#endif + + return time_valid; +} + void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) @@ -67,28 +105,9 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* Latch the current wallclock time before doing anything else. */ - struct timespec ts; /* Available on all compilers we use. */ + struct timespec ts; /* The type is available on all compilers we use. */ + bool time_valid = GetWallclockTime (&ts); -#if defined(__MINGW64__) - /* Note: we check for MINGW64 before MINGW32, since MINGW64 also defines __MINGW32__. */ - /* Using timespec_get() in the MinGW64 compiler makes the Linux workflow build fail. */ - /* Using clock_gettime() in the MinGW64 compiler makes the Linux workflow build fail. */ - struct timeval tv; - bool time_valid = (gettimeofday(&tv, NULL) == 0); - if (time_valid) - { - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; - } -#elif defined(__MINGW32__) - #error "MinGW32 compiler detected, but we're not handling it." -#elif defined(_MSC_VER) - /* clock_gettime() is not available when using the Microsoft compiler. Use timespec_get() instead. */ - bool time_valid = timespec_get(&ts, TIME_UTC) == TIME_UTC; -#else - /* clock_gettime() is available on Linux and MacOS. */ - bool time_valid = clock_gettime(CLOCK_REALTIME, &ts) == 0; -#endif if (time_valid) { /* Wallclock time: number of nanoseconds since 1-1-1970. */ Peripherals.Counter.LatchedWallclockTime = 1000000000 * (uint64_t)ts.tv_sec + ts.tv_nsec; From e785b88d425cd4ad741d9b7f018a4a9615625ef8 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 27 Dec 2024 09:21:04 +0100 Subject: [PATCH 356/707] Cleaning up the GetWallclockTime function. --- src/sim65/peripherals.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index e155ba04c..bd00c5b3a 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -53,38 +53,34 @@ Sim65Peripherals Peripherals; /*****************************************************************************/ static bool GetWallclockTime (struct timespec * ts) +/* Get the wallclock time with nanosecond resolution. */ { - /* Note: the 'struct timespec' type is supported on all compilers we want to support. */ + /* Note: the 'struct timespec' type is available on all compilers we want to support. */ + + bool time_valid; #if defined(__MINGW64__) - /* This check comes before the check on symbol __MINGW32__, as MinGW64 defines both. - * - * When using the MinGW64 compiler, neither timespec_get() nor clock_gettime() - * are available; this makes the Linux workflow build fail. - * The gettimeofday() function works, so use that. + /* When using the MinGW64 compiler, neither timespec_get() nor clock_gettime() + * are available; using either of them makes the Linux workflow build fail. + * The gettimeofday() function does work, so use that; its microsecond resulution + * is plenty for most applications. */ struct timeval tv; - bool time_valid = (gettimeofday(&tv, NULL) == 0); + time_valid = (gettimeofday(&tv, NULL) == 0); if (time_valid) { ts->tv_sec = tv.tv_sec; ts->tv_nsec = tv.tv_usec * 1000; } -#elif defined(__MINGW32__) - /* The MinGW32 compiler is not used in the build process. - * Support can be added when the need arises. - */ -#error "The MinGW32 compiler is not supported." #elif defined(_MSC_VER) /* Using the Microsoft C++ compiler. * clock_gettime() is not available; use timespec_get() instead. */ - bool time_valid = timespec_get(ts, TIME_UTC) == TIME_UTC; + time_valid = timespec_get(ts, TIME_UTC) == TIME_UTC; #else - /* Other platforms (Linux, MacOS, ...): assume that clock_gettime() - * is available. + /* On all other compilers, assume that the clock_gettime() function is available. */ - bool time_valid = clock_gettime(CLOCK_REALTIME, ts) == 0; + time_valid = clock_gettime(CLOCK_REALTIME, ts) == 0; #endif return time_valid; From 29063021a815a05dca3a0cff9ea057504aae217b Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Sat, 28 Dec 2024 06:49:23 +0100 Subject: [PATCH 357/707] Cosmetic improvements. --- src/sim65/peripherals.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index bd00c5b3a..713b8173c 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -2,7 +2,7 @@ /* */ /* peripherals.c */ /* */ -/* Memory-mapped peripheral subsystem for the 6502 simulator */ +/* Memory-mapped peripheral subsystem for the 6502 simulator */ /* */ /* */ /* */ @@ -30,13 +30,15 @@ #include <stdbool.h> #include <time.h> -#include "peripherals.h" - #if defined(__MINGW64__) /* For gettimeofday() */ #include <sys/time.h> #endif + +#include "peripherals.h" + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -62,13 +64,12 @@ static bool GetWallclockTime (struct timespec * ts) #if defined(__MINGW64__) /* When using the MinGW64 compiler, neither timespec_get() nor clock_gettime() * are available; using either of them makes the Linux workflow build fail. - * The gettimeofday() function does work, so use that; its microsecond resulution - * is plenty for most applications. + * The gettimeofday() function does work, so use that; its microsecond resolution + * is fine for most applications. */ struct timeval tv; time_valid = (gettimeofday(&tv, NULL) == 0); - if (time_valid) - { + if (time_valid) { ts->tv_sec = tv.tv_sec; ts->tv_nsec = tv.tv_usec * 1000; } @@ -78,7 +79,8 @@ static bool GetWallclockTime (struct timespec * ts) */ time_valid = timespec_get(ts, TIME_UTC) == TIME_UTC; #else - /* On all other compilers, assume that the clock_gettime() function is available. + /* On all other compilers, assume that clock_gettime() is available. + * This is true on Linux and MacOS, at least. */ time_valid = clock_gettime(CLOCK_REALTIME, ts) == 0; #endif @@ -101,7 +103,7 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) /* Latch the current wallclock time before doing anything else. */ - struct timespec ts; /* The type is available on all compilers we use. */ + struct timespec ts; bool time_valid = GetWallclockTime (&ts); if (time_valid) { @@ -109,11 +111,11 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) Peripherals.Counter.LatchedWallclockTime = 1000000000 * (uint64_t)ts.tv_sec + ts.tv_nsec; /* Wallclock time, split: high word is number of seconds since 1-1-1970, * low word is number of nanoseconds since the start of that second. */ - Peripherals.Counter.LatchedWallclockTimeSplit = ((uint64_t)ts.tv_sec << 32) | ts.tv_nsec; + Peripherals.Counter.LatchedWallclockTimeSplit = (uint64_t)ts.tv_sec << 32 | ts.tv_nsec; } else { /* Unable to get time. Report max uint64 value for both fields. */ - Peripherals.Counter.LatchedWallclockTime = 0xffffffffffffffff; - Peripherals.Counter.LatchedWallclockTimeSplit = 0xffffffffffffffff; + Peripherals.Counter.LatchedWallclockTime = -1; + Peripherals.Counter.LatchedWallclockTimeSplit = -1; } /* Latch the counters that reflect the state of the processor. */ @@ -160,8 +162,9 @@ uint8_t PeripheralsReadByte (uint8_t Addr) /* Read from any of the eight counter bytes. * The first byte is the 64 bit value's LSB, the seventh byte is its MSB. */ - unsigned ByteIndex = Addr - PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE; /* 0 .. 7 */ + unsigned SelectedByteIndex = Addr - PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE; /* 0 .. 7 */ uint64_t Value; + uint8_t SelectedByteValue; switch (Peripherals.Counter.LatchedValueSelected) { case PERIPHERALS_COUNTER_SELECT_CLOCKCYCLE_COUNTER: Value = Peripherals.Counter.LatchedClockCycles; break; case PERIPHERALS_COUNTER_SELECT_INSTRUCTION_COUNTER: Value = Peripherals.Counter.LatchedCpuInstructions; break; @@ -172,7 +175,8 @@ uint8_t PeripheralsReadByte (uint8_t Addr) default: Value = 0; /* Reading from a non-existent latch register will yield 0. */ } /* Return the desired byte of the latched counter. 0==LSB, 7==MSB. */ - return (uint8_t)(Value >> (ByteIndex * 8)); + SelectedByteValue = Value >> (SelectedByteIndex * 8); + return SelectedByteValue; } /* Handle reads from unused peripheral and write-only addresses. */ From 7576f59e6aa67e5993c737da966267b27493e45e Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Sat, 28 Dec 2024 06:57:37 +0100 Subject: [PATCH 358/707] Visual Studio compiler demands an explicit cast from uint64_t to uint8_t. --- src/sim65/peripherals.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 713b8173c..4fa512ed8 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -164,7 +164,6 @@ uint8_t PeripheralsReadByte (uint8_t Addr) */ unsigned SelectedByteIndex = Addr - PERIPHERALS_COUNTER_ADDRESS_OFFSET_VALUE; /* 0 .. 7 */ uint64_t Value; - uint8_t SelectedByteValue; switch (Peripherals.Counter.LatchedValueSelected) { case PERIPHERALS_COUNTER_SELECT_CLOCKCYCLE_COUNTER: Value = Peripherals.Counter.LatchedClockCycles; break; case PERIPHERALS_COUNTER_SELECT_INSTRUCTION_COUNTER: Value = Peripherals.Counter.LatchedCpuInstructions; break; @@ -174,9 +173,8 @@ uint8_t PeripheralsReadByte (uint8_t Addr) case PERIPHERALS_COUNTER_SELECT_WALLCLOCK_TIME_SPLIT: Value = Peripherals.Counter.LatchedWallclockTimeSplit; break; default: Value = 0; /* Reading from a non-existent latch register will yield 0. */ } - /* Return the desired byte of the latched counter. 0==LSB, 7==MSB. */ - SelectedByteValue = Value >> (SelectedByteIndex * 8); - return SelectedByteValue; + /* Return the desired byte of the latched counter; 0==LSB, 7==MSB. */ + return (uint8_t)(Value >> (SelectedByteIndex * 8)); } /* Handle reads from unused peripheral and write-only addresses. */ From 511f4478deec1de16825b0d072e872e823162f23 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Sun, 29 Dec 2024 22:26:38 +0100 Subject: [PATCH 359/707] Fixed style issues. --- src/sim65/6502.c | 584 ++++++++++++++++++++++++----------------------- 1 file changed, 293 insertions(+), 291 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index 6d83ef07b..079a2343a 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -11,9 +11,13 @@ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ -/* Mar-2017, Christian Krueger, added support for 65SC02 */ +/* Mar-2017, Christian Krueger, added support for 65SC02. */ /* Dec-2023, Carlo Bramini, rewritten for better maintenance and added */ -/* support for undocumented opcodes for 6502 */ +/* support for undocumented opcodes for 6502. */ +/* Dec-2024, Sidney Cadot, fixed 65C02 ADC/SBC (decimal mode); implemented */ +/* 65C02 missing instructions; fixed 6502X illegal instructions; */ +/* fixed cycle count for all 6502(X) / 65C02 opcodes; */ +/* achieved full 65x02 test-suite compliance. */ /* */ /* This software is provided 'as-is', without any expressed or implied */ /* warranty. In no event will the authors be held liable for any damages */ @@ -358,7 +362,7 @@ ANC #imm | 2Bh | 2 | -------------+--------+--------+ -* LAS: calculates the contents of a memory location with the contents of the +* LAS: calculates the AND of a memory location with the contents of the stack pointer register and it stores the result in the accumulator, the X register, and the stack pointer. @@ -375,7 +379,6 @@ Address mode | opcode | cycles | N V B D I Z C SBC #imm | EBh | 2 | -------------+--------+--------+ - */ /*****************************************************************************/ @@ -397,10 +400,11 @@ CPURegs Regs; static unsigned Cycles; /* NMI request active */ -static unsigned HaveNMIRequest; +static bool HaveNMIRequest; /* IRQ request active */ -static unsigned HaveIRQRequest; +static bool HaveIRQRequest; + /*****************************************************************************/ @@ -432,7 +436,6 @@ static unsigned HaveIRQRequest; */ #define TEST_ZF(v) SET_ZF (((v) & 0xFF) == 0) #define TEST_SF(v) SET_SF (((v) & 0x80) != 0) -#define TEST_CF(v) SET_CF (((v) & 0xFF00) != 0) /* Program counter halves */ #define PCL (Regs.PC & 0xFF) @@ -554,7 +557,7 @@ static unsigned HaveIRQRequest; /* #imm */ #define ALU_OP_IMM(op) \ - unsigned char immediate; \ + uint8_t immediate; \ MEM_AD_OP_IMM(immediate); \ Cycles = 2; \ op (immediate) @@ -590,14 +593,6 @@ static unsigned HaveIRQRequest; ADR_##mode (address); \ MemWriteByte(address, op) -/* zp / zp,x / zp,y / abs / abs,x / abs,y / (zp,x) / (zp),y / (zp) */ -#define STO_CB(mode, cb) \ - unsigned address, operand; \ - Cycles = STO_CY_##mode; \ - ADR_##mode (address); \ - cb (operand); \ - MemWriteByte(address, operand) - /* Read-Modify-Write opcode helpers */ /* Execution cycles for R-M-W opcodes */ @@ -673,7 +668,7 @@ static unsigned HaveIRQRequest; const uint8_t op = v; \ const uint8_t OldAC = Regs.AC; \ bool carry = GET_CF(); \ - Regs.AC = (OldAC + op + carry); \ + Regs.AC = OldAC + op + carry; \ const bool NV = Regs.AC >= 0x80; \ carry = OldAC + op + carry >= 0x100; \ SET_SF(NV); \ @@ -740,7 +735,7 @@ static unsigned HaveIRQRequest; } while (0) /* ADC, 65C02 version */ -#define ADC_65C02(v) \ +#define ADC_65C02(v) \ do { \ if (GET_DF()) { \ ADC_DECIMAL_MODE_65C02(v); \ @@ -751,21 +746,23 @@ static unsigned HaveIRQRequest; /* branches */ #define BRANCH(cond) \ - Cycles = 2; \ - if (cond) { \ - signed char Offs; \ - unsigned char OldPCH; \ - ++Cycles; \ - Offs = (signed char) MemReadByte (Regs.PC+1); \ - Regs.PC += 2; \ - OldPCH = PCH; \ - Regs.PC = (Regs.PC + (int) Offs) & 0xFFFF; \ - if (PCH != OldPCH) { \ + do { \ + Cycles = 2; \ + if (cond) { \ + int8_t Offs; \ + uint8_t OldPCH; \ ++Cycles; \ + Offs = MemReadByte (Regs.PC+1); \ + Regs.PC += 2; \ + OldPCH = PCH; \ + Regs.PC = (Regs.PC + (int) Offs) & 0xFFFF; \ + if (PCH != OldPCH) { \ + ++Cycles; \ + } \ + } else { \ + Regs.PC += 2; \ } \ - } else { \ - Regs.PC += 2; \ - } + } while (0) /* compares */ #define COMPARE(v1, v2) \ @@ -788,7 +785,7 @@ static unsigned HaveIRQRequest; /* ROL */ #define ROL(Val) \ do { \ - unsigned ShiftOut = (Val & 0x80); \ + const bool ShiftOut = (Val & 0x80) != 0; \ Val <<= 1; \ if (GET_CF ()) { \ Val |= 0x01; \ @@ -801,7 +798,7 @@ static unsigned HaveIRQRequest; /* ROR */ #define ROR(Val) \ do { \ - unsigned ShiftOut = (Val & 0x01); \ + const bool ShiftOut = (Val & 0x01) != 0; \ Val >>= 1; \ if (GET_CF ()) { \ Val |= 0x80; \ @@ -809,7 +806,7 @@ static unsigned HaveIRQRequest; TEST_ZF (Val); \ TEST_SF (Val); \ SET_CF (ShiftOut); \ - } while(0) + } while (0) /* ASL */ #define ASL(Val) \ @@ -967,7 +964,7 @@ static unsigned HaveIRQRequest; SET_OF ((Val & 0x40) ^ ((Val & 0x20) << 1)); \ } \ Regs.AC = Val; \ - } while (0); + } while (0) /* ANE */ /* An "unstable" illegal opcode that depends on a "constant" value that isn't @@ -999,7 +996,7 @@ static unsigned HaveIRQRequest; Regs.XR = tmp; \ TEST_SF (tmp); \ TEST_ZF (tmp); \ - } while (0); + } while (0) /* NOP */ #define NOP(Val) \ @@ -1039,7 +1036,7 @@ static unsigned HaveIRQRequest; const uint8_t op = v; \ const uint8_t OldAC = Regs.AC; \ const bool borrow = !GET_CF(); \ - Regs.AC = (OldAC - op - borrow); \ + Regs.AC = OldAC - op - borrow; \ const bool NV = Regs.AC >= 0x80; \ SET_SF(NV); \ SET_OF(((OldAC >= 0x80) ^ NV) & ((op < 0x80) ^ NV)); \ @@ -1121,7 +1118,7 @@ static unsigned HaveIRQRequest; */ #define ZP_BITOP(bitnr, bitval) \ do { \ - uint8_t zp_address = MemReadByte (Regs.PC + 1); \ + const uint8_t zp_address = MemReadByte (Regs.PC + 1); \ uint8_t zp_value = MemReadByte (zp_address); \ if (bitval) { \ zp_value |= (1 << bitnr); \ @@ -1139,9 +1136,9 @@ static unsigned HaveIRQRequest; */ #define ZP_BIT_BRANCH(bitnr, bitval) \ do { \ - uint8_t zp_address = MemReadByte (Regs.PC + 1); \ - uint8_t zp_value = MemReadByte (zp_address); \ - int displacement = (int8_t)MemReadByte (Regs.PC + 2); \ + const uint8_t zp_address = MemReadByte (Regs.PC + 1); \ + const uint8_t zp_value = MemReadByte (zp_address); \ + const int8_t displacement = MemReadByte (Regs.PC + 2); \ if (((zp_value & (1 << bitnr)) != 0) == bitval) { \ Regs.PC += 3; \ uint8_t OldPCH = PCH; \ @@ -1196,7 +1193,7 @@ static void OPC_6502_01 (void) -static void OPC_6502_03 (void) +static void OPC_6502X_03 (void) /* Opcode $03: SLO (zp,x) */ { ILLx2_OP (ZPXIND, SLO); @@ -1205,10 +1202,10 @@ static void OPC_6502_03 (void) /* Aliases of opcode $04 */ -#define OPC_6502_44 OPC_6502_04 -#define OPC_6502_64 OPC_6502_04 +#define OPC_6502X_44 OPC_6502X_04 +#define OPC_6502X_64 OPC_6502X_04 -static void OPC_6502_04 (void) +static void OPC_6502X_04 (void) /* Opcode $04: NOP zp */ { ALU_OP (ZP, NOP); @@ -1216,7 +1213,7 @@ static void OPC_6502_04 (void) -static void OPC_65SC02_04 (void) +static void OPC_65C02_04 (void) /* Opcode $04: TSB zp */ { MEM_OP (ZP, TSB); @@ -1240,7 +1237,7 @@ static void OPC_6502_06 (void) -static void OPC_6502_07 (void) +static void OPC_6502X_07 (void) /* Opcode $07: SLO zp */ { ILLx2_OP (ZP, SLO); @@ -1285,9 +1282,9 @@ static void OPC_6502_0A (void) /* Aliases of opcode $0B */ -#define OPC_6502_2B OPC_6502_0B +#define OPC_6502X_2B OPC_6502X_0B -static void OPC_6502_0B (void) +static void OPC_6502X_0B (void) /* Opcode $0B: ANC #imm */ { ALU_OP_IMM (ANC); @@ -1295,7 +1292,7 @@ static void OPC_6502_0B (void) -static void OPC_6502_0C (void) +static void OPC_6502X_0C (void) /* Opcode $0C: NOP abs */ { ALU_OP (ABS, NOP); @@ -1303,7 +1300,7 @@ static void OPC_6502_0C (void) -static void OPC_65SC02_0C (void) +static void OPC_65C02_0C (void) /* Opcode $0C: TSB abs */ { MEM_OP (ABS, TSB); @@ -1327,7 +1324,7 @@ static void OPC_6502_0E (void) -static void OPC_6502_0F (void) +static void OPC_6502X_0F (void) /* Opcode $0F: SLO abs */ { ILLx2_OP (ABS, SLO); @@ -1359,7 +1356,7 @@ static void OPC_6502_11 (void) -static void OPC_65SC02_12 (void) +static void OPC_65C02_12 (void) /* Opcode $12: ORA (zp) */ { AC_OP (ZPIND, |); @@ -1367,7 +1364,7 @@ static void OPC_65SC02_12 (void) -static void OPC_6502_13 (void) +static void OPC_6502X_13 (void) /* Opcode $03: SLO (zp),y */ { ILLx2_OP (ZPINDY_NP, SLO); @@ -1376,13 +1373,13 @@ static void OPC_6502_13 (void) /* Aliases of opcode $14 */ -#define OPC_6502_34 OPC_6502_14 -#define OPC_6502_54 OPC_6502_14 -#define OPC_6502_74 OPC_6502_14 -#define OPC_6502_D4 OPC_6502_14 -#define OPC_6502_F4 OPC_6502_14 +#define OPC_6502X_34 OPC_6502X_14 +#define OPC_6502X_54 OPC_6502X_14 +#define OPC_6502X_74 OPC_6502X_14 +#define OPC_6502X_D4 OPC_6502X_14 +#define OPC_6502X_F4 OPC_6502X_14 -static void OPC_6502_14 (void) +static void OPC_6502X_14 (void) /* Opcode $04: NOP zp,x */ { ALU_OP (ZPX, NOP); @@ -1390,7 +1387,7 @@ static void OPC_6502_14 (void) -static void OPC_65SC02_14 (void) +static void OPC_65C02_14 (void) /* Opcode $14: TRB zp */ { MEM_OP (ZP, TRB); @@ -1414,7 +1411,7 @@ static void OPC_6502_16 (void) -static void OPC_6502_17 (void) +static void OPC_6502X_17 (void) /* Opcode $17: SLO zp,x */ { ILLx2_OP (ZPX, SLO); @@ -1448,7 +1445,7 @@ static void OPC_6502_19 (void) -static void OPC_65SC02_1A (void) +static void OPC_65C02_1A (void) /* Opcode $1A: INC a */ { Cycles = 2; @@ -1458,7 +1455,7 @@ static void OPC_65SC02_1A (void) -static void OPC_6502_1B (void) +static void OPC_6502X_1B (void) /* Opcode $1B: SLO abs,y */ { ILLx2_OP (ABSY_NP, SLO); @@ -1467,13 +1464,13 @@ static void OPC_6502_1B (void) /* Aliases of opcode $1C */ -#define OPC_6502_3C OPC_6502_1C -#define OPC_6502_5C OPC_6502_1C -#define OPC_6502_7C OPC_6502_1C -#define OPC_6502_DC OPC_6502_1C -#define OPC_6502_FC OPC_6502_1C +#define OPC_6502X_3C OPC_6502X_1C +#define OPC_6502X_5C OPC_6502X_1C +#define OPC_6502X_7C OPC_6502X_1C +#define OPC_6502X_DC OPC_6502X_1C +#define OPC_6502X_FC OPC_6502X_1C -static void OPC_6502_1C (void) +static void OPC_6502X_1C (void) /* Opcode $1C: NOP abs,x */ { ALU_OP (ABSX, NOP); @@ -1481,7 +1478,7 @@ static void OPC_6502_1C (void) -static void OPC_65SC02_1C (void) +static void OPC_65C02_1C (void) /* Opcode $1C: TRB abs */ { MEM_OP (ABS, TRB); @@ -1514,7 +1511,7 @@ static void OPC_65C02_1E (void) -static void OPC_6502_1F (void) +static void OPC_6502X_1F (void) /* Opcode $1F: SLO abs,x */ { ILLx2_OP (ABSX_NP, SLO); @@ -1553,15 +1550,13 @@ static void OPC_6502_20 (void) * the order of the bus operations on a real 6502. */ - unsigned AddrLo, AddrHi; - Cycles = 6; Regs.PC += 1; - AddrLo = MemReadByte(Regs.PC); + uint8_t AddrLo = MemReadByte(Regs.PC); Regs.PC += 1; PUSH (PCH); PUSH (PCL); - AddrHi = MemReadByte(Regs.PC); + uint8_t AddrHi = MemReadByte(Regs.PC); Regs.PC = AddrLo + (AddrHi << 8); @@ -1578,7 +1573,7 @@ static void OPC_6502_21 (void) -static void OPC_6502_23 (void) +static void OPC_6502X_23 (void) /* Opcode $23: RLA (zp,x) */ { ILLx2_OP (ZPXIND, RLA); @@ -1610,7 +1605,7 @@ static void OPC_6502_26 (void) -static void OPC_6502_27 (void) +static void OPC_6502X_27 (void) /* Opcode $27: RLA zp */ { ILLx2_OP (ZP, RLA); @@ -1681,7 +1676,7 @@ static void OPC_6502_2E (void) -static void OPC_6502_2F (void) +static void OPC_6502X_2F (void) /* Opcode $2F: RLA abs */ { ILLx2_OP (ABS, RLA); @@ -1713,7 +1708,7 @@ static void OPC_6502_31 (void) -static void OPC_65SC02_32 (void) +static void OPC_65C02_32 (void) /* Opcode $32: AND (zp) */ { AC_OP (ZPIND, &); @@ -1721,7 +1716,7 @@ static void OPC_65SC02_32 (void) -static void OPC_6502_33 (void) +static void OPC_6502X_33 (void) /* Opcode $33: RLA (zp),y */ { ILLx2_OP (ZPINDY_NP, RLA); @@ -1729,7 +1724,7 @@ static void OPC_6502_33 (void) -static void OPC_65SC02_34 (void) +static void OPC_65C02_34 (void) /* Opcode $34: BIT zp,x */ { ALU_OP (ZPX, BIT); @@ -1753,7 +1748,7 @@ static void OPC_6502_36 (void) -static void OPC_6502_37 (void) +static void OPC_6502X_37 (void) /* Opcode $37: RLA zp,x */ { ILLx2_OP (ZPX, RLA); @@ -1787,7 +1782,7 @@ static void OPC_6502_39 (void) -static void OPC_65SC02_3A (void) +static void OPC_65C02_3A (void) /* Opcode $3A: DEC a */ { Cycles = 2; @@ -1797,7 +1792,7 @@ static void OPC_65SC02_3A (void) -static void OPC_6502_3B (void) +static void OPC_6502X_3B (void) /* Opcode $3B: RLA abs,y */ { ILLx2_OP (ABSY_NP, RLA); @@ -1805,7 +1800,7 @@ static void OPC_6502_3B (void) -static void OPC_65SC02_3C (void) +static void OPC_65C02_3C (void) /* Opcode $3C: BIT abs,x */ { ALU_OP (ABSX, BIT); @@ -1838,7 +1833,7 @@ static void OPC_65C02_3E (void) -static void OPC_6502_3F (void) +static void OPC_6502X_3F (void) /* Opcode $3F: RLA abs,x */ { ILLx2_OP (ABSX_NP, RLA); @@ -1875,7 +1870,7 @@ static void OPC_6502_41 (void) -static void OPC_6502_43 (void) +static void OPC_6502X_43 (void) /* Opcode $43: SRE (zp,x) */ { ILLx2_OP (ZPXIND, SRE); @@ -1899,7 +1894,7 @@ static void OPC_6502_46 (void) -static void OPC_6502_47 (void) +static void OPC_6502X_47 (void) /* Opcode $47: SRE zp */ { ILLx2_OP (ZP, SRE); @@ -1943,7 +1938,7 @@ static void OPC_6502_4A (void) -static void OPC_6502_4B (void) +static void OPC_6502X_4B (void) /* Opcode $4B: ASR imm */ { ALU_OP_IMM (ASR); @@ -1978,7 +1973,7 @@ static void OPC_6502_4E (void) -static void OPC_6502_4F (void) +static void OPC_6502X_4F (void) /* Opcode $4F: SRE abs */ { ILLx2_OP (ABS, SRE); @@ -2010,7 +2005,7 @@ static void OPC_6502_51 (void) -static void OPC_65SC02_52 (void) +static void OPC_65C02_52 (void) /* Opcode $52: EOR (zp) */ { AC_OP (ZPIND, ^); @@ -2018,7 +2013,7 @@ static void OPC_65SC02_52 (void) -static void OPC_6502_53 (void) +static void OPC_6502X_53 (void) /* Opcode $43: SRE (zp),y */ { ILLx2_OP (ZPINDY_NP, SRE); @@ -2042,7 +2037,7 @@ static void OPC_6502_56 (void) -static void OPC_6502_57 (void) +static void OPC_6502X_57 (void) /* Opcode $57: SRE zp,x */ { ILLx2_OP (ZPX, SRE); @@ -2076,7 +2071,7 @@ static void OPC_6502_59 (void) -static void OPC_65SC02_5A (void) +static void OPC_65C02_5A (void) /* Opcode $5A: PHY */ { Cycles = 3; @@ -2086,7 +2081,7 @@ static void OPC_65SC02_5A (void) -static void OPC_6502_5B (void) +static void OPC_6502X_5B (void) /* Opcode $5B: SRE abs,y */ { ILLx2_OP (ABSY_NP, SRE); @@ -2136,7 +2131,7 @@ static void OPC_65C02_5E (void) -static void OPC_6502_5F (void) +static void OPC_6502X_5F (void) /* Opcode $5F: SRE abs,x */ { ILLx2_OP (ABSX_NP, SRE); @@ -2177,7 +2172,9 @@ static void OPC_65C02_61 (void) ALU_OP (ZPXIND, ADC_65C02); } -static void OPC_6502_63 (void) + + +static void OPC_6502X_63 (void) /* Opcode $63: RRA (zp,x) */ { ILLx2_OP (ZPXIND, RRA); @@ -2185,7 +2182,7 @@ static void OPC_6502_63 (void) -static void OPC_65SC02_64 (void) +static void OPC_65C02_64 (void) /* Opcode $64: STZ zp */ { STO_OP (ZP, 0); @@ -2217,7 +2214,7 @@ static void OPC_6502_66 (void) -static void OPC_6502_67 (void) +static void OPC_6502X_67 (void) /* Opcode $67: RRA zp */ { ILLx2_OP (ZP, RRA); @@ -2259,6 +2256,8 @@ static void OPC_65C02_69 (void) ALU_OP_IMM (ADC_65C02); } + + static void OPC_6502_6A (void) /* Opcode $6A: ROR a */ { @@ -2269,7 +2268,7 @@ static void OPC_6502_6A (void) -static void OPC_6502_6B (void) +static void OPC_6502X_6B (void) /* Opcode $6B: ARR imm */ { ALU_OP_IMM (ARR); @@ -2338,7 +2337,7 @@ static void OPC_6502_6E (void) -static void OPC_6502_6F (void) +static void OPC_6502X_6F (void) /* Opcode $6F: RRA abs */ { ILLx2_OP (ABS, RRA); @@ -2386,7 +2385,7 @@ static void OPC_65C02_72 (void) -static void OPC_6502_73 (void) +static void OPC_6502X_73 (void) /* Opcode $73: RRA (zp),y */ { ILLx2_OP (ZPINDY_NP, RRA); @@ -2394,7 +2393,7 @@ static void OPC_6502_73 (void) -static void OPC_65SC02_74 (void) +static void OPC_65C02_74 (void) /* Opcode $74: STZ zp,x */ { STO_OP (ZPX, 0); @@ -2416,6 +2415,8 @@ static void OPC_65C02_75 (void) ALU_OP (ZPX, ADC_65C02); } + + static void OPC_6502_76 (void) /* Opcode $76: ROR zp,x */ { @@ -2424,7 +2425,7 @@ static void OPC_6502_76 (void) -static void OPC_6502_77 (void) +static void OPC_6502X_77 (void) /* Opcode $77: RRA zp,x */ { ILLx2_OP (ZPX, RRA); @@ -2466,7 +2467,7 @@ static void OPC_65C02_79 (void) -static void OPC_65SC02_7A (void) +static void OPC_65C02_7A (void) /* Opcode $7A: PLY */ { Cycles = 4; @@ -2478,7 +2479,7 @@ static void OPC_65SC02_7A (void) -static void OPC_6502_7B (void) +static void OPC_6502X_7B (void) /* Opcode $7B: RRA abs,y */ { ILLx2_OP (ABSY_NP, RRA); @@ -2486,7 +2487,7 @@ static void OPC_6502_7B (void) -static void OPC_65SC02_7C (void) +static void OPC_65C02_7C (void) /* Opcode $7C: JMP (ind,X) */ { unsigned PC, Adr; @@ -2533,7 +2534,7 @@ static void OPC_65C02_7E (void) -static void OPC_6502_7F (void) +static void OPC_6502X_7F (void) /* Opcode $7F: RRA abs,x */ { ILLx2_OP (ABSX_NP, RRA); @@ -2550,12 +2551,12 @@ static void OPC_65C02_7F (void) /* Aliases of opcode $80 */ -#define OPC_6502_82 OPC_6502_80 -#define OPC_6502_C2 OPC_6502_80 -#define OPC_6502_E2 OPC_6502_80 -#define OPC_6502_89 OPC_6502_80 +#define OPC_6502X_82 OPC_6502X_80 +#define OPC_6502X_C2 OPC_6502X_80 +#define OPC_6502X_E2 OPC_6502X_80 +#define OPC_6502X_89 OPC_6502X_80 -static void OPC_6502_80 (void) +static void OPC_6502X_80 (void) /* Opcode $80: NOP imm */ { ALU_OP_IMM (NOP); @@ -2563,7 +2564,7 @@ static void OPC_6502_80 (void) -static void OPC_65SC02_80 (void) +static void OPC_65C02_80 (void) /* Opcode $80: BRA */ { BRANCH (1); @@ -2579,7 +2580,7 @@ static void OPC_6502_81 (void) -static void OPC_6502_83 (void) +static void OPC_6502X_83 (void) /* Opcode $83: SAX (zp,x) */ { STO_OP (ZPXIND, Regs.AC & Regs.XR); @@ -2611,7 +2612,7 @@ static void OPC_6502_86 (void) -static void OPC_6502_87 (void) +static void OPC_6502X_87 (void) /* Opcode $87: SAX zp */ { STO_OP (ZP, Regs.AC & Regs.XR); @@ -2637,7 +2638,7 @@ static void OPC_6502_88 (void) -static void OPC_65SC02_89 (void) +static void OPC_65C02_89 (void) /* Opcode $89: BIT #imm */ { /* Note: BIT #imm behaves differently from BIT with other addressing modes, @@ -2659,7 +2660,7 @@ static void OPC_6502_8A (void) -static void OPC_6502_8B (void) +static void OPC_6502X_8B (void) /* Opcode $8B: ANE imm */ { ALU_OP_IMM (ANE); @@ -2691,7 +2692,7 @@ static void OPC_6502_8E (void) -static void OPC_6502_8F (void) +static void OPC_6502X_8F (void) /* Opcode $8F: SAX abs */ { STO_OP (ABS, Regs.AC & Regs.XR); @@ -2723,7 +2724,7 @@ static void OPC_6502_91 (void) -static void OPC_65SC02_92 (void) +static void OPC_65C02_92 (void) /* Opcode $92: sta (zp) */ { STO_OP (ZPIND, Regs.AC); @@ -2731,7 +2732,7 @@ static void OPC_65SC02_92 (void) -static void OPC_6502_93 (void) +static void OPC_6502X_93 (void) /* Opcode $93: SHA (zp),y */ { ++Regs.PC; @@ -2776,7 +2777,7 @@ static void OPC_6502_96 (void) -static void OPC_6502_97 (void) +static void OPC_6502X_97 (void) /* Opcode $97: SAX zp,y */ { STO_OP (ZPY, Regs.AC & Regs.XR); @@ -2822,7 +2823,7 @@ static void OPC_6502_9A (void) -static void OPC_6502_9B (void) +static void OPC_6502X_9B (void) /* Opcode $9B: TAS abs,y */ { ++Regs.PC; @@ -2843,7 +2844,7 @@ static void OPC_6502_9B (void) -static void OPC_6502_9C (void) +static void OPC_6502X_9C (void) /* Opcode $9D: SHY abs,x */ { ++Regs.PC; @@ -2863,7 +2864,7 @@ static void OPC_6502_9C (void) -static void OPC_65SC02_9C (void) +static void OPC_65C02_9C (void) /* Opcode $9C: STZ abs */ { STO_OP (ABS, 0); @@ -2879,7 +2880,7 @@ static void OPC_6502_9D (void) -static void OPC_6502_9E (void) +static void OPC_6502X_9E (void) /* Opcode $9E: SHX abs,x */ { ++Regs.PC; @@ -2899,7 +2900,7 @@ static void OPC_6502_9E (void) -static void OPC_65SC02_9E (void) +static void OPC_65C02_9E (void) /* Opcode $9E: STZ abs,x */ { STO_OP (ABSX_NP, 0); @@ -2907,7 +2908,7 @@ static void OPC_65SC02_9E (void) -static void OPC_6502_9F (void) +static void OPC_6502X_9F (void) /* Opcode $9F: SHA abs,y */ { ++Regs.PC; @@ -2959,7 +2960,7 @@ static void OPC_6502_A2 (void) -static void OPC_6502_A3 (void) +static void OPC_6502X_A3 (void) /* Opcode $A3: LAX (zp,x) */ { ALU_OP (ZPXIND, LAX); @@ -2991,7 +2992,7 @@ static void OPC_6502_A6 (void) -static void OPC_6502_A7 (void) +static void OPC_6502X_A7 (void) /* Opcode $A7: LAX zp */ { ALU_OP (ZP, LAX); @@ -3039,7 +3040,7 @@ static void OPC_6502_AA (void) -static void OPC_6502_AB (void) +static void OPC_6502X_AB (void) /* Opcode $AB: LXA imm */ { ALU_OP_IMM (LXA); @@ -3071,7 +3072,7 @@ static void OPC_6502_AE (void) -static void OPC_6502_AF (void) +static void OPC_6502X_AF (void) /* Opcode $AF: LAX abs */ { ALU_OP (ABS, LAX); @@ -3103,7 +3104,7 @@ static void OPC_6502_B1 (void) -static void OPC_65SC02_B2 (void) +static void OPC_65C02_B2 (void) /* Opcode $B2: LDA (zp) */ { ALU_OP (ZPIND, LDA); @@ -3111,7 +3112,7 @@ static void OPC_65SC02_B2 (void) -static void OPC_6502_B3 (void) +static void OPC_6502X_B3 (void) /* Opcode $B3: LAX (zp),y */ { ALU_OP (ZPINDY, LAX); @@ -3143,7 +3144,7 @@ static void OPC_6502_B6 (void) -static void OPC_6502_B7 (void) +static void OPC_6502X_B7 (void) /* Opcode $B7: LAX zp,y */ { ALU_OP (ZPY, LAX); @@ -3189,7 +3190,7 @@ static void OPC_6502_BA (void) -static void OPC_6502_BB (void) +static void OPC_6502X_BB (void) /* Opcode $BB: LAS abs,y */ { ALU_OP (ABSY, LAS); @@ -3221,7 +3222,7 @@ static void OPC_6502_BE (void) -static void OPC_6502_BF (void) +static void OPC_6502X_BF (void) /* Opcode $BF: LAX abs,y */ { ALU_OP (ABSY, LAX); @@ -3253,7 +3254,7 @@ static void OPC_6502_C1 (void) -static void OPC_6502_C3 (void) +static void OPC_6502X_C3 (void) /* Opcode $C3: DCP (zp,x) */ { MEM_OP (ZPXIND, DCP); @@ -3285,7 +3286,7 @@ static void OPC_6502_C6 (void) -static void OPC_6502_C7 (void) +static void OPC_6502X_C7 (void) /* Opcode $C7: DCP zp */ { MEM_OP (ZP, DCP); @@ -3329,7 +3330,7 @@ static void OPC_6502_CA (void) -static void OPC_6502_CB (void) +static void OPC_6502X_CB (void) /* Opcode $CB: SBX imm */ { ALU_OP_IMM (SBX); @@ -3361,7 +3362,7 @@ static void OPC_6502_CE (void) -static void OPC_6502_CF (void) +static void OPC_6502X_CF (void) /* Opcode $CF: DCP abs */ { MEM_OP (ABS, DCP); @@ -3393,7 +3394,7 @@ static void OPC_6502_D1 (void) -static void OPC_65SC02_D2 (void) +static void OPC_65C02_D2 (void) /* Opcode $D2: CMP (zp) */ { ALU_OP (ZPIND, CMP); @@ -3401,7 +3402,7 @@ static void OPC_65SC02_D2 (void) -static void OPC_6502_D3 (void) +static void OPC_6502X_D3 (void) /* Opcode $D3: DCP (zp),y */ { MEM_OP (ZPINDY_NP, DCP); @@ -3425,7 +3426,7 @@ static void OPC_6502_D6 (void) -static void OPC_6502_D7 (void) +static void OPC_6502X_D7 (void) /* Opcode $D7: DCP zp,x */ { MEM_OP (ZPX, DCP); @@ -3459,7 +3460,7 @@ static void OPC_6502_D9 (void) -static void OPC_65SC02_DA (void) +static void OPC_65C02_DA (void) /* Opcode $DA: PHX */ { Cycles = 3; @@ -3469,7 +3470,7 @@ static void OPC_65SC02_DA (void) -static void OPC_6502_DB (void) +static void OPC_6502X_DB (void) /* Opcode $DB: DCP abs,y */ { MEM_OP (ABSY_NP, DCP); @@ -3493,7 +3494,7 @@ static void OPC_6502_DE (void) -static void OPC_6502_DF (void) +static void OPC_6502X_DF (void) /* Opcode $DF: DCP abs,x */ { MEM_OP (ABSX_NP, DCP); @@ -3531,7 +3532,9 @@ static void OPC_65C02_E1 (void) ALU_OP (ZPXIND, SBC_65C02); } -static void OPC_6502_E3 (void) + + +static void OPC_6502X_E3 (void) /* Opcode $E3: ISC (zp,x) */ { MEM_OP (ZPXIND, ISC); @@ -3571,7 +3574,7 @@ static void OPC_6502_E6 (void) -static void OPC_6502_E7 (void) +static void OPC_6502X_E7 (void) /* Opcode $E7: ISC zp */ { MEM_OP (ZP, ISC); @@ -3598,7 +3601,7 @@ static void OPC_6502_E8 (void) /* Aliases of opcode $E9 */ -#define OPC_6502_EB OPC_6502_E9 +#define OPC_6502X_EB OPC_6502_E9 static void OPC_6502_E9 (void) /* Opcode $E9: SBC #imm */ @@ -3615,12 +3618,12 @@ static void OPC_65C02_E9 (void) } /* Aliases of opcode $EA */ -#define OPC_6502_1A OPC_6502_EA -#define OPC_6502_3A OPC_6502_EA -#define OPC_6502_5A OPC_6502_EA -#define OPC_6502_7A OPC_6502_EA -#define OPC_6502_DA OPC_6502_EA -#define OPC_6502_FA OPC_6502_EA +#define OPC_6502X_1A OPC_6502_EA +#define OPC_6502X_3A OPC_6502_EA +#define OPC_6502X_5A OPC_6502_EA +#define OPC_6502X_7A OPC_6502_EA +#define OPC_6502X_DA OPC_6502_EA +#define OPC_6502X_FA OPC_6502_EA static void OPC_6502_EA (void) /* Opcode $EA: NOP */ @@ -3699,7 +3702,7 @@ static void OPC_6502_EE (void) -static void OPC_6502_EF (void) +static void OPC_6502X_EF (void) /* Opcode $EF: ISC abs */ { MEM_OP (ABS, ISC); @@ -3731,7 +3734,6 @@ static void OPC_6502_F1 (void) - static void OPC_65C02_F1 (void) /* Opcode $F1: SBC (zp),y */ { @@ -3748,7 +3750,7 @@ static void OPC_65C02_F2 (void) -static void OPC_6502_F3 (void) +static void OPC_6502X_F3 (void) /* Opcode $F3: ISC (zp),y */ { MEM_OP (ZPINDY_NP, ISC); @@ -3780,7 +3782,7 @@ static void OPC_6502_F6 (void) -static void OPC_6502_F7 (void) +static void OPC_6502X_F7 (void) /* Opcode $F7: ISC zp,x */ { MEM_OP (ZPX, ISC); @@ -3822,7 +3824,7 @@ static void OPC_65C02_F9 (void) -static void OPC_65SC02_FA (void) +static void OPC_65C02_FA (void) /* Opcode $7A: PLX */ { Cycles = 4; @@ -3834,7 +3836,7 @@ static void OPC_65SC02_FA (void) -static void OPC_6502_FB (void) +static void OPC_6502X_FB (void) /* Opcode $FB: ISC abs,y */ { MEM_OP (ABSY_NP, ISC); @@ -3866,7 +3868,7 @@ static void OPC_6502_FE (void) -static void OPC_6502_FF (void) +static void OPC_6502X_FF (void) /* Opcode $FF: ISC abs,x */ { MEM_OP (ABSX_NP, ISC); @@ -4155,259 +4157,259 @@ static const OPFunc OP6502XTable[256] = { OPC_6502_00, OPC_6502_01, OPC_Illegal, - OPC_6502_03, - OPC_6502_04, + OPC_6502X_03, + OPC_6502X_04, OPC_6502_05, OPC_6502_06, - OPC_6502_07, + OPC_6502X_07, OPC_6502_08, OPC_6502_09, OPC_6502_0A, - OPC_6502_0B, - OPC_6502_0C, + OPC_6502X_0B, + OPC_6502X_0C, OPC_6502_0D, OPC_6502_0E, - OPC_6502_0F, + OPC_6502X_0F, OPC_6502_10, OPC_6502_11, OPC_Illegal, - OPC_6502_13, - OPC_6502_14, + OPC_6502X_13, + OPC_6502X_14, OPC_6502_15, OPC_6502_16, - OPC_6502_17, + OPC_6502X_17, OPC_6502_18, OPC_6502_19, - OPC_6502_1A, - OPC_6502_1B, - OPC_6502_1C, + OPC_6502X_1A, + OPC_6502X_1B, + OPC_6502X_1C, OPC_6502_1D, OPC_6502_1E, - OPC_6502_1F, + OPC_6502X_1F, OPC_6502_20, OPC_6502_21, OPC_Illegal, - OPC_6502_23, + OPC_6502X_23, OPC_6502_24, OPC_6502_25, OPC_6502_26, - OPC_6502_27, + OPC_6502X_27, OPC_6502_28, OPC_6502_29, OPC_6502_2A, - OPC_6502_2B, + OPC_6502X_2B, OPC_6502_2C, OPC_6502_2D, OPC_6502_2E, - OPC_6502_2F, + OPC_6502X_2F, OPC_6502_30, OPC_6502_31, OPC_Illegal, - OPC_6502_33, - OPC_6502_34, + OPC_6502X_33, + OPC_6502X_34, OPC_6502_35, OPC_6502_36, - OPC_6502_37, + OPC_6502X_37, OPC_6502_38, OPC_6502_39, - OPC_6502_3A, - OPC_6502_3B, - OPC_6502_3C, + OPC_6502X_3A, + OPC_6502X_3B, + OPC_6502X_3C, OPC_6502_3D, OPC_6502_3E, - OPC_6502_3F, + OPC_6502X_3F, OPC_6502_40, OPC_6502_41, OPC_Illegal, - OPC_6502_43, - OPC_6502_44, + OPC_6502X_43, + OPC_6502X_44, OPC_6502_45, OPC_6502_46, - OPC_6502_47, + OPC_6502X_47, OPC_6502_48, OPC_6502_49, OPC_6502_4A, - OPC_6502_4B, + OPC_6502X_4B, OPC_6502_4C, OPC_6502_4D, OPC_6502_4E, - OPC_6502_4F, + OPC_6502X_4F, OPC_6502_50, OPC_6502_51, OPC_Illegal, - OPC_6502_53, - OPC_6502_54, + OPC_6502X_53, + OPC_6502X_54, OPC_6502_55, OPC_6502_56, - OPC_6502_57, + OPC_6502X_57, OPC_6502_58, OPC_6502_59, - OPC_6502_5A, - OPC_6502_5B, - OPC_6502_5C, + OPC_6502X_5A, + OPC_6502X_5B, + OPC_6502X_5C, OPC_6502_5D, OPC_6502_5E, - OPC_6502_5F, + OPC_6502X_5F, OPC_6502_60, OPC_6502_61, OPC_Illegal, - OPC_6502_63, - OPC_6502_64, + OPC_6502X_63, + OPC_6502X_64, OPC_6502_65, OPC_6502_66, - OPC_6502_67, + OPC_6502X_67, OPC_6502_68, OPC_6502_69, OPC_6502_6A, - OPC_6502_6B, + OPC_6502X_6B, OPC_6502_6C, OPC_6502_6D, OPC_6502_6E, - OPC_6502_6F, + OPC_6502X_6F, OPC_6502_70, OPC_6502_71, OPC_Illegal, - OPC_6502_73, - OPC_6502_74, + OPC_6502X_73, + OPC_6502X_74, OPC_6502_75, OPC_6502_76, - OPC_6502_77, + OPC_6502X_77, OPC_6502_78, OPC_6502_79, - OPC_6502_7A, - OPC_6502_7B, - OPC_6502_7C, + OPC_6502X_7A, + OPC_6502X_7B, + OPC_6502X_7C, OPC_6502_7D, OPC_6502_7E, - OPC_6502_7F, - OPC_6502_80, + OPC_6502X_7F, + OPC_6502X_80, OPC_6502_81, - OPC_6502_82, - OPC_6502_83, + OPC_6502X_82, + OPC_6502X_83, OPC_6502_84, OPC_6502_85, OPC_6502_86, - OPC_6502_87, + OPC_6502X_87, OPC_6502_88, - OPC_6502_89, + OPC_6502X_89, OPC_6502_8A, - OPC_6502_8B, + OPC_6502X_8B, OPC_6502_8C, OPC_6502_8D, OPC_6502_8E, - OPC_6502_8F, + OPC_6502X_8F, OPC_6502_90, OPC_6502_91, OPC_Illegal, - OPC_6502_93, + OPC_6502X_93, OPC_6502_94, OPC_6502_95, OPC_6502_96, - OPC_6502_97, + OPC_6502X_97, OPC_6502_98, OPC_6502_99, OPC_6502_9A, - OPC_6502_9B, - OPC_6502_9C, + OPC_6502X_9B, + OPC_6502X_9C, OPC_6502_9D, - OPC_6502_9E, - OPC_6502_9F, + OPC_6502X_9E, + OPC_6502X_9F, OPC_6502_A0, OPC_6502_A1, OPC_6502_A2, - OPC_6502_A3, + OPC_6502X_A3, OPC_6502_A4, OPC_6502_A5, OPC_6502_A6, - OPC_6502_A7, + OPC_6502X_A7, OPC_6502_A8, OPC_6502_A9, OPC_6502_AA, - OPC_6502_AB, + OPC_6502X_AB, OPC_6502_AC, OPC_6502_AD, OPC_6502_AE, - OPC_6502_AF, + OPC_6502X_AF, OPC_6502_B0, OPC_6502_B1, OPC_Illegal, - OPC_6502_B3, + OPC_6502X_B3, OPC_6502_B4, OPC_6502_B5, OPC_6502_B6, - OPC_6502_B7, + OPC_6502X_B7, OPC_6502_B8, OPC_6502_B9, OPC_6502_BA, - OPC_6502_BB, + OPC_6502X_BB, OPC_6502_BC, OPC_6502_BD, OPC_6502_BE, - OPC_6502_BF, + OPC_6502X_BF, OPC_6502_C0, OPC_6502_C1, - OPC_6502_C2, - OPC_6502_C3, + OPC_6502X_C2, + OPC_6502X_C3, OPC_6502_C4, OPC_6502_C5, OPC_6502_C6, - OPC_6502_C7, + OPC_6502X_C7, OPC_6502_C8, OPC_6502_C9, OPC_6502_CA, - OPC_6502_CB, + OPC_6502X_CB, OPC_6502_CC, OPC_6502_CD, OPC_6502_CE, - OPC_6502_CF, + OPC_6502X_CF, OPC_6502_D0, OPC_6502_D1, OPC_Illegal, - OPC_6502_D3, - OPC_6502_D4, + OPC_6502X_D3, + OPC_6502X_D4, OPC_6502_D5, OPC_6502_D6, - OPC_6502_D7, + OPC_6502X_D7, OPC_6502_D8, OPC_6502_D9, - OPC_6502_DA, - OPC_6502_DB, - OPC_6502_DC, + OPC_6502X_DA, + OPC_6502X_DB, + OPC_6502X_DC, OPC_6502_DD, OPC_6502_DE, - OPC_6502_DF, + OPC_6502X_DF, OPC_6502_E0, OPC_6502_E1, - OPC_6502_E2, - OPC_6502_E3, + OPC_6502X_E2, + OPC_6502X_E3, OPC_6502_E4, OPC_6502_E5, OPC_6502_E6, - OPC_6502_E7, + OPC_6502X_E7, OPC_6502_E8, OPC_6502_E9, OPC_6502_EA, - OPC_6502_EB, + OPC_6502X_EB, OPC_6502_EC, OPC_6502_ED, OPC_6502_EE, - OPC_6502_EF, + OPC_6502X_EF, OPC_6502_F0, OPC_6502_F1, OPC_Illegal, - OPC_6502_F3, - OPC_6502_F4, + OPC_6502X_F3, + OPC_6502X_F4, OPC_6502_F5, OPC_6502_F6, - OPC_6502_F7, + OPC_6502X_F7, OPC_6502_F8, OPC_6502_F9, - OPC_6502_FA, - OPC_6502_FB, - OPC_6502_FC, + OPC_6502X_FA, + OPC_6502X_FB, + OPC_6502X_FC, OPC_6502_FD, OPC_6502_FE, - OPC_6502_FF + OPC_6502X_FF }; @@ -4418,7 +4420,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_01, OPC_65C02_NOP22, // $02 OPC_65C02_NOP11, // $03 - OPC_65SC02_04, + OPC_65C02_04, OPC_6502_05, OPC_6502_06, OPC_65C02_07, @@ -4426,23 +4428,23 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_09, OPC_6502_0A, OPC_65C02_NOP11, // $0B - OPC_65SC02_0C, + OPC_65C02_0C, OPC_6502_0D, OPC_6502_0E, OPC_65C02_0F, OPC_6502_10, OPC_6502_11, - OPC_65SC02_12, + OPC_65C02_12, OPC_65C02_NOP11, // $13 - OPC_65SC02_14, + OPC_65C02_14, OPC_6502_15, OPC_6502_16, OPC_65C02_17, OPC_6502_18, OPC_6502_19, - OPC_65SC02_1A, + OPC_65C02_1A, OPC_65C02_NOP11, // $1B - OPC_65SC02_1C, + OPC_65C02_1C, OPC_6502_1D, OPC_65C02_1E, OPC_65C02_1F, @@ -4464,17 +4466,17 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_2F, OPC_6502_30, OPC_6502_31, - OPC_65SC02_32, + OPC_65C02_32, OPC_65C02_NOP11, // $33 - OPC_65SC02_34, + OPC_65C02_34, OPC_6502_35, OPC_6502_36, OPC_65C02_37, OPC_6502_38, OPC_6502_39, - OPC_65SC02_3A, + OPC_65C02_3A, OPC_65C02_NOP11, // $3B - OPC_65SC02_3C, + OPC_65C02_3C, OPC_6502_3D, OPC_65C02_3E, OPC_65C02_3F, @@ -4482,7 +4484,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_41, OPC_65C02_NOP22, // $42 OPC_65C02_NOP11, // $43 - OPC_6502_44, // $44 + OPC_6502X_44, // $44 OPC_6502_45, OPC_6502_46, OPC_65C02_47, @@ -4496,7 +4498,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_4F, OPC_6502_50, OPC_6502_51, - OPC_65SC02_52, + OPC_65C02_52, OPC_65C02_NOP11, // $53 OPC_65C02_NOP24, // $54 OPC_6502_55, @@ -4504,7 +4506,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_57, OPC_6502_58, OPC_6502_59, - OPC_65SC02_5A, + OPC_65C02_5A, OPC_65C02_NOP11, // $5B OPC_65C02_5C, OPC_6502_5D, @@ -4514,7 +4516,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_61, OPC_65C02_NOP22, // $62 OPC_65C02_NOP11, // $63 - OPC_65SC02_64, + OPC_65C02_64, OPC_65C02_65, OPC_6502_66, OPC_65C02_67, @@ -4530,19 +4532,19 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_71, OPC_65C02_72, OPC_65C02_NOP11, // $73 - OPC_65SC02_74, + OPC_65C02_74, OPC_65C02_75, OPC_6502_76, OPC_65C02_77, OPC_6502_78, OPC_65C02_79, - OPC_65SC02_7A, + OPC_65C02_7A, OPC_65C02_NOP11, // $7B - OPC_65SC02_7C, + OPC_65C02_7C, OPC_65C02_7D, OPC_65C02_7E, OPC_65C02_7F, - OPC_65SC02_80, + OPC_65C02_80, OPC_6502_81, OPC_65C02_NOP22, // $82 OPC_65C02_NOP11, // $83 @@ -4551,7 +4553,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_86, OPC_65C02_87, OPC_6502_88, - OPC_65SC02_89, + OPC_65C02_89, OPC_6502_8A, OPC_65C02_NOP11, // $8B OPC_6502_8C, @@ -4560,7 +4562,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_8F, OPC_6502_90, OPC_6502_91, - OPC_65SC02_92, + OPC_65C02_92, OPC_65C02_NOP11, // $93 OPC_6502_94, OPC_6502_95, @@ -4570,9 +4572,9 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_99, OPC_6502_9A, OPC_65C02_NOP11, // $9B - OPC_65SC02_9C, + OPC_65C02_9C, OPC_6502_9D, - OPC_65SC02_9E, + OPC_65C02_9E, OPC_65C02_9F, OPC_6502_A0, OPC_6502_A1, @@ -4592,7 +4594,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_AF, OPC_6502_B0, OPC_6502_B1, - OPC_65SC02_B2, + OPC_65C02_B2, OPC_65C02_NOP11, // $B3 OPC_6502_B4, OPC_6502_B5, @@ -4624,7 +4626,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_CF, OPC_6502_D0, OPC_6502_D1, - OPC_65SC02_D2, + OPC_65C02_D2, OPC_65C02_NOP11, // $D3 OPC_65C02_NOP24, // $D4 OPC_6502_D5, @@ -4632,7 +4634,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_D7, OPC_6502_D8, OPC_6502_D9, - OPC_65SC02_DA, + OPC_65C02_DA, OPC_Illegal, // $DB: STP currently unsupported OPC_65C02_NOP34, // $DC OPC_6502_DD, @@ -4664,7 +4666,7 @@ static const OPFunc OP65C02Table[256] = { OPC_65C02_F7, OPC_6502_F8, OPC_65C02_F9, - OPC_65SC02_FA, + OPC_65C02_FA, OPC_65C02_NOP11, // $FB OPC_65C02_NOP34, // $FC OPC_65C02_FD, @@ -4693,7 +4695,7 @@ void IRQRequest (void) /* Generate an IRQ */ { /* Remember the request */ - HaveIRQRequest = 1; + HaveIRQRequest = true; } @@ -4702,7 +4704,7 @@ void NMIRequest (void) /* Generate an NMI */ { /* Remember the request */ - HaveNMIRequest = 1; + HaveNMIRequest = true; } @@ -4711,8 +4713,8 @@ void Reset (void) /* Generate a CPU RESET */ { /* Reset the CPU */ - HaveIRQRequest = 0; - HaveNMIRequest = 0; + HaveIRQRequest = false; + HaveNMIRequest = false; /* Bits 5 and 4 aren't used, and always are 1! */ Regs.SR = 0x30; @@ -4727,7 +4729,7 @@ unsigned ExecuteInsn (void) /* If we have an NMI request, handle it */ if (HaveNMIRequest) { - HaveNMIRequest = 0; + HaveNMIRequest = false; PUSH (PCH); PUSH (PCL); PUSH (Regs.SR & ~BF); @@ -4741,7 +4743,7 @@ unsigned ExecuteInsn (void) } else if (HaveIRQRequest && GET_IF () == 0) { - HaveIRQRequest = 0; + HaveIRQRequest = false; PUSH (PCH); PUSH (PCL); PUSH (Regs.SR & ~BF); @@ -4756,12 +4758,12 @@ unsigned ExecuteInsn (void) } else { /* Normal instruction - read the next opcode */ - unsigned char OPC = MemReadByte (Regs.PC); + uint8_t OPC = MemReadByte (Regs.PC); /* Execute it */ Handlers[CPU][OPC] (); } - /* Return the number of clock cycles needed by this insn */ + /* Return the number of clock cycles needed by this instruction */ return Cycles; } From e37a2b1559570d567e35ae55928280b09b3655d1 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Tue, 31 Dec 2024 13:35:16 +0100 Subject: [PATCH 360/707] Updated documentation with counter documentation. --- doc/sim65.sgml | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 962f07254..9c54c71f3 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -151,6 +151,71 @@ int main() // sim65 example.prg </verb></tscreen> +<sect>Counter peripheral<p> + +The sim65 simulator supports a memory-mapped counter peripheral that manages +a number of 64-bit counters that are continuously updated as the simulator is +running. For each counter, it also provides a 64 bit "latching" register. + +The functionality of the counter peripheral is accessible through 3 registers: + +* PERIPHERALS_COUNTER_LATCH ($FFC0, write-only) +* PERIPHERALS_COUNTER_SELECT ($FFC1, read/write) +* PERIPHERALS_COUNTER_VALUE ($FFC2..$FFC9, read-only) + +These three registers are used as follows. + +When a program explicitly requests a "counter latch" operation by writing any value +to the PERIPHERALS_COUNTER_LATCH address ($FFC0), all live registers are copied to +the latch registers. They will keep the latched value until another latch operation +updates them. + +The PERIPHERALS_COUNTER_SELECT address ($FFC1) register holds an 8-bit value that +specifies which 64-bit value is currently readable through the PERIPHERALS_COUNTER_VALUE +address range. Possible values are: + +$00: latched clock cycle counter selected. +$01: latched CPU instruction counter selected. +$02: latched IRQ interrupt counter selected. +$03: latched NMI interrupt counter selected. + +In addition to these counters, two other latch registers are available that are also +updated when the PERIPHERALS_COUNTER_LATCH address is written: + +$80: latched wallclock time (nanoseconds) selected. +$81: latched wallclock time (split s/ns) selected. + +When PERIPHERALS_COUNTER_LATCH equals $80, the PERIPHERALS_COUNTER_VALUE will be a +64-bit value corresponding to the number of nanoseconds elapsed since Midnight, Jan 1st, +1970 UTC. + +When PERIPHERALS_COUNTER_LATCH equals $81, the high 32 bits of PERIPHERALS_COUNTER_VALUE +will be a 32-bit value corresponding to the number of seconds elapsed since Midnight, +Jan 1st, 1970 UTC. The low 32 bits of PERIPHERALS_COUNTER_VALUE will hold the +nanoseconds since the start of that seconds. + +The two different wallclock-time latch registers are provided for different applications. +For some applications, the single 64-bit value will be more convenient, while for other +applications, the split 32/32 bits representations with separate seconds and nanoseconds +is more convenient. + +Note that the definition above given as "time since Midnight, Jan 1st, 1970 UTC" is an +approximation, as the implementation depends on the POSIX definition of time which does +not account for leap seconds. + +If the PERIPHERALS_COUNTER_SELECT register holds a value other than one of the six values +described above, all PERIPHERALS_COUNTER_VALUE bytes will read as zero. + +On reset, PERIPHERALS_COUNTER_SELECT is initialized to zero. + +The PERIPHERALS_COUNTER_VALUE addresses ($FFC2..$FFC9) are used to read to currently +selected latch register value. Address $FFF2 holds the least significant byte (LSB), +while address $FFC9 holds the most significant byte (MSB). + +On reset, all latch registers are reset to zero. this means that reading any of the +PERIPHERALS_COUNTER_VALUE bytes before a write to PERIPHERALS_COUNTER_LATCH will +yield zero. + <sect>Creating a Test in Assembly<p> Though a C test may also link with assembly code, From f95a60d5ad7249e0f40e41356595b6839a56d418 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Tue, 31 Dec 2024 13:48:45 +0100 Subject: [PATCH 361/707] Updating sim65 docs. --- doc/sim65.sgml | 71 ++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 9c54c71f3..7d54b87b9 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -151,70 +151,73 @@ int main() // sim65 example.prg </verb></tscreen> -<sect>Counter peripheral<p> +<sect>Counter peripheral -The sim65 simulator supports a memory-mapped counter peripheral that manages +<p>The sim65 simulator supports a memory-mapped counter peripheral that manages a number of 64-bit counters that are continuously updated as the simulator is running. For each counter, it also provides a 64 bit "latching" register. -The functionality of the counter peripheral is accessible through 3 registers: +<p>The functionality of the counter peripheral is accessible through 3 registers: -* PERIPHERALS_COUNTER_LATCH ($FFC0, write-only) -* PERIPHERALS_COUNTER_SELECT ($FFC1, read/write) -* PERIPHERALS_COUNTER_VALUE ($FFC2..$FFC9, read-only) +<itemize> +<item><tt>PERIPHERALS_COUNTER_LATCH</tt> ($FFC0, write-only) +<item><tt>PERIPHERALS_COUNTER_SELECT</tt> ($FFC1, read/write) +<item><tt>PERIPHERALS_COUNTER_VALUE</tt> ($FFC2..$FFC9, read-only) +</itemize> -These three registers are used as follows. +<p>These three registers are used as follows. -When a program explicitly requests a "counter latch" operation by writing any value -to the PERIPHERALS_COUNTER_LATCH address ($FFC0), all live registers are copied to +<p>When a program explicitly requests a "counter latch" operation by writing any value +to the <tt>PERIPHERALS_COUNTER_LATCH</tt> address ($FFC0), all live registers are copied to the latch registers. They will keep the latched value until another latch operation updates them. -The PERIPHERALS_COUNTER_SELECT address ($FFC1) register holds an 8-bit value that -specifies which 64-bit value is currently readable through the PERIPHERALS_COUNTER_VALUE -address range. Possible values are: +<p>The <tt>PERIPHERALS_COUNTER_SELECT</tt> address ($FFC1) register holds an 8-bit value that +specifies which 64-bit value is currently readable through the <tt>PERIPHERALS_COUNTER_VALUE</tt> +address range. Six values are currently defined: -$00: latched clock cycle counter selected. -$01: latched CPU instruction counter selected. -$02: latched IRQ interrupt counter selected. -$03: latched NMI interrupt counter selected. +<itemize> +<item>$00: latched clock cycle counter selected. +<item>$01: latched CPU instruction counter selected. +<item>$02: latched IRQ interrupt counter selected. +<item>$03: latched NMI interrupt counter selected. +<item>$80: latched wallclock time (nanoseconds) selected. +<item>$81: latched wallclock time (split s/ns) selected. +</itemize> -In addition to these counters, two other latch registers are available that are also -updated when the PERIPHERALS_COUNTER_LATCH address is written: +<p>Values $00 to $03 provide access to the latched (frozen) value of their respective live +counters at the time of the last write to <tt>PERIPHERALS_COUNTER_LATCH</tt> . -$80: latched wallclock time (nanoseconds) selected. -$81: latched wallclock time (split s/ns) selected. - -When PERIPHERALS_COUNTER_LATCH equals $80, the PERIPHERALS_COUNTER_VALUE will be a -64-bit value corresponding to the number of nanoseconds elapsed since Midnight, Jan 1st, +<p>When <tt>PERIPHERALS_COUNTER_LATCH</tt> equals $80, the <tt>PERIPHERALS_COUNTER_VALUE</tt> +will be a 64-bit value corresponding to the number of nanoseconds elapsed since Midnight, Jan 1st, 1970 UTC. -When PERIPHERALS_COUNTER_LATCH equals $81, the high 32 bits of PERIPHERALS_COUNTER_VALUE +<p>When <tt>PERIPHERALS_COUNTER_LATCH</tt> equals $81, the high 32 bits of <tt>PERIPHERALS_COUNTER_VALUE</tt> will be a 32-bit value corresponding to the number of seconds elapsed since Midnight, -Jan 1st, 1970 UTC. The low 32 bits of PERIPHERALS_COUNTER_VALUE will hold the +Jan 1st, 1970 UTC. The low 32 bits of <tt>PERIPHERALS_COUNTER_VALUE</tt> will hold the nanoseconds since the start of that seconds. -The two different wallclock-time latch registers are provided for different applications. +<p>The two different wallclock-time latch registers are provided for different applications. For some applications, the single 64-bit value will be more convenient, while for other applications, the split 32/32 bits representations with separate seconds and nanoseconds is more convenient. -Note that the definition above given as "time since Midnight, Jan 1st, 1970 UTC" is an +<p>Note that the definition above given as time since Midnight, Jan 1st, 1970 UTC is an approximation, as the implementation depends on the POSIX definition of time which does not account for leap seconds. -If the PERIPHERALS_COUNTER_SELECT register holds a value other than one of the six values -described above, all PERIPHERALS_COUNTER_VALUE bytes will read as zero. +<p>If the <tt>PERIPHERALS_COUNTER_SELECT</tt> register holds a value other than one of the six +values described above, all <tt>PERIPHERALS_COUNTER_VALUE</tt> bytes will read as zero. -On reset, PERIPHERALS_COUNTER_SELECT is initialized to zero. +<p>On reset, <tt>PERIPHERALS_COUNTER_SELECT</tt> is initialized to zero. -The PERIPHERALS_COUNTER_VALUE addresses ($FFC2..$FFC9) are used to read to currently +<p>The <tt>PERIPHERALS_COUNTER_VALUE</tt> addresses ($FFC2..$FFC9) are used to read to currently selected latch register value. Address $FFF2 holds the least significant byte (LSB), while address $FFC9 holds the most significant byte (MSB). -On reset, all latch registers are reset to zero. this means that reading any of the -PERIPHERALS_COUNTER_VALUE bytes before a write to PERIPHERALS_COUNTER_LATCH will -yield zero. +<p>On reset, all latch registers are reset to zero. this means that reading any of the +<tt>PERIPHERALS_COUNTER_VALUE</tt> bytes before a write to <tt>PERIPHERALS_COUNTER_LATCH</tt> +will yield zero. <sect>Creating a Test in Assembly<p> From d8df73c36d6dfab9033cb24c4e206cb468d1fafd Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Tue, 31 Dec 2024 17:54:58 +0100 Subject: [PATCH 362/707] Improved counter peripheral documentation, and moved its documentation to the end of the page just before the copyright notice. --- doc/sim65.sgml | 134 ++++++++++++++++++++++++------------------------- 1 file changed, 66 insertions(+), 68 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 7d54b87b9..f8e5caf19 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -151,74 +151,6 @@ int main() // sim65 example.prg </verb></tscreen> -<sect>Counter peripheral - -<p>The sim65 simulator supports a memory-mapped counter peripheral that manages -a number of 64-bit counters that are continuously updated as the simulator is -running. For each counter, it also provides a 64 bit "latching" register. - -<p>The functionality of the counter peripheral is accessible through 3 registers: - -<itemize> -<item><tt>PERIPHERALS_COUNTER_LATCH</tt> ($FFC0, write-only) -<item><tt>PERIPHERALS_COUNTER_SELECT</tt> ($FFC1, read/write) -<item><tt>PERIPHERALS_COUNTER_VALUE</tt> ($FFC2..$FFC9, read-only) -</itemize> - -<p>These three registers are used as follows. - -<p>When a program explicitly requests a "counter latch" operation by writing any value -to the <tt>PERIPHERALS_COUNTER_LATCH</tt> address ($FFC0), all live registers are copied to -the latch registers. They will keep the latched value until another latch operation -updates them. - -<p>The <tt>PERIPHERALS_COUNTER_SELECT</tt> address ($FFC1) register holds an 8-bit value that -specifies which 64-bit value is currently readable through the <tt>PERIPHERALS_COUNTER_VALUE</tt> -address range. Six values are currently defined: - -<itemize> -<item>$00: latched clock cycle counter selected. -<item>$01: latched CPU instruction counter selected. -<item>$02: latched IRQ interrupt counter selected. -<item>$03: latched NMI interrupt counter selected. -<item>$80: latched wallclock time (nanoseconds) selected. -<item>$81: latched wallclock time (split s/ns) selected. -</itemize> - -<p>Values $00 to $03 provide access to the latched (frozen) value of their respective live -counters at the time of the last write to <tt>PERIPHERALS_COUNTER_LATCH</tt> . - -<p>When <tt>PERIPHERALS_COUNTER_LATCH</tt> equals $80, the <tt>PERIPHERALS_COUNTER_VALUE</tt> -will be a 64-bit value corresponding to the number of nanoseconds elapsed since Midnight, Jan 1st, -1970 UTC. - -<p>When <tt>PERIPHERALS_COUNTER_LATCH</tt> equals $81, the high 32 bits of <tt>PERIPHERALS_COUNTER_VALUE</tt> -will be a 32-bit value corresponding to the number of seconds elapsed since Midnight, -Jan 1st, 1970 UTC. The low 32 bits of <tt>PERIPHERALS_COUNTER_VALUE</tt> will hold the -nanoseconds since the start of that seconds. - -<p>The two different wallclock-time latch registers are provided for different applications. -For some applications, the single 64-bit value will be more convenient, while for other -applications, the split 32/32 bits representations with separate seconds and nanoseconds -is more convenient. - -<p>Note that the definition above given as time since Midnight, Jan 1st, 1970 UTC is an -approximation, as the implementation depends on the POSIX definition of time which does -not account for leap seconds. - -<p>If the <tt>PERIPHERALS_COUNTER_SELECT</tt> register holds a value other than one of the six -values described above, all <tt>PERIPHERALS_COUNTER_VALUE</tt> bytes will read as zero. - -<p>On reset, <tt>PERIPHERALS_COUNTER_SELECT</tt> is initialized to zero. - -<p>The <tt>PERIPHERALS_COUNTER_VALUE</tt> addresses ($FFC2..$FFC9) are used to read to currently -selected latch register value. Address $FFF2 holds the least significant byte (LSB), -while address $FFC9 holds the most significant byte (MSB). - -<p>On reset, all latch registers are reset to zero. this means that reading any of the -<tt>PERIPHERALS_COUNTER_VALUE</tt> bytes before a write to <tt>PERIPHERALS_COUNTER_LATCH</tt> -will yield zero. - <sect>Creating a Test in Assembly<p> Though a C test may also link with assembly code, @@ -296,6 +228,72 @@ but if customization is needed <tt/sim6502.cfg/ or <tt/sim65c02.cfg/ might be us </itemize> +<sect>Counter peripheral + +<p>The sim65 simulator supports a memory-mapped counter peripheral that manages +a number of 64-bit counters that are continuously updated as the simulator is +running. For each counter, it also provides a 64 bit "latching" register. + +<p>The functionality of the counter peripheral is accessible through 3 registers: + +<itemize> +<item><tt>PERIPHERALS_COUNTER_LATCH</tt> ($FFC0, write-only) +<item><tt>PERIPHERALS_COUNTER_SELECT</tt> ($FFC1, read/write) +<item><tt>PERIPHERALS_COUNTER_VALUE</tt> ($FFC2..$FFC9, read-only) +</itemize> + +<p>These three registers are used as follows. + +<p>When a program explicitly requests a "counter latch" operation by writing any value +to the <tt>PERIPHERALS_COUNTER_LATCH</tt> address ($FFC0), all live registers are simultaneously +copied to the latch registers. They will keep the newly latched value until another latch +operation is requested. + +<p>The <tt>PERIPHERALS_COUNTER_SELECT</tt> address ($FFC1) register holds an 8-bit value that +specifies which 64-bit latch register is currently readable through the <tt>PERIPHERALS_COUNTER_VALUE</tt> +address range. Six values are currently defined: + +<itemize> +<item>$00: latched clock cycle counter selected. +<item>$01: latched CPU instruction counter selected. +<item>$02: latched IRQ interrupt counter selected. +<item>$03: latched NMI interrupt counter selected. +<item>$80: latched wallclock time (nanoseconds) selected. +<item>$81: latched wallclock time (split s/ns) selected. +</itemize> + +<p>Values $00 to $03 provide access to the latched (frozen) value of their respective live +counters at the time of the last write to <tt>PERIPHERALS_COUNTER_LATCH</tt>. + +<p>When <tt>PERIPHERALS_COUNTER_LATCH</tt> equals $80, the <tt>PERIPHERALS_COUNTER_VALUE</tt> +will be a 64-bit value corresponding to the number of nanoseconds elapsed since Midnight, Jan 1st, +1970 UTC, at the time of the last latch operation. + +<p>When <tt>PERIPHERALS_COUNTER_LATCH</tt> equals $81, the high 32 bits of <tt>PERIPHERALS_COUNTER_VALUE</tt> +will be a 32-bit value corresponding to the number of seconds elapsed since Midnight, +Jan 1st, 1970 UTC, at the time of the last latch operation. The low 32 bits of +<tt>PERIPHERALS_COUNTER_VALUE</tt> will hold the nanoseconds since the start of that second. + +<p>The two different wallclock-time latch registers will always refer to precisely the same time instant. +For some applications, the single 64-bit value measured in nanoseconds will be more convenient, while +for other applications, the split 32/32 bits representations with separate seconds and nanosecond +values will be more convenient. + +<p>Note that the definition above, with time elapsed measured since Midnight, Jan 1st, 1970 UTC is +an approximation, as the implementation depends on the way POSIX definition time, which does +not account for leap seconds (POSIX falsely assumes that all days are precisely 86400 seconds +long). + +<p>On reset, <tt>PERIPHERALS_COUNTER_SELECT</tt> is initialized to zero. If the <tt>PERIPHERALS_COUNTER_SELECT</tt> +register holds a value other than one of the six values described above, all <tt>PERIPHERALS_COUNTER_VALUE</tt> +bytes will read as zero. + +<p>The <tt>PERIPHERALS_COUNTER_VALUE</tt> addresses ($FFC2..$FFC9) are used to read to currently +selected 64-bit latch register value. Address $FFC2 holds the least significant byte (LSB), +while address $FFC9 holds the most significant byte (MSB). + +<p>On reset, all latch registers are reset to zero. Reading any of the <tt>PERIPHERALS_COUNTER_VALUE</tt> +bytes before the first write to <tt>PERIPHERALS_COUNTER_LATCH</tt> will yield zero. <sect>Copyright<p> From 915416dc663323dbc9cff2fab404a8395aa6448f Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Tue, 31 Dec 2024 18:11:35 +0100 Subject: [PATCH 363/707] Added example. --- doc/sim65.sgml | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index f8e5caf19..849d6c65c 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -276,13 +276,12 @@ Jan 1st, 1970 UTC, at the time of the last latch operation. The low 32 bits of <p>The two different wallclock-time latch registers will always refer to precisely the same time instant. For some applications, the single 64-bit value measured in nanoseconds will be more convenient, while -for other applications, the split 32/32 bits representations with separate seconds and nanosecond +for other applications, the split 32/32 bits representations with separate second and nanosecond values will be more convenient. -<p>Note that the definition above, with time elapsed measured since Midnight, Jan 1st, 1970 UTC is -an approximation, as the implementation depends on the way POSIX definition time, which does -not account for leap seconds (POSIX falsely assumes that all days are precisely 86400 seconds -long). +<p>Note that the definition above, with time elapsed measured since Midnight, Jan 1st, 1970 UTC, is +an approximation, as the implementation depends on the way POSIX definition time, and POSIX does +not account for leap seconds; it falsely assumes that all days are precisely 86400 seconds long. <p>On reset, <tt>PERIPHERALS_COUNTER_SELECT</tt> is initialized to zero. If the <tt>PERIPHERALS_COUNTER_SELECT</tt> register holds a value other than one of the six values described above, all <tt>PERIPHERALS_COUNTER_VALUE</tt> @@ -295,6 +294,39 @@ while address $FFC9 holds the most significant byte (MSB). <p>On reset, all latch registers are reset to zero. Reading any of the <tt>PERIPHERALS_COUNTER_VALUE</tt> bytes before the first write to <tt>PERIPHERALS_COUNTER_LATCH</tt> will yield zero. +Example: + +<tscreen><verb> +#include <stdio.h> +#include <stdint.h> + +volatile uint8_t * CounterLatch = (uint8_t *)0xffc0; +volatile uint8_t * CounterSelect = (uint8_t *)0xffc1; +volatile uint32_t * CounterValue = (uint32_t *)0xffc1; + +static void print_current_counters(void) +{ + *CounterLatch = 0; /* latch values */ + + *CounterSelect = 0x00; + printf("clock cycles ............... : %08lx %08lx\n", CounterValue[1], CounterValue[0]); + *CounterSelect = 0x01; + printf("instructions ............... : %08lx %08lx\n", CounterValue[1], CounterValue[0]); + *CounterSelect = 0x80; + printf("wallclock time ............. : %08lx %08lx\n", CounterValue[1], CounterValue[0]); + *CounterSelect = 0x81; + printf("wallclock time, split ...... : %08lx %08lx\n", CounterValue[1], CounterValue[0]); + printf("\n"); +} + +int main(void) +{ + print_current_counters(); + print_current_counters(); + return 0; +} +</verb></tscreen> + <sect>Copyright<p> sim65 (and all cc65 binutils) are (C) Copyright 1998-2000 Ullrich von From b2851be34099b9c3137e5df6fe722a84e47c63e4 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Tue, 31 Dec 2024 18:20:11 +0100 Subject: [PATCH 364/707] Fixed several typos. --- doc/sim65.sgml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 849d6c65c..2b99a6682 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -246,7 +246,7 @@ running. For each counter, it also provides a 64 bit "latching" register. <p>When a program explicitly requests a "counter latch" operation by writing any value to the <tt>PERIPHERALS_COUNTER_LATCH</tt> address ($FFC0), all live registers are simultaneously -copied to the latch registers. They will keep the newly latched value until another latch +copied to the latch registers. They will keep their newly latched values until another latch operation is requested. <p>The <tt>PERIPHERALS_COUNTER_SELECT</tt> address ($FFC1) register holds an 8-bit value that @@ -259,7 +259,7 @@ address range. Six values are currently defined: <item>$02: latched IRQ interrupt counter selected. <item>$03: latched NMI interrupt counter selected. <item>$80: latched wallclock time (nanoseconds) selected. -<item>$81: latched wallclock time (split s/ns) selected. +<item>$81: latched wallclock time (split: seconds, nanoseconds) selected. </itemize> <p>Values $00 to $03 provide access to the latched (frozen) value of their respective live @@ -276,12 +276,13 @@ Jan 1st, 1970 UTC, at the time of the last latch operation. The low 32 bits of <p>The two different wallclock-time latch registers will always refer to precisely the same time instant. For some applications, the single 64-bit value measured in nanoseconds will be more convenient, while -for other applications, the split 32/32 bits representations with separate second and nanosecond +for other applications, the split 32/32 bits representation with separate second and nanosecond values will be more convenient. <p>Note that the definition above, with time elapsed measured since Midnight, Jan 1st, 1970 UTC, is -an approximation, as the implementation depends on the way POSIX definition time, and POSIX does -not account for leap seconds; it falsely assumes that all days are precisely 86400 seconds long. +an approximation, as the implementation depends on the way POSIX definition time. Unfortunately, +POSIX does not account for leap seconds; it incorrectly assumes that all days are precisely 86400 seconds +long. <p>On reset, <tt>PERIPHERALS_COUNTER_SELECT</tt> is initialized to zero. If the <tt>PERIPHERALS_COUNTER_SELECT</tt> register holds a value other than one of the six values described above, all <tt>PERIPHERALS_COUNTER_VALUE</tt> @@ -302,7 +303,7 @@ Example: volatile uint8_t * CounterLatch = (uint8_t *)0xffc0; volatile uint8_t * CounterSelect = (uint8_t *)0xffc1; -volatile uint32_t * CounterValue = (uint32_t *)0xffc1; +volatile uint32_t * CounterValue = (uint32_t *)0xffc2; static void print_current_counters(void) { From a8581d042f31aef6fc3c38f2d4b82255dd327285 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Tue, 31 Dec 2024 18:32:11 +0100 Subject: [PATCH 365/707] Improved description. --- doc/sim65.sgml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 2b99a6682..9f2914254 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -265,13 +265,13 @@ address range. Six values are currently defined: <p>Values $00 to $03 provide access to the latched (frozen) value of their respective live counters at the time of the last write to <tt>PERIPHERALS_COUNTER_LATCH</tt>. -<p>When <tt>PERIPHERALS_COUNTER_LATCH</tt> equals $80, the <tt>PERIPHERALS_COUNTER_VALUE</tt> -will be a 64-bit value corresponding to the number of nanoseconds elapsed since Midnight, Jan 1st, -1970 UTC, at the time of the last latch operation. +<p>When <tt>PERIPHERALS_COUNTER_SELECT</tt> equals $80, the <tt>PERIPHERALS_COUNTER_VALUE</tt> +will be a 64-bit value corresponding to the number of nanoseconds elapsed since the Unix epoch +(Midnight, Jan 1st, 1970 UTC), at the time of the last latch operation. -<p>When <tt>PERIPHERALS_COUNTER_LATCH</tt> equals $81, the high 32 bits of <tt>PERIPHERALS_COUNTER_VALUE</tt> -will be a 32-bit value corresponding to the number of seconds elapsed since Midnight, -Jan 1st, 1970 UTC, at the time of the last latch operation. The low 32 bits of +<p>When <tt>PERIPHERALS_COUNTER_SELECT</tt> equals $81, the high 32 bits of <tt>PERIPHERALS_COUNTER_VALUE</tt> +will be a 32-bit value corresponding to the number of seconds elapsed since the Unix epoch (Midnight, Jan 1st, +1970 UTC), at the time of the last latch operation. The low 32 bits of <tt>PERIPHERALS_COUNTER_VALUE</tt> will hold the nanoseconds since the start of that second. <p>The two different wallclock-time latch registers will always refer to precisely the same time instant. @@ -279,10 +279,10 @@ For some applications, the single 64-bit value measured in nanoseconds will be m for other applications, the split 32/32 bits representation with separate second and nanosecond values will be more convenient. -<p>Note that the definition above, with time elapsed measured since Midnight, Jan 1st, 1970 UTC, is -an approximation, as the implementation depends on the way POSIX definition time. Unfortunately, -POSIX does not account for leap seconds; it incorrectly assumes that all days are precisely 86400 seconds -long. +<p>Note that the time elapsed since the Unix epoch is an approximation, as the implementation depends on the +way POSIX defines time-since-the-epoch. Unfortunately, POSIX incorrectly assumes that all days are precisely +86400 seconds long, which is not true in case of leap seconds. The way this inconsistency is resolved is +system dependent. <p>On reset, <tt>PERIPHERALS_COUNTER_SELECT</tt> is initialized to zero. If the <tt>PERIPHERALS_COUNTER_SELECT</tt> register holds a value other than one of the six values described above, all <tt>PERIPHERALS_COUNTER_VALUE</tt> From ef18d2cdd97c3c631acf05c30f7ad13ea48e4352 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Wed, 1 Jan 2025 08:28:17 +0100 Subject: [PATCH 366/707] Added code path for for MinGW32 builds that happen during snapshot builds, but not during PR builds. --- src/sim65/peripherals.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 4fa512ed8..cc5274f67 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -63,7 +63,22 @@ static bool GetWallclockTime (struct timespec * ts) #if defined(__MINGW64__) /* When using the MinGW64 compiler, neither timespec_get() nor clock_gettime() - * are available; using either of them makes the Linux workflow build fail. + * are available; using either of them makes the Linux PR build workflow build fail. + * The gettimeofday() function does work, so use that; its microsecond resolution + * is fine for most applications. + */ + struct timeval tv; + time_valid = (gettimeofday(&tv, NULL) == 0); + if (time_valid) { + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; + } +#elif defined(__MINGW32__) + /* Note: we test for MinGW32 after the test for MinGW64, as the __MINGW32__ symbol is also + * defined in MinGW64. This allows us to distinguish MinGW32 and MinGW64 build. + * + * When using the MinGW32 compiler, neither timespec_get() nor clock_gettime() + * are available; using either of them makes the Linux snapshot workflow build fail. * The gettimeofday() function does work, so use that; its microsecond resolution * is fine for most applications. */ From 66594d44a56b72dcb4ebc3adde853d5fff5d03e3 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Wed, 1 Jan 2025 08:58:51 +0100 Subject: [PATCH 367/707] Forget to include sys/time.h which is needed for MingGW32 builds. --- src/sim65/peripherals.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 4fa512ed8..4f105d87a 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -30,7 +30,7 @@ #include <stdbool.h> #include <time.h> -#if defined(__MINGW64__) +#if defined(__MINGW64__) || defined(__MINGW32__) /* For gettimeofday() */ #include <sys/time.h> #endif @@ -63,7 +63,22 @@ static bool GetWallclockTime (struct timespec * ts) #if defined(__MINGW64__) /* When using the MinGW64 compiler, neither timespec_get() nor clock_gettime() - * are available; using either of them makes the Linux workflow build fail. + * are available; using either of them makes the Linux PR build workflow build fail. + * The gettimeofday() function does work, so use that; its microsecond resolution + * is fine for most applications. + */ + struct timeval tv; + time_valid = (gettimeofday(&tv, NULL) == 0); + if (time_valid) { + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; + } +#elif defined(__MINGW32__) + /* Note: we test for MinGW32 after the test for MinGW64, as the __MINGW32__ symbol is also + * defined in MinGW64. This allows us to distinguish MinGW32 and MinGW64 build. + * + * When using the MinGW32 compiler, neither timespec_get() nor clock_gettime() + * are available; using either of them makes the Linux snapshot workflow build fail. * The gettimeofday() function does work, so use that; its microsecond resolution * is fine for most applications. */ From 50cccc2c3a8f864cd354caf703bc3483718ebadf Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Wed, 1 Jan 2025 13:23:03 +0100 Subject: [PATCH 368/707] Add lseek to sim6502 paravirt --- libsrc/sim6502/paravirt.s | 3 +- src/sim65/paravirt.c | 25 ++++++++++++++ src/sim65/paravirt.h | 2 +- test/ref/test_fseek.c | 73 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 test/ref/test_fseek.c diff --git a/libsrc/sim6502/paravirt.s b/libsrc/sim6502/paravirt.s index 3bd40fbe4..b9fc38de5 100644 --- a/libsrc/sim6502/paravirt.s +++ b/libsrc/sim6502/paravirt.s @@ -7,9 +7,10 @@ ; int __fastcall__ write (int fd, const void* buf, unsigned count); ; - .export exit, args, _open, _close, _read, _write + .export exit, args, _open, _close, _read, _write, _lseek .export __sysremove, ___osmaperrno +_lseek := $FFF1 __sysremove := $FFF2 ___osmaperrno := $FFF3 _open := $FFF4 diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 141bcd2bd..4e68a3f0e 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -159,6 +159,30 @@ static void PVArgs (CPURegs* Regs) SetAX (Regs, ArgC); } +/* Match between standard POSIX whence and cc65 whence. */ +static unsigned SEEK_MODE_MATCH[3] = { + SEEK_CUR, + SEEK_END, + SEEK_SET +}; + +static void PVLseek (CPURegs* Regs) +{ + unsigned RetVal; + + unsigned Whence = GetAX (Regs); + unsigned Offset = PopParam (4); + unsigned FD = PopParam (2); + + Print (stderr, 2, "PVLseek ($%04X, $%08X, $%04X (%d))\n", + FD, Offset, Whence, SEEK_MODE_MATCH[Whence]); + + RetVal = lseek(FD, (off_t)Offset, SEEK_MODE_MATCH[Whence]); + Print (stderr, 2, "PVLseek returned %04X\n", RetVal); + + SetAX (Regs, RetVal); +} + static void PVOpen (CPURegs* Regs) @@ -343,6 +367,7 @@ static void PVOSMapErrno (CPURegs* Regs) static const PVFunc Hooks[] = { + PVLseek, PVSysRemove, PVOSMapErrno, PVOpen, diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index f3281705e..109fdb847 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -44,7 +44,7 @@ -#define PARAVIRT_BASE 0xFFF2 +#define PARAVIRT_BASE 0xFFF1 /* Lowest address used by a paravirtualization hook */ #define PV_PATH_SIZE 1024 diff --git a/test/ref/test_fseek.c b/test/ref/test_fseek.c new file mode 100644 index 000000000..e63dc0c02 --- /dev/null +++ b/test/ref/test_fseek.c @@ -0,0 +1,73 @@ +/* + !!DESCRIPTION!! fgets test + !!LICENCE!! Public domain +*/ + +#include "common.h" + +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +FILE *in; +char bufA[32]; +char bufB[32]; + +#define INFILE "cf.in" + +int main(int argc,char **argv) +{ + static int r; + + in = fopen(INFILE, "rb"); + if (in == NULL) { + return EXIT_FAILURE; + } + + r = fread(bufA, 1, sizeof(bufA), in); + + if (r == 0) { + printf("Error: could not read.\n"); + return EXIT_FAILURE; + } + fwrite(bufA, 1, r, stdout); + + /* Test SEEK_SET */ + fseek(in, 0, SEEK_SET); + r = fread(bufB, 1, sizeof(bufB), in); + + if (r == 0) { + printf("Error: could not re-read after SEEK_SET.\n"); + return EXIT_FAILURE; + } + fwrite(bufB, 1, r, stdout); + + if (memcmp(bufA, bufB, sizeof(bufA))) { + printf("reads differ.\n"); + return EXIT_FAILURE; + } + + /* Test SEEK_CUR */ + fseek(in, 0, SEEK_SET); + fseek(in, 1, SEEK_CUR); + r = fread(bufB, 1, sizeof(bufB), in); + + if (r == 0) { + printf("Error: could not re-read after SEEK_CUR.\n"); + return EXIT_FAILURE; + } + fwrite(bufB, 1, r, stdout); + + if (memcmp(bufA+1, bufB, sizeof(bufA)-1)) { + printf("reads differ.\n"); + return EXIT_FAILURE; + } + + + fclose(in); + + return 0; +} From 5531320b5123c7632ce50829b30420f791605ecb Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Wed, 1 Jan 2025 13:23:30 +0100 Subject: [PATCH 369/707] Fix test_fread return value on error --- test/ref/test_fread.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/ref/test_fread.c b/test/ref/test_fread.c index 5d180d723..cf7083760 100644 --- a/test/ref/test_fread.c +++ b/test/ref/test_fread.c @@ -51,6 +51,7 @@ int main(int argc,char **argv) if (r == 0) { printf("Error: could not start reading.\n"); + return EXIT_FAILURE; } fwrite(buf, 1, r, stdout); @@ -63,6 +64,7 @@ int main(int argc,char **argv) if (!feof(in)) { printf("We should have EOF!\n"); + return EXIT_FAILURE; } fclose(in); From adfb42bfa6baaa8c4190a162339d406e928b432a Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Wed, 1 Jan 2025 13:23:57 +0100 Subject: [PATCH 370/707] Rewrite rewind in assembly --- libsrc/common/rewind.c | 25 ------------------- libsrc/common/rewind.s | 35 ++++++++++++++++++++++++++ test/ref/test_rewind.c | 56 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 25 deletions(-) delete mode 100644 libsrc/common/rewind.c create mode 100644 libsrc/common/rewind.s create mode 100644 test/ref/test_rewind.c diff --git a/libsrc/common/rewind.c b/libsrc/common/rewind.c deleted file mode 100644 index 333230b74..000000000 --- a/libsrc/common/rewind.c +++ /dev/null @@ -1,25 +0,0 @@ -/* -** rewind.c -** -** Christian Groessler, 07-Aug-2000 -*/ - - - -#include <stdio.h> - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -void __fastcall__ rewind (FILE* f) -{ - fseek(f, 0L, SEEK_SET); - clearerr(f); -} - - diff --git a/libsrc/common/rewind.s b/libsrc/common/rewind.s new file mode 100644 index 000000000..e7013505c --- /dev/null +++ b/libsrc/common/rewind.s @@ -0,0 +1,35 @@ +; +; Colin Leroy-Mira <colin@colino.net> +; +; void __fastcall__ rewind (FILE* f) +; /* Rewind a file */ +; + + .export _rewind + + .import _fseek, _clearerr + .import pushax, pushl0, popax + + .include "stdio.inc" + + +; ------------------------------------------------------------------------ +; Code + +.proc _rewind + + ; Push f twice (once for fseek, once for clearerr later) + jsr pushax + jsr pushax + + ; Push offset (long) zero + jsr pushl0 + + lda #SEEK_SET + jsr _fseek + + ; Clear error + jsr popax + jmp _clearerr + +.endproc diff --git a/test/ref/test_rewind.c b/test/ref/test_rewind.c new file mode 100644 index 000000000..80fe08ce1 --- /dev/null +++ b/test/ref/test_rewind.c @@ -0,0 +1,56 @@ +/* + !!DESCRIPTION!! fgets test + !!LICENCE!! Public domain +*/ + +#include "common.h" + +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +FILE *in; +char bufA[32]; +char bufB[32]; + +#define INFILE "cf.in" + +int main(int argc,char **argv) +{ + static int r; + + in = fopen(INFILE, "rb"); + if (in == NULL) { + return EXIT_FAILURE; + } + + r = fread(bufA, 1, sizeof(bufA), in); + + if (r == 0) { + printf("Error: could not read.\n"); + return EXIT_FAILURE; + } + fwrite(bufA, 1, r, stdout); + + rewind(in); + printf("rewind.\n"); + r = fread(bufB, 1, sizeof(bufB), in); + + if (r == 0) { + printf("Error: could not re-read.\n"); + return EXIT_FAILURE; + } + fwrite(bufB, 1, r, stdout); + + fclose(in); + + if (memcmp(bufA, bufB, sizeof(bufA))) { + printf("reads differ.\n"); + return EXIT_FAILURE; + } + + return 0; +} From 21345bd6da1730b47f22c94da666b5d8d350ce5a Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Wed, 1 Jan 2025 13:25:52 +0100 Subject: [PATCH 371/707] Fix headers --- test/ref/test_fread.c | 2 +- test/ref/test_fseek.c | 2 +- test/ref/test_rewind.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/ref/test_fread.c b/test/ref/test_fread.c index cf7083760..99411ab28 100644 --- a/test/ref/test_fread.c +++ b/test/ref/test_fread.c @@ -1,5 +1,5 @@ /* - !!DESCRIPTION!! fgets test + !!DESCRIPTION!! fread test !!LICENCE!! Public domain */ diff --git a/test/ref/test_fseek.c b/test/ref/test_fseek.c index e63dc0c02..157d0bdf0 100644 --- a/test/ref/test_fseek.c +++ b/test/ref/test_fseek.c @@ -1,5 +1,5 @@ /* - !!DESCRIPTION!! fgets test + !!DESCRIPTION!! fseek test !!LICENCE!! Public domain */ diff --git a/test/ref/test_rewind.c b/test/ref/test_rewind.c index 80fe08ce1..d1b361983 100644 --- a/test/ref/test_rewind.c +++ b/test/ref/test_rewind.c @@ -1,5 +1,5 @@ /* - !!DESCRIPTION!! fgets test + !!DESCRIPTION!! rewind test !!LICENCE!! Public domain */ From 3047439174bec1d0de79b7c99624e5253e55d647 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 1 Jan 2025 18:26:11 +0100 Subject: [PATCH 372/707] Fixed typo --- doc/da65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index 113eb6f97..94fbfbd29 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -255,7 +255,7 @@ disassembler may be told to recognize either the 65SC02 or 65C02 CPUs. The latter understands the same opcodes as the former, plus 16 additional bit manipulation and bit test-and-branch commands. Using 6502x as CPU the illegal opcodes of 6502 CPU are detected and displayed. 6502dtv setting recognizes the -emulated CPU instructons of the C64DTV device. +emulated CPU instructions of the C64DTV device. When disassembling 4510 code, due to handling of 16-bit wide branches, da65 From 0d8cbbc38b6c99e91f804f0a2b2df95a3a0054c7 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 1 Jan 2025 18:30:23 +0100 Subject: [PATCH 373/707] Fixed typos --- doc/funcref.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index f2dd02efc..bc2424272 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -2436,7 +2436,7 @@ the address must first be ORed with $60. <tag/Availability/cc65 <tag/See also/ <ref id="cbm_k_listen" name="cbm_k_listen"> -<tag/Exampe/None. +<tag/Example/None. </descrip> </quote> @@ -7315,7 +7315,7 @@ if (stat (FILENAME, &stbuf) == 0) { <tag/Function/Get filesystem statistics. <tag/Header/<tt/<ref id="sys/statvfs.h" name="sys/statvfs.h">/ <tag/Declaration/<tt/int __fastcall__ statvfs (const char* pathname, struct statvfs* buf);/ -<tag/Description/<tt/statvfs/ gets information for the filesytem on which the given file +<tag/Description/<tt/statvfs/ gets information for the filesystem on which the given file resides. On success, zero is returned. On error, -1 is returned and <tt/errno/ is set to an error code describing the reason for the failure. From bf8b8343177ecec6ea64b398b1b155d204c5ef3b Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 1 Jan 2025 18:31:57 +0100 Subject: [PATCH 374/707] Fixed typo --- doc/tgi.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index 29acd8ce6..3b013664f 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -477,10 +477,10 @@ be used in presence of a prototype. <quote> <descrip> -<tag/Function/Get number of horisontal pixels on the screen. +<tag/Function/Get number of horizontal pixels on the screen. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/unsigned tgi_getxres (void);/ -<tag/Description/Get number of horisontal pixels on the screen. +<tag/Description/Get number of horizontal pixels on the screen. This is same as tgi_maxx()+1. <tag/Availability/cc65 <tag/See also/Other tgi functions. From 5be0b10b62c4d95389c7a1caeb66a0ddebf47f0d Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Fri, 3 Jan 2025 21:39:20 +0100 Subject: [PATCH 375/707] sim65: add tracing, and a sim65 control peripheral for sim65 runtime control. This PR is the first of two PRs that replaces earlier PRs #2589 and #2590. Due to a git branching mishap it was decided to re-partition the new functionality in two sequential PRs that offer self-contained, new functionality to sim65. The functionality in this first PR extends the sim65 simulator in the following ways: (1) It provides tracing functionality, i.e., the possibility of printing one line of simulator state information per instruction executed. (2) It provides a memory mapped "sim65 control" peripheral that allows control of (a) the tracing functionality, and (b) the cpu mode. (3) It provides command-line options to sim65 to enable the tracing, and to override the CPU mode as specified in the program file header. More detailed information and some discussion can be found in the discussions with the (now retracted) PRs #2589 and #2590. This PR provides the technical infrastructure inside the sim65 simulator program itself. Once this PR is accepted, a follow-up PR will be posted that adds C and assembly-language support for the new tracing and peripheral features so they can be easily accessed from the CC65 compiler and the CA65 assembler; some examples; and the documentation for these features. The lack of the latter, in this pull request, will be addressed then. --- src/sim65.vcxproj | 2 + src/sim65/6502.c | 27 +- src/sim65/6502.h | 6 +- src/sim65/main.c | 98 +++- src/sim65/paravirt.h | 3 +- src/sim65/peripherals.c | 26 + src/sim65/peripherals.h | 13 +- src/sim65/trace.c | 1157 +++++++++++++++++++++++++++++++++++++++ src/sim65/trace.h | 89 +++ 9 files changed, 1389 insertions(+), 32 deletions(-) create mode 100644 src/sim65/trace.c create mode 100644 src/sim65/trace.h diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj index 07a9f7fb5..f1fe6bdd2 100644 --- a/src/sim65.vcxproj +++ b/src/sim65.vcxproj @@ -87,6 +87,7 @@ <ClInclude Include="sim65\memory.h" /> <ClInclude Include="sim65\paravirt.h" /> <ClInclude Include="sim65\peripherals.h" /> + <ClInclude Include="sim65\trace.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="sim65\6502.c" /> @@ -95,6 +96,7 @@ <ClCompile Include="sim65\memory.c" /> <ClCompile Include="sim65\paravirt.c" /> <ClCompile Include="sim65\peripherals.c" /> + <ClCompile Include="sim65\trace.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> diff --git a/src/sim65/6502.c b/src/sim65/6502.c index be5afc036..a9aa299ff 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -42,14 +42,16 @@ * the WAI ($CB) and STP ($DB) instructions are unsupported. */ -#include <stdbool.h> #include <stdint.h> +#include <stdbool.h> #include "memory.h" #include "peripherals.h" #include "error.h" -#include "6502.h" #include "paravirt.h" +#include "trace.h" + +#include "6502.h" /* @@ -4485,7 +4487,7 @@ static const OPFunc OP65C02Table[256] = { OPC_6502_41, OPC_65C02_NOP22, // $42 OPC_65C02_NOP11, // $43 - OPC_6502X_44, // $44 + OPC_6502X_44, // $44 OPC_6502_45, OPC_6502_46, OPC_65C02_47, @@ -4730,6 +4732,10 @@ unsigned ExecuteInsn (void) /* If we have an NMI request, handle it */ if (HaveNMIRequest) { + if (TraceMode != TRACE_DISABLED) { + PrintTraceNMI (); + } + HaveNMIRequest = false; Peripherals.Counter.NmiEvents += 1; @@ -4746,6 +4752,10 @@ unsigned ExecuteInsn (void) } else if (HaveIRQRequest && GET_IF () == 0) { + if (TraceMode != TRACE_DISABLED) { + PrintTraceIRQ (); + } + HaveIRQRequest = false; Peripherals.Counter.IrqEvents += 1; @@ -4765,11 +4775,16 @@ unsigned ExecuteInsn (void) /* Normal instruction - read the next opcode */ uint8_t OPC = MemReadByte (Regs.PC); - /* Execute it */ - Handlers[CPU][OPC] (); + /* Print a trace line, if trace mode is enabled. */ + if (TraceMode != TRACE_DISABLED) { + PrintTraceInstruction (); + } - /* Increment the instruction counter by one.NMIs and IRQs are counted separately. */ + /* Increment the instruction counter by one. */ Peripherals.Counter.CpuInstructions += 1; + + /* Execute the instruction. The handler sets the 'Cycles' variable. */ + Handlers[CPU][OPC] (); } /* Increment the 64-bit clock cycle counter with the cycle count for the instruction that we just executed. */ diff --git a/src/sim65/6502.h b/src/sim65/6502.h index 0f4d066d0..d715f3288 100644 --- a/src/sim65/6502.h +++ b/src/sim65/6502.h @@ -48,9 +48,9 @@ /* Supported CPUs */ typedef enum CPUType { - CPU_6502, - CPU_65C02, - CPU_6502X + CPU_6502 = 0, + CPU_65C02 = 1, + CPU_6502X = 2 } CPUType; /* Current CPU */ diff --git a/src/sim65/main.c b/src/sim65/main.c index 8b41fcc0f..828ea498e 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -35,6 +35,7 @@ #include <string.h> #include <stdlib.h> +#include <stdbool.h> #include <errno.h> /* common */ @@ -49,6 +50,7 @@ #include "memory.h" #include "peripherals.h" #include "paravirt.h" +#include "trace.h" @@ -61,6 +63,9 @@ /* Name of program file */ const char* ProgramFile; +/* Set to True if CPU mode override is in effect. If set, the CPU is not read from the program file. */ +static bool CPUOverrideActive = false; + /* exit simulator after MaxCycles Cccles */ unsigned long long MaxCycles = 0; @@ -95,6 +100,8 @@ static void Usage (void) "Long options:\n" " --help\t\tHelp (this text)\n" " --cycles\t\tPrint amount of executed CPU cycles\n" + " --cpu <type>\t\tOverride CPU type (6502, 65C02, 6502X)\n" + " --trace\t\tEnable CPU trace\n" " --verbose\t\tIncrease verbosity\n" " --version\t\tPrint the simulator version number\n", ProgName); @@ -112,6 +119,35 @@ static void OptHelp (const char* Opt attribute ((unused)), +static void OptCPU (const char* Opt, const char* Arg) +/* Set CPU type */ +{ + /* Don't use FindCPU here. Enum constants would clash. */ + if (strcmp(Arg, "6502") == 0) { + CPU = CPU_6502; + CPUOverrideActive = true; + } else if (strcmp(Arg, "65C02") == 0 || strcmp(Arg, "65c02") == 0) { + CPU = CPU_65C02; + CPUOverrideActive = true; + } else if (strcmp(Arg, "6502X") == 0 || strcmp(Arg, "6502x") == 0) { + CPU = CPU_6502X; + CPUOverrideActive = true; + } else { + AbEnd ("Invalid argument for %s: '%s'", Opt, Arg); + } +} + + + +static void OptTrace (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Enable trace mode */ +{ + TraceMode = TRACE_ENABLE_FULL; /* Enable full trace mode. */ +} + + + static void OptVerbose (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Increase verbosity */ @@ -135,16 +171,20 @@ static void OptVersion (const char* Opt attribute ((unused)), /* Print the simulator version */ { fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); - exit(EXIT_SUCCESS); + exit (EXIT_SUCCESS); } + + static void OptQuitXIns (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) -/* quit after MaxCycles cycles */ + const char* Arg) +/* Quit after MaxCycles cycles */ { MaxCycles = strtoull(Arg, NULL, 0); } + + static unsigned char ReadProgramFile (void) /* Load program into memory */ { @@ -173,17 +213,20 @@ static unsigned char ReadProgramFile (void) Error ("'%s': Invalid header version.", ProgramFile); } - /* Get the CPU type from the file header */ + /* Get the CPU type from the file header. + * Use it to set the CPU type, unless CPUOverrideActive is set. + */ if ((Val = fgetc(F)) != EOF) { - switch (Val) { - case CPU_6502: - case CPU_65C02: - case CPU_6502X: - CPU = Val; - break; - - default: - Error ("'%s': Invalid CPU type", ProgramFile); + if (!CPUOverrideActive) { + switch (Val) { + case CPU_6502: + case CPU_65C02: + case CPU_6502X: + CPU = Val; + break; + default: + Error ("'%s': Invalid CPU type", ProgramFile); + } } } @@ -238,16 +281,22 @@ int main (int argc, char* argv[]) { /* Program long options */ static const LongOpt OptTab[] = { - { "--help", 0, OptHelp }, - { "--cycles", 0, OptCycles }, - { "--verbose", 0, OptVerbose }, - { "--version", 0, OptVersion }, + { "--help", 0, OptHelp }, + { "--cycles", 0, OptCycles }, + { "--cpu", 1, OptCPU }, + { "--trace", 0, OptTrace }, + { "--verbose", 0, OptVerbose }, + { "--version", 0, OptVersion }, }; unsigned I; unsigned char SPAddr; unsigned int Cycles; + /* Set reasonable defaults. */ + CPU = CPU_6502; + TraceMode = TRACE_DISABLED; /* Disabled by default */ + /* Initialize the cmdline module */ InitCmdLine (&argc, &argv, "sim65"); @@ -302,16 +351,29 @@ int main (int argc, char* argv[]) } /* Do we have a program file? */ - if (ProgramFile == 0) { + if (ProgramFile == NULL) { AbEnd ("No program file"); } + /* Reset memory */ MemInit (); + + /* Reset peripherals. */ PeripheralsInit (); + /* Read program file into memory. + * This also sets the CPU type, unless a CPU override is in effect. + */ SPAddr = ReadProgramFile (); + + /* Initialize the paravirtualization subsystem. It requires the stack pointer address, to be able to + * simulate 6502 subroutine calls. + */ + + TraceInit(SPAddr); ParaVirtInit (I, SPAddr); + /* Reset the CPU */ Reset (); RemainCycles = MaxCycles; diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index f3281705e..f5d74acc8 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -32,11 +32,12 @@ /*****************************************************************************/ - #ifndef PARAVIRT_H #define PARAVIRT_H +#include "6502.h" + /*****************************************************************************/ /* Data */ diff --git a/src/sim65/peripherals.c b/src/sim65/peripherals.c index 4f105d87a..1d7ff6bdb 100644 --- a/src/sim65/peripherals.c +++ b/src/sim65/peripherals.c @@ -37,6 +37,8 @@ #include "peripherals.h" +#include "trace.h" +#include "6502.h" /*****************************************************************************/ @@ -146,6 +148,20 @@ void PeripheralsWriteByte (uint8_t Addr, uint8_t Val) break; } + /* Handle writes to the SimControl peripheral. */ + + case PERIPHERALS_SIMCONTROL_ADDRESS_OFFSET_CPUMODE: { + if (Val == CPU_6502 || Val == CPU_65C02 || Val == CPU_6502X) { + CPU = Val; + } + break; + } + + case PERIPHERALS_SIMCONTROL_ADDRESS_OFFSET_TRACEMODE: { + TraceMode = Val; + break; + } + /* Handle writes to unused and read-only peripheral addresses. */ default: { @@ -192,6 +208,16 @@ uint8_t PeripheralsReadByte (uint8_t Addr) return (uint8_t)(Value >> (SelectedByteIndex * 8)); } + /* Handle reads from the SimControl peripheral. */ + + case PERIPHERALS_SIMCONTROL_ADDRESS_OFFSET_CPUMODE: { + return CPU; + } + + case PERIPHERALS_SIMCONTROL_ADDRESS_OFFSET_TRACEMODE: { + return TraceMode; + } + /* Handle reads from unused peripheral and write-only addresses. */ default: { diff --git a/src/sim65/peripherals.h b/src/sim65/peripherals.h index 16ea83782..dc86e6c6e 100644 --- a/src/sim65/peripherals.h +++ b/src/sim65/peripherals.h @@ -38,9 +38,9 @@ /* The memory range where the memory-mapped peripherals can be accessed. */ #define PERIPHERALS_APERTURE_BASE_ADDRESS 0xffc0 -#define PERIPHERALS_APERTURE_LAST_ADDRESS 0xffc9 +#define PERIPHERALS_APERTURE_LAST_ADDRESS 0xffcb -/* Declarations for the COUNTER peripheral (currently the only peripheral). */ +/* Declarations for the COUNTER peripheral */ #define PERIPHERALS_COUNTER_ADDRESS_OFFSET_LATCH 0x00 #define PERIPHERALS_COUNTER_ADDRESS_OFFSET_SELECT 0x01 @@ -84,13 +84,18 @@ typedef struct { uint8_t LatchedValueSelected; } CounterPeripheral; +/* Declarations for the SIMCONTROL peripheral. */ +#define PERIPHERALS_SIMCONTROL_ADDRESS_OFFSET_CPUMODE 0x0A +#define PERIPHERALS_SIMCONTROL_ADDRESS_OFFSET_TRACEMODE 0x0B + +#define PERIPHERALS_SIMCONTROL_CPUMODE (PERIPHERALS_APERTURE_BASE_ADDRESS + PERIPHERALS_SIMCONTROL_ADDRESS_OFFSET_CPUMODE) +#define PERIPHERALS_SIMCONTROL_TRACEMODE (PERIPHERALS_APERTURE_BASE_ADDRESS + PERIPHERALS_SIMCONTROL_ADDRESS_OFFSET_TRACEMODE) /* Declare the 'Sim65Peripherals' type and its single instance 'Peripherals'. */ typedef struct { - /* State of the peripherals available in sim65. - * Currently, there is only one peripheral: the Counter. */ + /* State of the peripherals available in sim65. */ CounterPeripheral Counter; } Sim65Peripherals; diff --git a/src/sim65/trace.c b/src/sim65/trace.c new file mode 100644 index 000000000..ef1edd0bf --- /dev/null +++ b/src/sim65/trace.c @@ -0,0 +1,1157 @@ +/*****************************************************************************/ +/* */ +/* trace.c */ +/* */ +/* Instruction tracing functionality sim65 6502 simulator */ +/* */ +/* */ +/* */ +/* (C) 2025, Sidney Cadot */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <inttypes.h> + +#include "6502.h" +#include "memory.h" +#include "trace.h" +#include "peripherals.h" + +/* Current Trace Mode. Tracing is off by default, and needs to be explicitly enabled. */ +uint8_t TraceMode = TRACE_DISABLED; + +/* CC65 stack pointer */ +uint8_t StackPointerZPageAddress; + +/* 6502, 65C02 addressing modes. */ +typedef enum { + ILLEGAL, + IMPLIED, + ACCUMULATOR, + IMMEDIATE, + REL, + ZP, + ZP_X, + ZP_Y, + ZP_IND, + ZP_X_IND, + ZP_IND_Y, + ZP_REL, + ABS, + ABS_X, + ABS_Y, + ABS_IND, + ABS_X_IND +} AddressingMode; + +/* Info for a specific opcode and addressing mode, for a specific CPU type. */ +typedef struct { + const char * mnemonic; + AddressingMode adrmode; +} InstructionInfo; + +/* Information for standard 6502 opcodes. */ +static InstructionInfo II_6502[256] = { + { "brk" , IMPLIED }, /* 0x00 to 0x0f */ + { "ora" , ZP_X_IND }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "ora" , ZP }, + { "asl" , ZP }, + { "???" , ILLEGAL }, + { "php" , IMPLIED }, + { "ora" , IMMEDIATE }, + { "asl" , ACCUMULATOR }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "ora" , ABS }, + { "asl" , ABS }, + { "???" , ILLEGAL }, + + { "bpl" , REL }, /* 0x10 to 0x1f */ + { "ora" , ZP_IND_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "ora" , ZP_X }, + { "asl" , ZP_X }, + { "???" , ILLEGAL }, + { "clc" , IMPLIED }, + { "ora" , ABS_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "ora" , ABS_X }, + { "asl" , ABS_X }, + { "???" , ILLEGAL }, + + { "jsr" , ABS }, /* 0x20 to 0x2f */ + { "and" , ZP_X_IND }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "bit" , ZP }, + { "and" , ZP }, + { "rol" , ZP }, + { "???" , ILLEGAL }, + { "plp" , IMPLIED }, + { "and" , IMMEDIATE }, + { "rol" , ACCUMULATOR }, + { "???" , ILLEGAL }, + { "bit" , ABS }, + { "and" , ABS }, + { "rol" , ABS }, + { "???" , ILLEGAL }, + + { "bmi" , REL }, /* 0x30 to 0x3f */ + { "and" , ZP_IND_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "and" , ZP_X }, + { "rol" , ZP_X }, + { "???" , ILLEGAL }, + { "sec" , IMPLIED }, + { "and" , ABS_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "and" , ABS_X }, + { "rol" , ABS_X }, + { "???" , ILLEGAL }, + + { "rti" , IMPLIED }, /* 0x40 to 0x4f */ + { "eor" , ZP_X_IND }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "eor" , ZP }, + { "lsr" , ZP }, + { "???" , ILLEGAL }, + { "pha" , IMPLIED }, + { "eor" , IMMEDIATE }, + { "lsr" , ACCUMULATOR }, + { "???" , ILLEGAL }, + { "jmp" , ABS }, + { "eor" , ABS }, + { "lsr" , ABS }, + { "???" , ILLEGAL }, + + { "bvc" , REL }, /* 0x50 to 0x5f */ + { "eor" , ZP_IND_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "eor" , ZP_X }, + { "lsr" , ZP_X }, + { "???" , ILLEGAL }, + { "cli" , IMPLIED }, + { "eor" , ABS_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "eor" , ABS_X }, + { "lsr" , ABS_X }, + { "???" , ILLEGAL }, + + { "rts" , IMPLIED }, /* 0x60 to 0x6f */ + { "adc" , ZP_X_IND }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "adc" , ZP }, + { "ror" , ZP }, + { "???" , ILLEGAL }, + { "pla" , IMPLIED }, + { "adc" , IMMEDIATE }, + { "ror" , ACCUMULATOR }, + { "???" , ILLEGAL }, + { "jmp" , ABS_IND }, + { "adc" , ABS }, + { "ror" , ABS }, + { "???" , ILLEGAL }, + + { "bvs" , REL }, /* 0x70 to 0x7f */ + { "adc" , ZP_IND_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "adc" , ZP_X }, + { "ror" , ZP_X }, + { "???" , ILLEGAL }, + { "sei" , IMPLIED }, + { "adc" , ABS_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "adc" , ABS_X }, + { "ror" , ABS_X }, + { "???" , ILLEGAL }, + + { "???" , ILLEGAL }, /* 0x80 to 0x8f */ + { "sta" , ZP_X_IND }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "sty" , ZP }, + { "sta" , ZP }, + { "stx" , ZP }, + { "???" , ILLEGAL }, + { "dey" , IMPLIED }, + { "???" , ILLEGAL }, + { "txa" , IMPLIED }, + { "???" , ILLEGAL }, + { "sty" , ABS }, + { "sta" , ABS }, + { "stx" , ABS }, + { "???" , ILLEGAL }, + + { "bcc" , REL }, /* 0x90 to 0x9f */ + { "sta" , ZP_IND_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "sty" , ZP_X }, + { "sta" , ZP_X }, + { "stx" , ZP_Y }, + { "???" , ILLEGAL }, + { "tya" , IMPLIED }, + { "sta" , ABS_Y }, + { "txs" , IMPLIED }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "sta" , ABS_X }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + + { "ldy" , IMMEDIATE }, /* 0xa0 to 0xaf */ + { "lda" , ZP_X_IND }, + { "ldx" , IMMEDIATE }, + { "???" , ILLEGAL }, + { "ldy" , ZP }, + { "lda" , ZP }, + { "ldx" , ZP }, + { "???" , ILLEGAL }, + { "tay" , IMPLIED }, + { "lda" , IMMEDIATE }, + { "tax" , IMPLIED }, + { "???" , ILLEGAL }, + { "ldy" , ABS }, + { "lda" , ABS }, + { "ldx" , ABS }, + { "???" , ILLEGAL }, + + { "bcs" , REL }, /* 0xb0 to 0xbf */ + { "lda" , ZP_IND_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "ldy" , ZP_X }, + { "lda" , ZP_X }, + { "ldx" , ZP_Y }, + { "???" , ILLEGAL }, + { "clv" , IMPLIED }, + { "lda" , ABS_Y }, + { "tsx" , IMPLIED }, + { "???" , ILLEGAL }, + { "ldy" , ABS_X }, + { "lda" , ABS_X }, + { "ldx" , ABS_Y }, + { "???" , ILLEGAL }, + + { "cpy" , IMMEDIATE }, /* 0xc0 to 0xcf */ + { "cmp" , ZP_X_IND }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "cpy" , ZP }, + { "cmp" , ZP }, + { "dec" , ZP }, + { "???" , ILLEGAL }, + { "iny" , IMPLIED }, + { "cmp" , IMMEDIATE }, + { "dex" , IMPLIED }, + { "???" , ILLEGAL }, + { "cpy" , ABS }, + { "cmp" , ABS }, + { "dec" , ABS }, + { "???" , ILLEGAL }, + + { "bne" , REL }, /* 0xd0 to 0xdf */ + { "cmp" , ZP_IND_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "cmp" , ZP_X }, + { "dec" , ZP_X }, + { "???" , ILLEGAL }, + { "cld" , IMPLIED }, + { "cmp" , ABS_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "cmp" , ABS_X }, + { "dec" , ABS_X }, + { "???" , ILLEGAL }, + + { "cpx" , IMMEDIATE }, /* 0xe0 to 0xef */ + { "sbc" , ZP_X_IND }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "cpx" , ZP }, + { "sbc" , ZP }, + { "inc" , ZP }, + { "???" , ILLEGAL }, + { "inx" , IMPLIED }, + { "sbc" , IMMEDIATE }, + { "nop" , IMPLIED }, + { "???" , ILLEGAL }, + { "cpx" , ABS }, + { "sbc" , ABS }, + { "inc" , ABS }, + { "???" , ILLEGAL }, + + { "beq" , REL }, /* 0xf0 to 0xff */ + { "sbc" , ZP_IND_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "sbc" , ZP_X }, + { "inc" , ZP_X }, + { "???" , ILLEGAL }, + { "sed" , IMPLIED }, + { "sbc" , ABS_Y }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "???" , ILLEGAL }, + { "sbc" , ABS_X }, + { "inc" , ABS_X }, + { "???" , ILLEGAL } +}; + +/* Information for 65C02 opcodes. */ +static InstructionInfo II_65C02[256] = { + { "brk" , IMPLIED }, /* 0x00 to 0x0f */ + { "ora" , ZP_X_IND }, + { "nop" , IMMEDIATE }, + { "nop" , IMPLIED }, + { "tsb" , ZP }, + { "ora" , ZP }, + { "asl" , ZP }, + { "rmb0" , ZP }, + { "php" , IMPLIED }, + { "ora" , IMMEDIATE }, + { "asl" , ACCUMULATOR }, + { "nop" , IMPLIED }, + { "tsb" , ABS }, + { "ora" , ABS }, + { "asl" , ABS }, + { "bbr0" , ZP_REL }, + + { "bpl" , REL }, /* 0x10 to 0x1f */ + { "ora" , ZP_IND_Y }, + { "ora" , ZP_IND }, + { "nop" , IMPLIED }, + { "trb" , ZP }, + { "ora" , ZP_X }, + { "asl" , ZP_X }, + { "rmb1" , ZP }, + { "clc" , IMPLIED }, + { "ora" , ABS_Y }, + { "inc" , ACCUMULATOR }, + { "nop" , IMPLIED }, + { "trb" , ABS }, + { "ora" , ABS_X }, + { "asl" , ABS_X }, + { "bbr1" , ZP_REL }, + + { "jsr" , ABS }, /* 0x20 to 0x2f */ + { "and" , ZP_X_IND }, + { "nop" , IMMEDIATE }, + { "nop" , IMPLIED }, + { "bit" , ZP }, + { "and" , ZP }, + { "rol" , ZP }, + { "rmb2" , ZP }, + { "plp" , IMPLIED }, + { "and" , IMMEDIATE }, + { "rol" , ACCUMULATOR }, + { "nop" , IMPLIED }, + { "bit" , ABS }, + { "and" , ABS }, + { "rol" , ABS }, + { "bbr2" , ZP_REL }, + + { "bmi" , REL }, /* 0x30 to 0x3f */ + { "and" , ZP_IND_Y }, + { "and" , ZP_IND }, + { "nop" , IMPLIED }, + { "bit" , ZP_X }, + { "and" , ZP_X }, + { "rol" , ZP_X }, + { "rmb3" , ZP }, + { "sec" , IMPLIED }, + { "and" , ABS_Y }, + { "dec" , ACCUMULATOR }, + { "nop" , IMPLIED }, + { "bit" , ABS_X }, + { "and" , ABS_X }, + { "rol" , ABS_X }, + { "bbr3" , ZP_REL }, + + { "rti" , IMPLIED }, /* 0x40 to 0x4f */ + { "eor" , ZP_X_IND }, + { "nop" , IMMEDIATE }, + { "nop" , ILLEGAL }, + { "nop" , ZP }, + { "eor" , ZP }, + { "lsr" , ZP }, + { "rmb4" , ZP }, + { "pha" , IMPLIED }, + { "eor" , IMMEDIATE }, + { "lsr" , ACCUMULATOR }, + { "nop" , IMPLIED }, + { "jmp" , ABS }, + { "eor" , ABS }, + { "lsr" , ABS }, + { "bbr4" , ZP_REL }, + + { "bvc" , REL }, /* 0x50 to 0x5f */ + { "eor" , ZP_IND_Y }, + { "eor" , ZP_IND }, + { "nop" , IMPLIED }, + { "nop" , ZP_X }, + { "eor" , ZP_X }, + { "lsr" , ZP_X }, + { "rmb5" , ZP }, + { "cli" , IMPLIED }, + { "eor" , ABS_Y }, + { "phy" , IMPLIED }, + { "nop" , IMPLIED }, + { "nop" , ABS }, + { "eor" , ABS_X }, + { "lsr" , ABS_X }, + { "bbr5" , ZP_REL }, + + { "rts" , IMPLIED }, /* 0x60 to 0x6f */ + { "adc" , ZP_X_IND }, + { "nop" , IMMEDIATE }, + { "nop" , IMPLIED }, + { "stz" , ZP }, + { "adc" , ZP }, + { "ror" , ZP }, + { "rmb6" , ZP }, + { "pla" , IMPLIED }, + { "adc" , IMMEDIATE }, + { "ror" , ACCUMULATOR }, + { "nop" , IMPLIED }, + { "jmp" , ABS_IND }, + { "adc" , ABS }, + { "ror" , ABS }, + { "bbr6" , ZP_REL }, + + { "bvs" , REL }, /* 0x70 to 0x7f */ + { "adc" , ZP_IND_Y }, + { "adc" , ZP_IND }, + { "nop" , IMPLIED }, + { "stz" , ZP_X }, + { "adc" , ZP_X }, + { "ror" , ZP_X }, + { "rmb7" , ZP }, + { "sei" , IMPLIED }, + { "adc" , ABS_Y }, + { "ply" , IMPLIED }, + { "nop" , IMPLIED }, + { "jmp" , ABS_X_IND }, + { "adc" , ABS_X }, + { "ror" , ABS_X }, + { "bbr7" , ZP_REL }, + + { "bra" , REL }, /* 0x80 to 0x8f */ + { "sta" , ZP_X_IND }, + { "nop" , IMMEDIATE }, + { "nop" , IMPLIED }, + { "sty" , ZP }, + { "sta" , ZP }, + { "stx" , ZP }, + { "smb0" , ZP }, + { "dey" , IMPLIED }, + { "bit" , IMMEDIATE }, + { "txa" , IMPLIED }, + { "nop" , IMPLIED }, + { "sty" , ABS }, + { "sta" , ABS }, + { "stx" , ABS }, + { "bbs0" , ZP_REL }, + + { "bcc" , REL }, /* 0x90 to 0x9f */ + { "sta" , ZP_IND_Y }, + { "sta" , ZP_IND }, + { "nop" , IMPLIED }, + { "sty" , ZP_X }, + { "sta" , ZP_X }, + { "stx" , ZP_Y }, + { "smb1" , ZP }, + { "tya" , IMPLIED }, + { "sta" , ABS_Y }, + { "txs" , IMPLIED }, + { "nop" , IMPLIED }, + { "stz" , ABS }, + { "sta" , ABS_X }, + { "stz" , ABS_X }, + { "bbs1" , ZP_REL }, + + { "ldy" , IMMEDIATE }, /* 0xa0 to 0xaf */ + { "lda" , ZP_X_IND }, + { "ldx" , IMMEDIATE }, + { "nop" , IMPLIED }, + { "ldy" , ZP }, + { "lda" , ZP }, + { "ldx" , ZP }, + { "smb2" , ZP }, + { "tay" , IMPLIED }, + { "lda" , IMMEDIATE }, + { "tax" , IMPLIED }, + { "nop" , IMPLIED }, + { "ldy" , ABS }, + { "lda" , ABS }, + { "ldx" , ABS }, + { "bbs2" , ZP_REL }, + + { "bcs" , REL }, /* 0xb0 to 0xbf */ + { "lda" , ZP_IND_Y }, + { "lda" , ZP_IND }, + { "nop" , IMPLIED }, + { "ldy" , ZP_X }, + { "lda" , ZP_X }, + { "ldx" , ZP_Y }, + { "smb3" , ZP }, + { "clv" , IMPLIED }, + { "lda" , ABS_Y }, + { "tsx" , IMPLIED }, + { "nop" , IMPLIED }, + { "ldy" , ABS_X }, + { "lda" , ABS_X }, + { "ldx" , ABS_Y }, + { "bbs3" , ZP_REL }, + + { "cpy" , IMMEDIATE }, /* 0xc0 to 0xcf */ + { "cmp" , ZP_X_IND }, + { "nop" , IMMEDIATE }, + { "nop" , IMPLIED }, + { "cpy" , ZP }, + { "cmp" , ZP }, + { "dec" , ZP }, + { "smb4" , ZP }, + { "iny" , IMPLIED }, + { "cmp" , IMMEDIATE }, + { "dex" , IMPLIED }, + { "wai" , IMPLIED }, + { "cpy" , ABS }, + { "cmp" , ABS }, + { "dec" , ABS }, + { "bbs4" , ZP_REL }, + + { "bne" , REL }, /* 0xd0 to 0xdf */ + { "cmp" , ZP_IND_Y }, + { "cmp" , ZP_IND }, + { "nop" , IMPLIED }, + { "nop" , ZP_X }, + { "cmp" , ZP_X }, + { "dec" , ZP_X }, + { "smb5" , ZP }, + { "cld" , IMPLIED }, + { "cmp" , ABS_Y }, + { "phx" , IMPLIED }, + { "stp" , IMPLIED }, + { "nop" , ABS }, + { "cmp" , ABS_X }, + { "dec" , ABS_X }, + { "bbs5" , ZP_REL }, + + { "cpx" , IMMEDIATE }, /* 0xe0 to 0xef */ + { "sbc" , ZP_X_IND }, + { "nop" , IMMEDIATE }, + { "nop" , IMPLIED }, + { "cpx" , ZP }, + { "sbc" , ZP }, + { "inc" , ZP }, + { "smb6" , ZP }, + { "inx" , IMPLIED }, + { "sbc" , IMMEDIATE }, + { "nop" , IMPLIED }, + { "nop" , IMPLIED }, + { "cpx" , ABS }, + { "sbc" , ABS }, + { "inc" , ABS }, + { "bbs6" , ZP_REL }, + + { "beq" , REL }, /* 0xf0 to 0xff */ + { "sbc" , ZP_IND_Y }, + { "sbc" , ZP_IND }, + { "nop" , IMPLIED }, + { "nop" , ZP_X }, + { "sbc" , ZP_X }, + { "inc" , ZP_X }, + { "smb7" , ZP }, + { "sed" , IMPLIED }, + { "sbc" , ABS_Y }, + { "plx" , IMPLIED }, + { "nop" , IMPLIED }, + { "nop" , ABS }, + { "sbc" , ABS_X }, + { "inc" , ABS_X }, + { "bbs7" , ZP_REL } +}; + +/* Information for 6502X (6502 with undocumented instructions) opcodes. */ +static InstructionInfo II_6502X[256] = { + { "brk" , IMPLIED }, /* 0x00 to 0x0f */ + { "ora" , ZP_X_IND }, + { "jam" , IMPLIED }, + { "slo" , ZP_X_IND }, + { "nop" , ZP }, + { "ora" , ZP }, + { "asl" , ZP }, + { "slo" , ZP }, + { "php" , IMPLIED }, + { "ora" , IMMEDIATE }, + { "asl" , ACCUMULATOR }, + { "anc" , IMMEDIATE }, + { "nop" , ABS }, + { "ora" , ABS }, + { "asl" , ABS }, + { "slo" , ABS }, + + { "bpl" , REL }, /* 0x10 to 0x1f */ + { "ora" , ZP_IND_Y }, + { "jam" , IMPLIED }, + { "slo" , ZP_IND_Y }, + { "nop" , ZP_X }, + { "ora" , ZP_X }, + { "asl" , ZP_X }, + { "slo" , ZP }, + { "clc" , IMPLIED }, + { "ora" , ABS_Y }, + { "nop" , IMPLIED }, + { "slo" , ABS_Y }, + { "*nop" , ABS_X }, + { "ora" , ABS_X }, + { "asl" , ABS_X }, + { "slo" , ABS_X }, + + { "jsr" , ABS }, /* 0x20 to 0x2f */ + { "and" , ZP_X_IND }, + { "jam" , IMPLIED }, + { "rla" , ZP_X_IND }, + { "bit" , ZP }, + { "and" , ZP }, + { "rol" , ZP }, + { "rla" , ZP }, + { "plp" , IMPLIED }, + { "and" , IMMEDIATE }, + { "rol" , ACCUMULATOR }, + { "anc" , IMMEDIATE }, + { "bit" , ABS }, + { "and" , ABS }, + { "rol" , ABS }, + { "rla" , ABS }, + + { "bmi" , REL }, /* 0x30 to 0x3f */ + { "and" , ZP_IND_Y }, + { "jam" , IMPLIED }, + { "rla" , ZP_IND_Y }, + { "nop" , ZP_X }, + { "and" , ZP_X }, + { "rol" , ZP_X }, + { "rla" , ZP_X }, + { "sec" , IMPLIED }, + { "and" , ABS_Y }, + { "nop" , IMPLIED }, + { "rla" , ABS_Y }, + { "nop" , ABS_X }, + { "and" , ABS_X }, + { "rol" , ABS_X }, + { "rla" , ABS_X }, + + { "rti" , IMPLIED }, /* 0x40 to 0x4f */ + { "eor" , ZP_X_IND }, + { "jam" , IMPLIED }, + { "sre" , ZP_X_IND }, + { "nop" , ZP }, + { "eor" , ZP }, + { "lsr" , ZP }, + { "sre" , ZP }, + { "pha" , IMPLIED }, + { "eor" , IMMEDIATE }, + { "lsr" , ACCUMULATOR }, + { "alr" , IMMEDIATE }, + { "jmp" , ABS }, + { "eor" , ABS }, + { "lsr" , ABS }, + { "sre" , ABS }, + + { "bvc" , REL }, /* 0x50 to 0x5f */ + { "eor" , ZP_IND_Y }, + { "jam" , IMPLIED }, + { "sre" , ZP_IND_Y }, + { "nop" , ZP_X }, + { "eor" , ZP_X }, + { "lsr" , ZP_X }, + { "sre" , ZP_X }, + { "cli" , IMPLIED }, + { "eor" , ABS_Y }, + { "nop" , IMPLIED }, + { "sre" , ABS_Y }, + { "nop" , ABS_X }, + { "eor" , ABS_X }, + { "lsr" , ABS_X }, + { "sre" , ABS_X }, + + { "rts" , IMPLIED }, /* 0x60 to 0x6f */ + { "adc" , ZP_X_IND }, + { "jam" , IMPLIED }, + { "rra" , ZP_X_IND }, + { "nop" , ZP }, + { "adc" , ZP }, + { "ror" , ZP }, + { "rra" , ZP }, + { "pla" , IMPLIED }, + { "adc" , IMMEDIATE }, + { "ror" , ACCUMULATOR }, + { "arr" , IMMEDIATE }, + { "jmp" , ABS_IND }, + { "adc" , ABS }, + { "ror" , ABS }, + { "rra" , ABS }, + + { "bvs" , REL }, /* 0x70 to 0x7f */ + { "adc" , ZP_IND_Y }, + { "jam" , IMPLIED }, + { "sre" , ZP_IND_Y }, + { "nop" , ZP_X }, + { "adc" , ZP_X }, + { "ror" , ZP_X }, + { "rra" , ZP_X }, + { "sei" , IMPLIED }, + { "adc" , ABS_Y }, + { "nop" , IMPLIED }, + { "rra" , ABS_Y }, + { "nop" , ABS_X }, + { "adc" , ABS_X }, + { "ror" , ABS_X }, + { "rra" , ABS_X }, + + { "nop" , IMMEDIATE }, /* 0x80 to 0x8f */ + { "sta" , ZP_X_IND }, + { "nop" , IMMEDIATE }, + { "sax" , ZP_X_IND }, + { "sty" , ZP }, + { "sta" , ZP }, + { "stx" , ZP }, + { "sax" , ZP }, + { "dey" , IMPLIED }, + { "nop" , IMMEDIATE }, + { "txa" , IMPLIED }, + { "ane" , IMMEDIATE }, + { "sty" , ABS }, + { "sta" , ABS }, + { "stx" , ABS }, + { "sax" , ABS }, + + { "bcc" , REL }, /* 0x90 to 0x9f */ + { "sta" , ZP_IND_Y }, + { "jam" , IMPLIED }, + { "sha" , ZP_IND_Y }, + { "sty" , ZP_X }, + { "sta" , ZP_X }, + { "stx" , ZP_Y }, + { "sax" , ZP_Y }, + { "tya" , IMPLIED }, + { "sta" , ABS_Y }, + { "txs" , IMPLIED }, + { "tas" , ABS_Y }, + { "shy" , ABS_X }, + { "sta" , ABS_X }, + { "shx" , ABS_Y }, + { "sha" , ABS_Y }, + + { "ldy" , IMMEDIATE }, /* 0xa0 to 0xaf */ + { "lda" , ZP_X_IND }, + { "ldx" , IMMEDIATE }, + { "lax" , ZP_X_IND }, + { "ldy" , ZP }, + { "lda" , ZP }, + { "ldx" , ZP }, + { "lax" , ZP }, + { "tay" , IMPLIED }, + { "lda" , IMMEDIATE }, + { "tax" , IMPLIED }, + { "lax" , IMMEDIATE }, + { "ldy" , ABS }, + { "lda" , ABS }, + { "ldx" , ABS }, + { "lax" , ABS }, + + { "bcs" , REL }, /* 0xb0 to 0xbf */ + { "lda" , ZP_IND_Y }, + { "jam" , IMPLIED }, + { "lax" , ZP_IND_Y }, + { "ldy" , ZP_X }, + { "lda" , ZP_X }, + { "ldx" , ZP_Y }, + { "lax" , ZP_Y }, + { "clv" , IMPLIED }, + { "lda" , ABS_Y }, + { "tsx" , IMPLIED }, + { "las" , ABS_Y }, + { "ldy" , ABS_X }, + { "lda" , ABS_X }, + { "ldx" , ABS_Y }, + { "lax" , ABS_Y }, + + { "cpy" , IMMEDIATE }, /* 0xc0 to 0xcf */ + { "cmp" , ZP_X_IND }, + { "nop" , IMMEDIATE }, + { "dcp" , ZP_X_IND }, + { "cpy" , ZP }, + { "cmp" , ZP }, + { "dec" , ZP }, + { "dcp" , ZP }, + { "iny" , IMPLIED }, + { "cmp" , IMMEDIATE }, + { "dex" , IMPLIED }, + { "sbx" , IMMEDIATE }, + { "cpy" , ABS }, + { "cmp" , ABS }, + { "dec" , ABS }, + { "dcp" , ABS }, + + { "bne" , REL }, /* 0xd0 to 0xdf */ + { "cmp" , ZP_IND_Y }, + { "jam" , IMPLIED }, + { "dcp" , ZP_IND_Y }, + { "nop" , ZP_X }, + { "cmp" , ZP_X }, + { "dec" , ZP_X }, + { "dcp" , ZP_X }, + { "cld" , IMPLIED }, + { "cmp" , ABS_Y }, + { "nop" , IMPLIED }, + { "dcp" , ABS_Y }, + { "nop" , ABS_X }, + { "cmp" , ABS_X }, + { "dec" , ABS_X }, + { "dcp" , ABS_X }, + + { "cpx" , IMMEDIATE }, /* 0xe0 to 0xef */ + { "sbc" , ZP_X_IND }, + { "nop" , IMMEDIATE }, + { "isc" , ZP_X_IND }, + { "cpx" , ZP }, + { "sbc" , ZP }, + { "inc" , ZP }, + { "isc" , ZP }, + { "inx" , IMPLIED }, + { "sbc" , IMMEDIATE }, + { "nop" , IMPLIED }, + { "sbc" , IMMEDIATE }, + { "cpx" , ABS }, + { "sbc" , ABS }, + { "inc" , ABS }, + { "isc" , ABS }, + + { "beq" , REL }, /* 0xf0 to 0xff */ + { "sbc" , ZP_IND_Y }, + { "jam" , IMPLIED }, + { "isc" , ZP_IND_Y }, + { "nop" , ZP_X }, + { "sbc" , ZP_X }, + { "inc" , ZP_X }, + { "isc" , ZP_X }, + { "sed" , IMPLIED }, + { "sbc" , ABS_Y }, + { "nop" , IMPLIED }, + { "isc" , ABS_Y }, + { "nop" , ABS_X }, + { "sbc" , ABS_X }, + { "inc" , ABS_X }, + { "isc" , ABS_X } +}; + +static InstructionInfo * II[3] = { II_6502, II_65C02, II_6502X }; + +static unsigned GetInstructionLength (uint8_t opcode) +/* Get the number of bytes in the full instruction. Depends on the addressing mode. */ +{ + switch (II[CPU][opcode].adrmode) { + case ILLEGAL: + case IMPLIED: + case ACCUMULATOR: + return 1; + case IMMEDIATE: + case REL: + case ZP: + case ZP_X: + case ZP_Y: + case ZP_IND: + case ZP_X_IND: + case ZP_IND_Y: + return 2; + case ZP_REL: + case ABS: + case ABS_X: + case ABS_Y: + case ABS_IND: + case ABS_X_IND: + return 3; + } + + /* We should never get here. */ + return -1; +} + + + +static char * PrintAssemblyInstruction (char * ptr) +/* Print assembly instruction: mnemonic and addres-mode specific operand(s). */ +{ + uint8_t opcode; + + /* Print the instruction starting at the current program counter. */ + + opcode = MemReadByte (Regs.PC); + + ptr += sprintf (ptr, "%-4s ", II[CPU][opcode].mnemonic); + + switch (II[CPU][opcode].adrmode) { + case IMPLIED: + case ILLEGAL: + break; + case ACCUMULATOR: + ptr += sprintf (ptr, "A"); + break; + case IMMEDIATE: + ptr += sprintf (ptr, "#$%02X", MemReadByte (Regs.PC + 1)); + break; + case REL: + ptr += sprintf (ptr, "$%04X", Regs.PC + 2 + (int8_t)MemReadByte (Regs.PC + 1)); + break; + case ZP: + ptr += sprintf (ptr, "$%02X", MemReadByte (Regs.PC + 1)); + break; + case ZP_X: + ptr += sprintf (ptr, "$%02X,X", MemReadByte (Regs.PC + 1)); + break; + case ZP_Y: + ptr += sprintf (ptr, "$%02X,Y", MemReadByte (Regs.PC + 1)); + break; + case ZP_IND: + ptr += sprintf (ptr, "($%02X)", MemReadByte (Regs.PC + 1)); + break; + case ZP_X_IND: + ptr += sprintf (ptr, "($%02X,X)", MemReadByte (Regs.PC + 1)); + break; + case ZP_IND_Y: + ptr += sprintf (ptr, "($%02X),Y", MemReadByte (Regs.PC + 1)); + break; + case ZP_REL: + ptr += sprintf (ptr, "$%02X,$%04X", MemReadByte (Regs.PC + 1), Regs.PC + 3 + (int8_t)MemReadByte (Regs.PC + 2)); + break; + case ABS: + ptr += sprintf (ptr, "$%04X", MemReadWord (Regs.PC + 1)); + break; + case ABS_IND: + ptr += sprintf (ptr, "($%04X)", MemReadWord (Regs.PC + 1)); + break; + case ABS_X: + ptr += sprintf (ptr, "$%04X,X", MemReadWord (Regs.PC + 1)); + break; + case ABS_X_IND: + ptr += sprintf (ptr, "($%04X,X)", MemReadWord (Regs.PC + 1)); + break; + case ABS_Y: + ptr += sprintf (ptr, "$%04X,Y", MemReadWord (Regs.PC + 1)); + break; + } + + return ptr; +} + + + +static void PrintTraceInstructionOrInterrupt (const char * InterruptType) +{ + char traceline[200]; + char * traceline_ptr = traceline; + uint8_t opcode; + unsigned k, num_bytes; + + if (TraceMode & TRACE_FIELD_INSTR_COUNTER) { + + if (traceline_ptr != traceline) { + /* Print field separator. */ + traceline_ptr += sprintf (traceline_ptr, " "); + } + + traceline_ptr += sprintf (traceline_ptr, "%12" PRIu64, Peripherals.Counter.CpuInstructions); + } + + if (TraceMode & TRACE_FIELD_CLOCK_COUNTER) { + + if (traceline_ptr != traceline) { + /* Print field separator. */ + traceline_ptr += sprintf (traceline_ptr, " "); + } + + traceline_ptr += sprintf (traceline_ptr, "%12" PRIu64, Peripherals.Counter.ClockCycles); + } + + if (TraceMode & TRACE_FIELD_PC) { + + if (traceline_ptr != traceline) { + /* Print field separator. */ + traceline_ptr += sprintf (traceline_ptr, " "); + } + + traceline_ptr += sprintf (traceline_ptr, "%04X", Regs.PC); + } + + if (TraceMode & TRACE_FIELD_INSTR_BYTES) { + + if (traceline_ptr != traceline) { + /* Print field separator. */ + traceline_ptr += sprintf (traceline_ptr, " "); + } + + if (InterruptType == NULL) + { + /* Get the opcode */ + opcode = MemReadByte (Regs.PC); + + /* How many bytes are in the full instruction? 1, 2 or 3. */ + num_bytes = GetInstructionLength (opcode); + } else { + num_bytes = 0; /* Consider interrupts as instructions that are inserted into the instruction stream. */ + } + + /* Print 0 to 3 bytes for the interrupt/instruction. */ + for (k = 0; k < 3; ++k) { + if (k != 0) { + *traceline_ptr++ = ' '; + } + if (k < num_bytes) { + traceline_ptr += sprintf (traceline_ptr, "%02X", MemReadByte (Regs.PC + k)); + } else { + traceline_ptr += sprintf (traceline_ptr, " "); + } + } + } + + if (TraceMode & TRACE_FIELD_INSTR_ASSEMBLY) { + + if (traceline_ptr != traceline) { + /* Print field separator. */ + traceline_ptr += sprintf (traceline_ptr, " "); + } + + char * save_ptr = traceline_ptr; + + if (InterruptType == NULL) { + traceline_ptr = PrintAssemblyInstruction (traceline_ptr); + } else { + /* Print interrupt message. */ + traceline_ptr += sprintf (traceline_ptr, "*** %s ***", InterruptType); + } + + /* Fill out the field to 16 characters */ + num_bytes = (unsigned)(traceline_ptr - save_ptr); + if (num_bytes < 16) { + traceline_ptr += sprintf (traceline_ptr, "%*s", 16 - num_bytes, ""); + } + } + + if (TraceMode & TRACE_FIELD_CPU_REGISTERS) { + + if (traceline_ptr != traceline) { + /* Print field separator. */ + traceline_ptr += sprintf (traceline_ptr, " "); + } + + traceline_ptr += sprintf (traceline_ptr, + "A=%02X X=%02X Y=%02X S=%02X Flags=%c%c%c%c%c%c", + Regs.AC, + Regs.XR, + Regs.YR, + Regs.SP, + (Regs.SR & SF) ? 'N' : 'n', + (Regs.SR & OF) ? 'V' : 'v', + (Regs.SR & DF) ? 'D' : 'd', + (Regs.SR & IF) ? 'I' : 'i', + (Regs.SR & ZF) ? 'Z' : 'z', + (Regs.SR & CF) ? 'C' : 'c' + ); + } + + if (TraceMode & TRACE_FIELD_CC65_SP) { + + if (traceline_ptr != traceline) { + /* Print field separator. */ + traceline_ptr += sprintf (traceline_ptr, " "); + } + + traceline_ptr += sprintf (traceline_ptr, + " SP=%04X", + MemReadZPWord (StackPointerZPageAddress) + ); + } + + if (traceline_ptr != traceline) { + puts (traceline); + } +} + + + +void TraceInit (uint8_t SPAddr) +{ + StackPointerZPageAddress = SPAddr; +} + + + +void PrintTraceNMI (void) +{ + PrintTraceInstructionOrInterrupt("NMI"); +} + + + +void PrintTraceIRQ (void) +{ + PrintTraceInstructionOrInterrupt("IRQ"); +} + + + +void PrintTraceInstruction (void) +{ + PrintTraceInstructionOrInterrupt(NULL); +} diff --git a/src/sim65/trace.h b/src/sim65/trace.h new file mode 100644 index 000000000..f982460d2 --- /dev/null +++ b/src/sim65/trace.h @@ -0,0 +1,89 @@ +/*****************************************************************************/ +/* */ +/* trace.h */ +/* */ +/* Instruction tracing functionality sim65 6502 simulator */ +/* */ +/* */ +/* */ +/* (C) 2025, Sidney Cadot */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + +#ifndef TRACE_H +#define TRACE_H + + +#include <stdint.h> + + +#include "6502.h" + +/* The trace mode is a bitfield that determines how trace lines are displayed. + * + * The value zero indicates that tracing is disabled (the default). + * + * In case TraceMode is not equal to zero, the value is interpreted as a bitfield: + * + * Bit Bit value Enables + * --- ----------- ------------------------------- + * 6 0x40 ( 64) Print the instruction counter. + * 5 0x20 ( 32) Print the clock cycle counter. + * 4 0x10 ( 16) Print the PC (program counter). + * 3 0x08 ( 8) Print the instruction bytes. + * 2 0x04 ( 4) Print the instruction assembly. + * 1 0x02 ( 2) Print the CPU registers. + * 0 0x01 ( 1) Print the CC65 stack pointer. + * + */ + +#define TRACE_FIELD_INSTR_COUNTER 0x40 +#define TRACE_FIELD_CLOCK_COUNTER 0x20 +#define TRACE_FIELD_PC 0x10 +#define TRACE_FIELD_INSTR_BYTES 0x08 +#define TRACE_FIELD_INSTR_ASSEMBLY 0x04 +#define TRACE_FIELD_CPU_REGISTERS 0x02 +#define TRACE_FIELD_CC65_SP 0x01 + +#define TRACE_DISABLED 0x00 +#define TRACE_ENABLE_FULL 0x7f + +/* Currently active tracing mode. */ +extern uint8_t TraceMode; + +void TraceInit (uint8_t SPAddr); +/* Initialize the trace subsystem. */ + +void PrintTraceNMI(void); +/* Print trace line for an NMI interrupt. */ + +void PrintTraceIRQ(void); +/* Print trace line for an IRQ interrupt. */ + +void PrintTraceInstruction (void); +/* Print trace line for the instruction at the currrent program counter. */ + + + +/* End of trace.h */ + +#endif From 988260c69998743932007e6995067e0ee49a1a50 Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Sun, 5 Jan 2025 15:58:05 +0100 Subject: [PATCH 376/707] sim65: add C/assembly support, docs, and samples for the new peripheral functionality. This PR is the second of two PRs that replaces earlier PRs #2589 and #2590. Due to a git branching mishap it was decided to re-partition the new functionality in two sequential PRs that offer self-contained, new functionality to sim65. The functionality in this second and last PR provides the following things in relation to the new "peripheral" support: * C support: there is now an include/sim65.h that can be included from C. It provides access to the memory-mapped peripheral addresses. * Asm support: there is now an asminc/sim65.inc that can be included from assembly. It provides symbolic labels for the memory-mapped peripheral addresses. Note: the two items above are implemented by adding a "_peripherals" symbol to cfg/sim6502.cfg and cfg/sim65c02.cfg, with the fixed base address of the peripherals memory aperture (0xffc0). * Updated the sim65 documentation to describe the peripherals in some detail, with examples that show to use the new features from within C. * Some examples in the new samples/sim5/ directory. These are currently not integrated in the build system (in other words, there's no Makefile there), because I don't know how to do that. I will happily implement that after #2582 is taken care of. If that is not acceptable, the next best thing will be for somebody else (who understands how the Makefiles are set up) to take care of this. If that's not going to happen, and we don't want examples that are not properly integrated with the build system, there's always the option of removing these samples from the PR. --- asminc/sim65.inc | 75 ++++++++++++++++++ cfg/sim6502.cfg | 6 +- cfg/sim65c02.cfg | 6 +- doc/sim65.sgml | 135 +++++++++++++++++++++++++++---- include/sim65.h | 136 ++++++++++++++++++++++++++++++++ samples/sim65/cpumode_example.c | 104 ++++++++++++++++++++++++ samples/sim65/timer_example.c | 117 +++++++++++++++++++++++++++ samples/sim65/trace_example.c | 40 ++++++++++ 8 files changed, 603 insertions(+), 16 deletions(-) create mode 100644 asminc/sim65.inc create mode 100644 include/sim65.h create mode 100644 samples/sim65/cpumode_example.c create mode 100644 samples/sim65/timer_example.c create mode 100644 samples/sim65/trace_example.c diff --git a/asminc/sim65.inc b/asminc/sim65.inc new file mode 100644 index 000000000..b8ea264b7 --- /dev/null +++ b/asminc/sim65.inc @@ -0,0 +1,75 @@ + +; ******************************************************************************* +; ** ** +; ** sim65.inc : assembler definitions for the sim6502 and sim65c02 targets. ** +; ** ** +; ** Sidney Cadot, January 2025 ** +; ** ** +; ******************************************************************************* + + ; The '_peripherals' symbol is defined in the linker configuration + ; file to correspond to the first address in the periperal memory + ; aparture. + ; + ; We use it here as a base address for all peripheral addresses. + + .import _peripherals + +; ************************************************************** +; ** ** +; ** Define assembler symbols for the "counter" peripheral. ** +; ** ** +; ************************************************************** + +peripheral_counter_base := _peripherals + 0 + +peripheral_counter_latch := peripheral_counter_base + 0 +peripheral_counter_select := peripheral_counter_base + 1 +peripheral_counter_value := peripheral_counter_base + 2 + +; Values for the peripheral_counter_select register. + +COUNTER_SELECT_CLOCKCYCLE_COUNTER = $00 +COUNTER_SELECT_INSTRUCTION_COUNTER = $01 +COUNTER_SELECT_IRQ_COUNTER = $02 +COUNTER_SELECT_NMI_COUNTER = $03 +COUNTER_SELECT_WALLCLOCK_TIME = $80 +COUNTER_SELECT_WALLCLOCK_TIME_SPLIT = $81 + +; ******************************************************************** +; ** ** +; ** Define assembler symbols for the "sim65 control" peripheral. ** +; ** ** +; ******************************************************************** + +peripheral_sim65_base := _peripherals + 10 + +peripheral_sim65_cpu_mode := peripheral_sim65_base + 0 +peripheral_sim65_trace_mode := peripheral_sim65_base + 1 + +; Values for the peripheral_sim65_cpu_mode register. + +SIM65_CPU_MODE_6502 = $00 +SIM65_CPU_MODE_65C02 = $01 +SIM65_CPU_MODE_6502X = $02 + +; Bitfield values for the peripheral_sim65_trace_mode field. + +SIM65_TRACE_MODE_FIELD_INSTR_COUNTER = $40 +SIM65_TRACE_MODE_FIELD_CLOCK_COUNTER = $20 +SIM65_TRACE_MODE_FIELD_PC = $10 +SIM65_TRACE_MODE_FIELD_INSTR_BYTES = $08 +SIM65_TRACE_MODE_FIELD_INSTR_ASSEMBLY = $04 +SIM65_TRACE_MODE_FIELD_CPU_REGISTERS = $02 +SIM65_TRACE_MODE_FIELD_CC65_SP = $01 + +; Values for the peripheral_sim65_trace_mode field that fully disable / enable tracing. + +SIM65_TRACE_MODE_DISABLE = $00 +SIM65_TRACE_MODE_ENABLE_FULL = $7F + +; ************************ +; ** ** +; ** End of sim65.inc ** +; ** ** +; ************************ diff --git a/cfg/sim6502.cfg b/cfg/sim6502.cfg index d393a4aee..72098f750 100644 --- a/cfg/sim6502.cfg +++ b/cfg/sim6502.cfg @@ -1,12 +1,15 @@ SYMBOLS { __EXEHDR__: type = import; __STACKSIZE__: type = weak, value = $0800; # 2k stack + _peripherals: type = export, value = $FFC0; } + MEMORY { ZP: file = "", start = $0000, size = $0100; HEADER: file = %O, start = $0000, size = $000C; - MAIN: file = %O, define = yes, start = $0200, size = $FDC0 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $0200, size = $FFC0 - $0200 - __STACKSIZE__; } + SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXEHDR: load = HEADER, type = ro; @@ -18,6 +21,7 @@ SEGMENTS { DATA: load = MAIN, type = rw; BSS: load = MAIN, type = bss, define = yes; } + FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, diff --git a/cfg/sim65c02.cfg b/cfg/sim65c02.cfg index d393a4aee..72098f750 100644 --- a/cfg/sim65c02.cfg +++ b/cfg/sim65c02.cfg @@ -1,12 +1,15 @@ SYMBOLS { __EXEHDR__: type = import; __STACKSIZE__: type = weak, value = $0800; # 2k stack + _peripherals: type = export, value = $FFC0; } + MEMORY { ZP: file = "", start = $0000, size = $0100; HEADER: file = %O, start = $0000, size = $000C; - MAIN: file = %O, define = yes, start = $0200, size = $FDC0 - __STACKSIZE__; + MAIN: file = %O, define = yes, start = $0200, size = $FFC0 - $0200 - __STACKSIZE__; } + SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXEHDR: load = HEADER, type = ro; @@ -18,6 +21,7 @@ SEGMENTS { DATA: load = MAIN, type = rw; BSS: load = MAIN, type = bss, define = yes; } + FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 9f2914254..9c3764e1d 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -40,6 +40,8 @@ The simulator is called as follows: Long options: --help Help (this text) --cycles Print amount of executed CPU cycles + --cpu <type> Override CPU type (6502, 65C02, 6502X) + --trace Enable CPU trace --verbose Increase verbosity --version Print the simulator version number </verb></tscreen> @@ -70,6 +72,17 @@ Here is a description of all the command line options: count. + <tag><tt>--cpu <type></tt></tag> + + Specify the CPU type to use while executing the program. This CPU type + is normally determined from the program file header, but it can be useful + to override it. + + <tag><tt>--trace</tt></tag> + + Print a single line of information for each instruction or interrupt that + is executed by the CPU to stdout. + <tag><tt>-v, --verbose</tt></tag> Increase the simulator verbosity. @@ -298,25 +311,23 @@ bytes before the first write to <tt>PERIPHERALS_COUNTER_LATCH</tt> will yield ze Example: <tscreen><verb> -#include <stdio.h> -#include <stdint.h> +/* This example uses the peripheral support in sim65.h */ -volatile uint8_t * CounterLatch = (uint8_t *)0xffc0; -volatile uint8_t * CounterSelect = (uint8_t *)0xffc1; -volatile uint32_t * CounterValue = (uint32_t *)0xffc2; +#include <stdio.h> +#include <sim65.h> static void print_current_counters(void) { - *CounterLatch = 0; /* latch values */ + peripherals.counter.latch = 0; /* latch values */ - *CounterSelect = 0x00; - printf("clock cycles ............... : %08lx %08lx\n", CounterValue[1], CounterValue[0]); - *CounterSelect = 0x01; - printf("instructions ............... : %08lx %08lx\n", CounterValue[1], CounterValue[0]); - *CounterSelect = 0x80; - printf("wallclock time ............. : %08lx %08lx\n", CounterValue[1], CounterValue[0]); - *CounterSelect = 0x81; - printf("wallclock time, split ...... : %08lx %08lx\n", CounterValue[1], CounterValue[0]); + peripherals.counter.select = COUNTER_SELECT_CLOCKCYCLE_COUNTER; + printf("clock cycles ............... : %08lx %08lx\n", peripherals.counter.value32[1], peripherals.counter.value32[0]); + peripherals.counter.select = COUNTER_SELECT_INSTRUCTION_COUNTER; + printf("instructions ............... : %08lx %08lx\n", peripherals.counter.value32[1], peripherals.counter.value32[0]); + peripherals.counter.select = COUNTER_SELECT_WALLCLOCK_TIME; + printf("wallclock time ............. : %08lx %08lx\n", peripherals.counter.value32[1], peripherals.counter.value32[0]); + peripherals.counter.select = COUNTER_SELECT_WALLCLOCK_TIME_SPLIT; + printf("wallclock time, split ...... : %08lx %08lx\n", peripherals.counter.value32[1], peripherals.counter.value32[0]); printf("\n"); } @@ -328,6 +339,102 @@ int main(void) } </verb></tscreen> +<sect>SIM65 control peripheral + +<p>The sim65 simulator supports a memory-mapped peripheral that allows control +of the simulator behavior itself. + +<p>The sim65 control peripheral interface consists of 2 registers: + +<itemize> +<item><tt>PERIPHERALS_SIMCONTROL_CPUMODE</tt> ($FFCA, read/write) +<item><tt>PERIPHERALS_SIMCONTROL_TRACEMODE</tt> ($FFCB, read/write) +</itemize> + +<p>Address <tt>PERIPHERALS_SIMCONTROL_CPUMODE</tt> allows access to the currently active CPU mode. + +<p>Possible values are CPU_6502 (0), CPU_65C02 (1), and CPU_6502X (2). For specialized applications, +it may be useful to switch CPU models at runtime; this is supported by writing 0, 1, or 2 to this address. +Writing any other value will be ignored. + +<p>Address <tt>PERIPHERALS_SIMCONTROL_TRACEMODE</tt> allows inspection and control of the currently active +CPU tracing mode. + +<p>A value of 0 means tracing is disabled; a value of $7F fully enables tracing. The 7 +lower bits of the value actually provide control over which fields are printed; see below +for an explanation of the seven fields. + +<p>Having the ability to enable/disable tracing on the fly can be a useful debugging aid. For example, +it can be used to enable tracing for short fragments of code. Consider the following example: + +<tscreen><verb> +/* This example uses the TRACE_ON and TRACE_OFF macros defined in sim65.h */ + +#include <stdio.h> +#include <sim65.h> + +unsigned x; + +int main(void) +{ + TRACE_ON(); + + x = 0x1234; /* We want to see what happens here. */ + + TRACE_OFF(); + + return 0; +} +</verb></tscreen> + +<p>This small test program, when compiled with optimizations enabled (-O), produces the output trace below: + +<tscreen><verb> +70 232 022E A2 12 ldx #$12 A=7F X=00 Y=04 S=FD Flags=nvdizC SP=FFBC +71 234 0230 A9 34 lda #$34 A=7F X=12 Y=04 S=FD Flags=nvdizC SP=FFBC +72 236 0232 8D C8 02 sta $02C8 A=34 X=12 Y=04 S=FD Flags=nvdizC SP=FFBC +73 240 0235 8E C9 02 stx $02C9 A=34 X=12 Y=04 S=FD Flags=nvdizC SP=FFBC +74 244 0238 A9 00 lda #$00 A=34 X=12 Y=04 S=FD Flags=nvdizC SP=FFBC +75 246 023A 8D CB FF sta $FFCB A=00 X=12 Y=04 S=FD Flags=nvdiZC SP=FFBC +</verb></tscreen> + +<p>The example output shows the full trace format, consisting of the following seven fields: + +<itemize> +<item>The first field is an instruction counter. We see here that the assignment '<tt>x = 0x1234;</tt>' +starts at the 70th CPU instruction since the start of the simulator, and takes four 6502 instructions. +The two instructions that follow correspond to the execution of the <tt>TRACE_OFF</tt>' macro +that disables tracing. +<item>The second field shows the clock cycles since the start of the program. Here we see that the +first four instructions take 12 clock cycles in total (262 - 250 = 12). +<item>The third field shows the program counter as a four-digit, i.e., the PC register. Its 16-bit + value is displayed as a 4-digit hecadecimal number. +<item>The fourth field shows one to three hexadecimal byte values that make up the instruction. +<item>The fifth field shows the instruction in human-readable assembly language. +<item>The sixth field shows the CPU registers before execution of the instruction. The A, X, Y, and + S registers are each shown as a single byte value. The six status bits of the CPU are shown in + the order NVDIZC (Negative, Overflow, Decimal, Interrupt, Zero, Carry). They are displayed as + a capital letter if the flag is set, or a small letter if the flag is unset. +<item>The seventh and last field shows the software stack pointer SP as used by CC65 programs that + conform to the CC65 conventions. +</itemize> + +<p>Writing a specific value to <tt>PERIPHERALS_SIMCONTROL_TRACEMODE</tt> will control which of these +seven fields are displayed. The following values are defined to denote the seven fields: + +<itemize> +<item>TRACE_FIELD_INSTR_COUNTER = 0x40 +<item>TRACE_FIELD_CLOCK_COUNTER = 0x20 +<item>TRACE_FIELD_PC = 0x10 +<item>TRACE_FIELD_INSTR_BYTES = 0x08 +<item>TRACE_FIELD_INSTR_ASSEMBLY = 0x04 +<item>TRACE_FIELD_CPU_REGISTERS = 0x02 +<item>TRACE_FIELD_CC65_SP = 0x01 +</itemize> + +<p>For example, writing the value $16 to <tt>PERIPHERALS_SIMCONTROL_TRACEMODE</tt> will only display +the program counter, instruction assembly, and CPU registers fields. + <sect>Copyright<p> sim65 (and all cc65 binutils) are (C) Copyright 1998-2000 Ullrich von diff --git a/include/sim65.h b/include/sim65.h new file mode 100644 index 000000000..ef59955ff --- /dev/null +++ b/include/sim65.h @@ -0,0 +1,136 @@ +/*****************************************************************************/ +/* */ +/* sim65.h */ +/* */ +/* Definitions for the sim6502 and sim65c02 targets */ +/* */ +/* */ +/* */ +/* (C) 2025 Sidney Cadot */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + +#ifndef _SIM65_H +#define _SIM65_H + +/* Check that we include this file while compiling to a compatible target. */ +#if !defined(__SIM6502__) && !defined(__SIM65C02__) +# error This module may only be used when compiling for the sim6502 or sim65c02 targets! +#endif + +#include <stdint.h> + +/* The sim65 targets (sim6502, sim65c02) have a peripheral memory aperture located at + * address range 0xFFC0 .. 0xFFDF. Currently, the following peripherals are located + * inside that memory apeture: + * + * $FFC0 .. $FFC9 "counter" peripheral + * $FFCA .. $FFCB "sim65 control" peripheral + * $FFCC .. $FFDF (currently unused) + * + * The "peripherals" structure below corresponds to the register layout of the currently + * defined peripherals in this memory range. Combined with the fact that the sim6502 and + * sim65c02 linker configuration files define the "peripherals" symbol to be fixed at + * address $FFC0, this provides easy-to-use and efficient access to the peripheral registers. + * + * After including "sim65.h", it is possible for a C program to do things like: + * + * { + * peripherals.counter.latch = 0; + * peripherals.sim65.cpu_mode = SIM65_CPU_MODE_6502X; + * peripherals.sim65.trace_mode = SIM65_TRACE_MODE_ENABLE_FULL; + * } + * + * Note that "peripherals" variable is declared volatile. This instructs a C compiler to + * forego optimizations on memory accesses to the variable. However, CC65 currently ignores + * the volatile attribute. Fortunately, it is not smart with respect to optimizing + * memory accesses, so accessing the "peripherals" fields works fine in practice. + */ + +extern volatile struct { + struct { + uint8_t latch; + uint8_t select; + union { + uint8_t value [8]; /* Access value as eight separate bytes. */ + uint16_t value16 [4]; /* Access value as four 16-bit words. */ + uint32_t value32 [2]; /* Access value as two 32-bit long words. */ + }; + } counter; + struct { + uint8_t cpu_mode; + uint8_t trace_mode; + } sim65; +} peripherals; + +/* Values for the peripherals.counter.select field. */ +#define COUNTER_SELECT_CLOCKCYCLE_COUNTER 0x00 +#define COUNTER_SELECT_INSTRUCTION_COUNTER 0x01 +#define COUNTER_SELECT_IRQ_COUNTER 0x02 +#define COUNTER_SELECT_NMI_COUNTER 0x03 +#define COUNTER_SELECT_WALLCLOCK_TIME 0x80 +#define COUNTER_SELECT_WALLCLOCK_TIME_SPLIT 0x81 + +/* Values for the peripherals.sim65.cpu_mode field. */ +#define SIM65_CPU_MODE_6502 0x00 +#define SIM65_CPU_MODE_65C02 0x01 +#define SIM65_CPU_MODE_6502X 0x02 + +/* Bitfield values for the peripherals.sim65.trace_mode field. */ +#define SIM65_TRACE_MODE_FIELD_INSTR_COUNTER 0x40 +#define SIM65_TRACE_MODE_FIELD_CLOCK_COUNTER 0x20 +#define SIM65_TRACE_MODE_FIELD_PC 0x10 +#define SIM65_TRACE_MODE_FIELD_INSTR_BYTES 0x08 +#define SIM65_TRACE_MODE_FIELD_INSTR_ASSEMBLY 0x04 +#define SIM65_TRACE_MODE_FIELD_CPU_REGISTERS 0x02 +#define SIM65_TRACE_MODE_FIELD_CC65_SP 0x01 + +/* Values for the peripherals.sim65.trace_mode field that fully disable / enable tracing. */ +#define SIM65_TRACE_MODE_DISABLE 0x00 +#define SIM65_TRACE_MODE_ENABLE_FULL 0x7F + +/* Convenience macros to enable / disable tracing at runtime. */ +#define TRACE_ON() do peripherals.sim65.trace_mode = SIM65_TRACE_MODE_ENABLE_FULL; while(0) +#define TRACE_OFF() do peripherals.sim65.trace_mode = SIM65_TRACE_MODE_DISABLE; while(0) + +/* Convenience macro to query the CPU mode at runtime. */ +#define GET_CPU_MODE() peripherals.sim65.cpu_mode + +/* Convenience macro to set the CPU mode at runtime. + * + * Use SIM65_CPU_MODE_6502, SIM65_CPU_MODE_65C02, or SIM65_CPU_MODE_6502 as argument. + * + * Important Note: + * + * When running in a program compiled for the "sim6502" target, it is safe to switch to + * 65C02 or 6502X mode, since the runtime library will only use plain 6502 opcodes, and + * those work the same in 65C02 and 6502X mode. + * + * However, when running in a program compiled for the "sim65c02" target, it is NOT safe + * to switch to 6502 or 6502X mode, since many routines in the runtime library use + * 65C02-specific opcodes, and these will not work as expected when the CPU is switched + * to 6502 or 6502X mode. When such an instruction is encountered, the program will + * exhibit undefined behavior. + */ +#define SET_CPU_MODE(mode) do peripherals.sim65.cpu_mode = mode; while(0) + +/* End of sim65.h */ +#endif diff --git a/samples/sim65/cpumode_example.c b/samples/sim65/cpumode_example.c new file mode 100644 index 000000000..87fce36cd --- /dev/null +++ b/samples/sim65/cpumode_example.c @@ -0,0 +1,104 @@ +/* + * Sim65 cpu-mode switching example. + * + * Description + * ----------- + * + * We can inspect and manipulate the CPU model that sim65 emulates at runtime. + * + * Sim65 always runs in one of three modes: + * + * - 6502 mode: the 151 documented opcodes are supported; if the processor encounters + * one of the 105 undocumented opcodes, the simulator ends with an + * 'illegal opcode' message. + * - 65C02 mode: the 105 undocumented opcodes now have well-defined behavior. Some + * do useful things, while all others are now defined as NOPs. + * - 6502X mode: the 105 undocumented opcodes don't have documented behavior, but + * they /do/ have behavior on a real 6502. This behavior has been + * figured out, and is deterministic (with minor exceptions). + * In this mode, sim65 mimics the behavior of a real 6502 when + * it encounters an undocumented opcode, rather than terminating. + * + * In the example below, we first switch to 6502X mode and execute a small + * assembly code fragment, then repeat this in 65C02 mode. + * + * The code fragment is designed to distinguish between a 6502 and a 65C02 + * processor based on the behavior of the ADC function in decimal mode. + * + * Important Note: + * + * When running in a program compiled for the "sim6502" target, it is safe to switch to + * 65C02 or 6502X mode, since the runtime library will only use plain 6502 opcodes, and + * those work the same in 65C02 and 6502X mode. + * + * However, when running in a program compiled for the "sim65c02" target, it is NOT safe + * to switch to 6502 or 6502X mode, since many routines in the runtime library use + * 65C02-specific opcodes, and these will not work as expected when the CPU is switched + * to 6502 or 6502X mode. When such an instruction is encountered, the program will + * exhibit undefined behavior. + * + * For this reason, this program will only work when compiled for the "sim6502" target. + * + * Running the example + * ------------------- + * + * cl65 -t sim6502 -O cpumode_example.c -o cpumode_example.prg + * sim65 cpumode_example.prg + * + */ + +#include <stdio.h> +#include <stdbool.h> +#include <sim65.h> + +static bool __fastcall__ is_65c02(void) +{ + /* This assembly routine loads 0 into AX on a 6502 (also on a 6502 on which decimal + * mode is not implemented), and 1 on a 65C02. + * + * Note: this implementation triggers a "control reaches end of non-void function" + * warning that can be safely ignored. While no return statement is present, the + * return value is correctly loaded into AX by the assembly code. + */ + __asm__("ldx #0"); + __asm__("sed"); + __asm__("txa"); + __asm__("sbc #28"); + __asm__("asl a"); + __asm__("sbc #28"); + __asm__("and #1"); + __asm__("cld"); +} + +int main(void) +{ + printf("CPU mode at startup ....... : %u\n", GET_CPU_MODE()); + printf("Is 65C02? ................. : %s\n", is_65c02() ? "YES" : "NO"); + + printf("\n"); + + printf("Switching to 6502 mode ....\n"); + SET_CPU_MODE(SIM65_CPU_MODE_6502); + printf("Current CPU mode .......... : %u\n", GET_CPU_MODE()); + printf("Is 65C02? ................. : %s\n", is_65c02() ? "YES" : "NO"); + + printf("\n"); + + printf("Switching to 65C02 mode ...\n"); + SET_CPU_MODE(SIM65_CPU_MODE_65C02); + printf("Current CPU mode .......... : %u\n", GET_CPU_MODE()); + printf("Is 65C02? ................. : %s\n", is_65c02() ? "YES" : "NO"); + + printf("\n"); + + printf("Switching to 6502X mode ...\n"); + SET_CPU_MODE(SIM65_CPU_MODE_6502X); + printf("Current CPU mode .......... : %u\n", GET_CPU_MODE()); + printf("Is 65C02? ................. : %s\n", is_65c02() ? "YES" : "NO"); + + printf("\n"); + + printf("Bye!\n"); + + return 0; +} diff --git a/samples/sim65/timer_example.c b/samples/sim65/timer_example.c new file mode 100644 index 000000000..0675979b1 --- /dev/null +++ b/samples/sim65/timer_example.c @@ -0,0 +1,117 @@ +/* + * Sim65 timer example. + * + * Description + * ----------- + * + * This example tests the clock cycle counter feature of sim65. + * + * The function 'timestamp' obtains the lower 32-bits of the clock cycle counter. + * + * The function 'calc_sum_terms' calculates the sum of a range of integers + * starting at zero. It simply iterates over all terms, which means that its + * runtime is a linear function of its input value. + * + * In the main function, we first derive an 'offset' value by getting two timestamp + * values, with nothing happening in between. Ideally this should yield a 0 clock + * cycle duration, but due to the overhead of calling the 'timestamp' function, + * and the 'timestamp' function itself, the difference between these timestamp + * will be non-zero. We store this value in the 'overhead' variable, and subtract + * this value in later measurements. + * + * Next, we measure the duration of calling the function 'calc_sum_terms' with two + * input values, 0, and 1. The duration includes storing the result in the 'result' + * variable. + * + * Extrapolating from these two measurements, and assuming that the runtime of + * calling 'calc_sum_terms' and storing its result scales linearly with its argument, + * we can predict the duration of a call to 'calc_sum_terms' with a much larger + * argument (max_terms = 10000). + * + * Finally, we actually measure the duration with max_terms = 10000. If the + * duration measured is equal to the predicted value, we exit successfully. If not, + * we exit with failure. + * + * Running the example + * ------------------- + * + * cl65 -t sim6502 -O timer_example.c -o timer_example.prg + * sim65 timer_example.prg + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sim65.h> + +static uint32_t timestamp(void) +{ + peripherals.counter.select = COUNTER_SELECT_CLOCKCYCLE_COUNTER; + peripherals.counter.latch = 0; + return peripherals.counter.value32[0]; +} + +static unsigned long calc_sum_terms(unsigned max_term) +/* A function with a runtime that scales linearly with its argument. */ +{ + unsigned k; + unsigned long sum = 0; + for (k = 0; k <= max_term; ++k) + { + sum += k; + } + return sum; +} + +int main(void) +{ + unsigned max_term; + unsigned long result; + uint32_t t1, t2, overhead, duration; + int32_t d0, d1; + int32_t predicted_duration; + + /* Calibration measurement of zero clock cycles, to determine the overhead. */ + + overhead = 0; + t1 = timestamp(); + t2 = timestamp() - overhead; + overhead = (t2 - t1); + + /* Calculate call duration (including assignment of result) for argument value 0. */ + + max_term = 0; + t1 = timestamp(); + result = calc_sum_terms(max_term); + t2 = timestamp(); + d0 = (t2 - t1) - overhead; + printf("max_term = %u -> result = %lu; duration = %ld\n", max_term, result, d0); + + /* Calculate call duration (including assignment of result) for argument value 1. */ + + max_term = 1; + t1 = timestamp(); + result = calc_sum_terms(max_term); + t2 = timestamp(); + d1 = (t2 - t1) - overhead; + printf("max_term = %u -> result = %lu; duration = %ld\n", max_term, result, d1); + + /* Predict runtime for a much bigger argument value, 10000. */ + + max_term = 10000; + predicted_duration = d0 + max_term * (d1 - d0); + + printf("predicted duration for max_term = %u: %lu\n", max_term, predicted_duration); + + /* Do the actual measurement for max_term = 10000. */ + + t1 = timestamp(); + result = calc_sum_terms(max_term); + t2 = timestamp(); + duration = (t2 - t1) - overhead; + printf("max_term = %u -> result = %lu; duration = %ld\n", max_term, result, duration); + + /* Report success or failure. */ + + return (duration == predicted_duration) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/samples/sim65/trace_example.c b/samples/sim65/trace_example.c new file mode 100644 index 000000000..cd4ec87d7 --- /dev/null +++ b/samples/sim65/trace_example.c @@ -0,0 +1,40 @@ +/* + * Sim65 trace functionailty example. + * + * Description + * ----------- + * + * The easiest way to use tracing in sim65 is to pass the '--trace' option + * to sim65 while starting a program. + * + * However, it is also possiblke to enable and disable the trace functionality + * at runtime, from within the C code itself. This can be useful to produce + * runtime traces of small code fragments for debugging purposes. + * + * In this example, We use the TRACE_ON and TRACE_OFF macros provided in sim65.h + * to trace what the CPU is doing during a single statement: the assignment of + * a constant to a global variable. + * + * Running the example + * ------------------- + * + * cl65 -t sim6502 -O trace_example.c -o trace_example.prg + * sim65 trace_example.prg + * + * Compiling and running the program like this will produce a trace of six 6502 instructions. + * The first four instructions correspond to the 'x = 0x1234' assignment statement. + * The last two instructions (ending in a store to address $FFCB) disable the trace facility. + * + */ + +#include <sim65.h> + +unsigned x; + +int main(void) +{ + TRACE_ON(); + x = 0x1234; + TRACE_OFF(); + return 0; +} From aca6b33af7c41eb8ac82eb4e96d05a2127e6f43d Mon Sep 17 00:00:00 2001 From: sidney <sidney@jigsaw.nl> Date: Sun, 5 Jan 2025 16:16:13 +0100 Subject: [PATCH 377/707] Fixed printf format types, and don't act like a test. --- samples/sim65/timer_example.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/samples/sim65/timer_example.c b/samples/sim65/timer_example.c index 0675979b1..8262bdff8 100644 --- a/samples/sim65/timer_example.c +++ b/samples/sim65/timer_example.c @@ -41,7 +41,6 @@ */ #include <stdio.h> -#include <stdlib.h> #include <sim65.h> static uint32_t timestamp(void) @@ -67,9 +66,9 @@ int main(void) { unsigned max_term; unsigned long result; - uint32_t t1, t2, overhead, duration; - int32_t d0, d1; - int32_t predicted_duration; + uint32_t t1, t2, overhead; + int32_t d0, d1, duration; + int32_t predicted_duration; /* Calibration measurement of zero clock cycles, to determine the overhead. */ @@ -101,9 +100,11 @@ int main(void) max_term = 10000; predicted_duration = d0 + max_term * (d1 - d0); - printf("predicted duration for max_term = %u: %lu\n", max_term, predicted_duration); + printf("predicted duration for max_term = %u: %ld\n", max_term, predicted_duration); - /* Do the actual measurement for max_term = 10000. */ + /* Do the actual measurement for max_term = 10000. + * Note: equality between the prediction and the measurement is only achieved if we compile with -O. + */ t1 = timestamp(); result = calc_sum_terms(max_term); @@ -111,7 +112,6 @@ int main(void) duration = (t2 - t1) - overhead; printf("max_term = %u -> result = %lu; duration = %ld\n", max_term, result, duration); - /* Report success or failure. */ - return (duration == predicted_duration) ? EXIT_SUCCESS : EXIT_FAILURE; + return 0; } From 3a52c143fb3b0e2f4d2e9e2ab4bc068a6e775b9a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 5 Jan 2025 13:25:12 +0100 Subject: [PATCH 378/707] Fix #2566. --- src/cc65/assignment.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index e51dde9ab..e9b200b0f 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -104,9 +104,9 @@ static void CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) } else { - /* The rhs cannot happen to be loaded in the primary as it is too big */ + /* Load the address of rhs into the primary */ + ED_AddrExpr (RExpr); if (!ED_IsLocExpr (RExpr)) { - ED_AddrExpr (RExpr); LoadExpr (CF_NONE, RExpr); } From 447b6e557302571e2b96a2a748920c6894f611c8 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 5 Jan 2025 16:27:36 +0100 Subject: [PATCH 379/707] More explicit solution. The first one was a bit hackish. --- src/cc65/assignment.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index e9b200b0f..a66c495da 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -105,9 +105,15 @@ static void CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) } else { /* Load the address of rhs into the primary */ - ED_AddrExpr (RExpr); if (!ED_IsLocExpr (RExpr)) { + ED_AddrExpr (RExpr); LoadExpr (CF_NONE, RExpr); + } else if (RExpr->IVal != 0) { + /* We have an expression in the primary plus a constant + ** offset. Adjust the value in the primary accordingly. + */ + g_inc (CF_PTR | CF_CONST, RExpr->IVal); + RExpr->IVal = 0; } /* Push the address of the rhs as the source of memcpy */ From 1556c8ac7cec6d0c3de4d9ca9fefb05797ff7d38 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 5 Jan 2025 17:04:31 +0100 Subject: [PATCH 380/707] Move the test from "todo" to "val" since it shouldn't fail any longer. --- test/{todo => val}/bug2566.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{todo => val}/bug2566.c (100%) diff --git a/test/todo/bug2566.c b/test/val/bug2566.c similarity index 100% rename from test/todo/bug2566.c rename to test/val/bug2566.c From aacd64b2bca57bbcb737c777380084f73b949264 Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Sun, 5 Jan 2025 22:29:51 +0100 Subject: [PATCH 381/707] Shorteded is_65c02 routine. --- samples/sim65/cpumode_example.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/sim65/cpumode_example.c b/samples/sim65/cpumode_example.c index 87fce36cd..6cc2d0c16 100644 --- a/samples/sim65/cpumode_example.c +++ b/samples/sim65/cpumode_example.c @@ -60,12 +60,12 @@ static bool __fastcall__ is_65c02(void) * warning that can be safely ignored. While no return statement is present, the * return value is correctly loaded into AX by the assembly code. */ - __asm__("ldx #0"); __asm__("sed"); + __asm__("ldx #0"); __asm__("txa"); - __asm__("sbc #28"); - __asm__("asl a"); - __asm__("sbc #28"); + __asm__("sbc #155"); + __asm__("asl"); + __asm__("rol"); __asm__("and #1"); __asm__("cld"); } From e245ae655d0d1f3a9b6c931e3dbbb0c991fb46be Mon Sep 17 00:00:00 2001 From: Sidney Cadot <sidney@jigsaw.nl> Date: Tue, 7 Jan 2025 23:36:17 +0100 Subject: [PATCH 382/707] Fixed typo in color symbol definition. Fixes #2594. --- include/cbm264.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cbm264.h b/include/cbm264.h index a6317f384..ab634b721 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -97,7 +97,7 @@ #define COLOR_WHITE (BCOLOR_WHITE | CATTR_LUMA7) #define COLOR_RED (BCOLOR_RED | CATTR_LUMA4) #define COLOR_CYAN (BCOLOR_CYAN | CATTR_LUMA7) -#define COLOR_PURPLE (BCOLOR_LIGHVIOLET | CATTR_LUMA7) +#define COLOR_PURPLE (BCOLOR_LIGHTVIOLET | CATTR_LUMA7) #define COLOR_GREEN (BCOLOR_GREEN | CATTR_LUMA7) #define COLOR_BLUE (BCOLOR_BLUE | CATTR_LUMA7) #define COLOR_YELLOW (BCOLOR_YELLOW | CATTR_LUMA7) From 67da1e712343d443cd8c69cd2310fd47d108ee59 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 12 Jan 2025 18:57:31 +0100 Subject: [PATCH 383/707] add makefile for simulator samples --- samples/sim65/Makefile | 61 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 samples/sim65/Makefile diff --git a/samples/sim65/Makefile b/samples/sim65/Makefile new file mode 100644 index 000000000..865594736 --- /dev/null +++ b/samples/sim65/Makefile @@ -0,0 +1,61 @@ + +# Run 'make SYS=<target>'; or, set a SYS env. +# var. to build for another target system. +SYS ?= sim6502 + +# Just the usual way to find out if we're +# using cmd.exe to execute make rules. +ifneq ($(shell echo),) + CMD_EXE = 1 +endif + +ifdef CMD_EXE + NULLDEV = nul: + DEL = -del /f + RMDIR = rmdir /s /q +else + NULLDEV = /dev/null + DEL = $(RM) + RMDIR = $(RM) -r +endif + +ifdef CC65_HOME + AS = $(CC65_HOME)/bin/ca65 + CC = $(CC65_HOME)/bin/cc65 + CL = $(CC65_HOME)/bin/cl65 + LD = $(CC65_HOME)/bin/ld65 +else + AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65) + CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65) + CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) + LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) +endif + +EXELIST_sim6502 = \ + cpumode_example.bin \ + timer_example.bin \ + trace_example.bin + +ifneq ($(EXELIST_$(SYS)),) +samples: $(EXELIST_$(SYS)) +else +samples: notavailable +endif + +# empty target used to skip systems that will not work with any program in this dir +notavailable: +ifeq ($(MAKELEVEL),0) + @echo "info: sim65 tests not available for" $(SYS) +else +# suppress the "nothing to be done for 'samples' message + @echo > $(NULLDEV) +endif + +.SUFFIXES: +.SUFFIXES: .c .bin + +%.bin : %.c + $(CL) -t $(SYS) -Oris -m $*.map -o $@ $< + +clean: + @$(DEL) *.o *.map *.bin 2>$(NULLDEV) From 734a76c15862b22ccedfe1c4ea1191e70872f134 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 12 Jan 2025 19:03:39 +0100 Subject: [PATCH 384/707] added missing directories to "install" target --- samples/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/samples/Makefile b/samples/Makefile index 0e5292306..3680f542c 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -562,6 +562,11 @@ install: $(INSTALL) -d $(DESTDIR)$(samplesdir)/cbm $(INSTALL) -d $(DESTDIR)$(samplesdir)/gamate $(INSTALL) -d $(DESTDIR)$(samplesdir)/supervision + $(INSTALL) -d $(DESTDIR)$(samplesdir)/disasm + $(INSTALL) -d $(DESTDIR)$(samplesdir)/kim1 + $(INSTALL) -d $(DESTDIR)$(samplesdir)/lynx + $(INSTALL) -d $(DESTDIR)$(samplesdir)/sim65 + $(INSTALL) -d $(DESTDIR)$(samplesdir)/sym1 $(INSTALL) -m0644 *.* $(DESTDIR)$(samplesdir) $(INSTALL) -m0644 readme.txt $(DESTDIR)$(samplesdir) $(INSTALL) -m0644 Makefile $(DESTDIR)$(samplesdir) @@ -573,6 +578,11 @@ install: $(INSTALL) -m0644 cbm/*.* $(DESTDIR)$(samplesdir)/cbm $(INSTALL) -m0644 gamate/*.* $(DESTDIR)$(samplesdir)/gamate $(INSTALL) -m0644 supervision/*.* $(DESTDIR)$(samplesdir)/supervision + $(INSTALL) -m0644 disasm/*.* $(DESTDIR)$(samplesdir)/disasm + $(INSTALL) -m0644 kim1/*.* $(DESTDIR)$(samplesdir)/kim1 + $(INSTALL) -m0644 lynx/*.* $(DESTDIR)$(samplesdir)/lynx + $(INSTALL) -m0644 sim65/*.* $(DESTDIR)$(samplesdir)/sim65 + $(INSTALL) -m0644 sym1/*.* $(DESTDIR)$(samplesdir)/sym1 # -------------------------------------------------------------------------- # Packaging rules From 99b113de64e4505b85ab5bff1cfc7024c3478b1d Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Sun, 19 Jan 2025 16:51:11 +0100 Subject: [PATCH 385/707] Make memory between the end of the text screen and the start of the loaded program available to the linker. --- cfg/apple2-hgr.cfg | 2 ++ cfg/apple2-overlay.cfg | 2 ++ cfg/apple2-system.cfg | 2 ++ cfg/apple2.cfg | 2 ++ cfg/apple2enh-hgr.cfg | 2 ++ cfg/apple2enh-overlay.cfg | 2 ++ cfg/apple2enh-system.cfg | 2 ++ cfg/apple2enh.cfg | 2 ++ 8 files changed, 16 insertions(+) diff --git a/cfg/apple2-hgr.cfg b/cfg/apple2-hgr.cfg index 109fbe4f6..402e53b34 100644 --- a/cfg/apple2-hgr.cfg +++ b/cfg/apple2-hgr.cfg @@ -17,6 +17,7 @@ MEMORY { MAIN: file = %O, define = yes, start = %S, size = __HIMEM__ - %S; BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; + LOW: file = "", define = yes, start = $0800, size = %S - $0800; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -31,6 +32,7 @@ SEGMENTS { ONCE: load = MAIN, type = ro, define = yes; LC: load = MAIN, run = LC, type = ro, optional = yes; BSS: load = BSS, type = bss, define = yes; + LOWBSS: load = LOW, type = bss, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2-overlay.cfg b/cfg/apple2-overlay.cfg index 754ece90f..512b19c16 100644 --- a/cfg/apple2-overlay.cfg +++ b/cfg/apple2-overlay.cfg @@ -25,6 +25,7 @@ MEMORY { MAIN: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = __HIMEM__ - __OVERLAYSIZE__ - %S; BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; + LOW: file = "", define = yes, start = $0800, size = %S - $0800; OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; @@ -47,6 +48,7 @@ SEGMENTS { ONCE: load = MAIN, type = ro, define = yes; LC: load = MAIN, run = LC, type = ro, optional = yes; BSS: load = BSS, type = bss, define = yes; + LOWBSS: load = LOW, type = bss, optional = yes; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes; diff --git a/cfg/apple2-system.cfg b/cfg/apple2-system.cfg index 3dd94d793..8720ae800 100644 --- a/cfg/apple2-system.cfg +++ b/cfg/apple2-system.cfg @@ -13,6 +13,7 @@ MEMORY { MAIN: file = %O, define = yes, start = $2000, size = $BF00 - $2000; BSS: file = "", start = __ONCE_RUN__, size = $BF00 - __STACKSIZE__ - __ONCE_RUN__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; + LOW: file = "", define = yes, start = $0800, size = $2000 - $0800; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -26,6 +27,7 @@ SEGMENTS { ONCE: load = MAIN, type = ro, define = yes; LC: load = MAIN, run = LC, type = ro, optional = yes; BSS: load = BSS, type = bss, define = yes; + LOWBSS: load = LOW, type = bss, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2.cfg b/cfg/apple2.cfg index 19932b1f9..c33bdee2d 100644 --- a/cfg/apple2.cfg +++ b/cfg/apple2.cfg @@ -17,6 +17,7 @@ MEMORY { MAIN: file = %O, define = yes, start = %S, size = __HIMEM__ - %S; BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; + LOW: file = "", define = yes, start = $0800, size = %S - $0800; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -30,6 +31,7 @@ SEGMENTS { ONCE: load = MAIN, type = ro, define = yes; LC: load = MAIN, run = LC, type = ro, optional = yes; BSS: load = BSS, type = bss, define = yes; + LOWBSS: load = LOW, type = bss, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2enh-hgr.cfg b/cfg/apple2enh-hgr.cfg index 109fbe4f6..402e53b34 100644 --- a/cfg/apple2enh-hgr.cfg +++ b/cfg/apple2enh-hgr.cfg @@ -17,6 +17,7 @@ MEMORY { MAIN: file = %O, define = yes, start = %S, size = __HIMEM__ - %S; BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; + LOW: file = "", define = yes, start = $0800, size = %S - $0800; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -31,6 +32,7 @@ SEGMENTS { ONCE: load = MAIN, type = ro, define = yes; LC: load = MAIN, run = LC, type = ro, optional = yes; BSS: load = BSS, type = bss, define = yes; + LOWBSS: load = LOW, type = bss, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2enh-overlay.cfg b/cfg/apple2enh-overlay.cfg index 754ece90f..512b19c16 100644 --- a/cfg/apple2enh-overlay.cfg +++ b/cfg/apple2enh-overlay.cfg @@ -25,6 +25,7 @@ MEMORY { MAIN: file = %O, define = yes, start = %S + __OVERLAYSIZE__, size = __HIMEM__ - __OVERLAYSIZE__ - %S; BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; + LOW: file = "", define = yes, start = $0800, size = %S - $0800; OVL1: file = "%O.1", start = %S, size = __OVERLAYSIZE__; OVL2: file = "%O.2", start = %S, size = __OVERLAYSIZE__; OVL3: file = "%O.3", start = %S, size = __OVERLAYSIZE__; @@ -47,6 +48,7 @@ SEGMENTS { ONCE: load = MAIN, type = ro, define = yes; LC: load = MAIN, run = LC, type = ro, optional = yes; BSS: load = BSS, type = bss, define = yes; + LOWBSS: load = LOW, type = bss, optional = yes; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes; OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes; diff --git a/cfg/apple2enh-system.cfg b/cfg/apple2enh-system.cfg index 3dd94d793..8720ae800 100644 --- a/cfg/apple2enh-system.cfg +++ b/cfg/apple2enh-system.cfg @@ -13,6 +13,7 @@ MEMORY { MAIN: file = %O, define = yes, start = $2000, size = $BF00 - $2000; BSS: file = "", start = __ONCE_RUN__, size = $BF00 - __STACKSIZE__ - __ONCE_RUN__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; + LOW: file = "", define = yes, start = $0800, size = $2000 - $0800; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -26,6 +27,7 @@ SEGMENTS { ONCE: load = MAIN, type = ro, define = yes; LC: load = MAIN, run = LC, type = ro, optional = yes; BSS: load = BSS, type = bss, define = yes; + LOWBSS: load = LOW, type = bss, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/apple2enh.cfg b/cfg/apple2enh.cfg index 19932b1f9..c33bdee2d 100644 --- a/cfg/apple2enh.cfg +++ b/cfg/apple2enh.cfg @@ -17,6 +17,7 @@ MEMORY { MAIN: file = %O, define = yes, start = %S, size = __HIMEM__ - %S; BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__; LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__; + LOW: file = "", define = yes, start = $0800, size = %S - $0800; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; @@ -30,6 +31,7 @@ SEGMENTS { ONCE: load = MAIN, type = ro, define = yes; LC: load = MAIN, run = LC, type = ro, optional = yes; BSS: load = BSS, type = bss, define = yes; + LOWBSS: load = LOW, type = bss, optional = yes; } FEATURES { CONDES: type = constructor, From fb12363a6a4eb559ab28b12edd57c3d45e535340 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Fri, 31 Jan 2025 20:26:35 +0100 Subject: [PATCH 386/707] Fixed cassette boot file header #2600 --- libsrc/atari/cashdr.s | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libsrc/atari/cashdr.s b/libsrc/atari/cashdr.s index 99aefe68f..d4824f816 100644 --- a/libsrc/atari/cashdr.s +++ b/libsrc/atari/cashdr.s @@ -31,6 +31,8 @@ _cas_hdr: ldy #80 sta (SAVMSC),y .endif + lda #$3c + sta PACTL clc rts From 46b2f95ac892769785408a086da7c015f39f6c4a Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Fri, 31 Jan 2025 20:56:59 +0100 Subject: [PATCH 387/707] comment --- libsrc/atari/cashdr.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/atari/cashdr.s b/libsrc/atari/cashdr.s index d4824f816..c00ee98c2 100644 --- a/libsrc/atari/cashdr.s +++ b/libsrc/atari/cashdr.s @@ -31,7 +31,7 @@ _cas_hdr: ldy #80 sta (SAVMSC),y .endif - lda #$3c + lda #$3c ; motor off sta PACTL clc rts From 0082473630675bdc91e323fbadde7d68260cdba5 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Sun, 23 Feb 2025 00:35:23 +0100 Subject: [PATCH 388/707] Atari: fix fallout of change of INIT segment to 'bss' type The size of the load chunk was calculated incorrectly in exehdr.s since the INIT segment is no longer being part of the file anymore. While at it, change atari-cassette.cfg so that order of BSS and INIT is the same as in the other configs. See 692f96409d4e809d8 why it was in different order. --- cfg/atari-cassette.cfg | 2 +- cfg/atari-overlay.cfg | 2 +- cfg/atari-xex.cfg | 2 +- cfg/atari.cfg | 2 +- cfg/atarixl-largehimem.cfg | 2 +- cfg/atarixl-overlay.cfg | 2 +- cfg/atarixl-xex.cfg | 2 +- cfg/atarixl.cfg | 2 +- libsrc/atari/cashdr.s | 6 +++--- libsrc/atari/exehdr.s | 4 ++-- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cfg/atari-cassette.cfg b/cfg/atari-cassette.cfg index 13b34cc73..1d7d02f93 100644 --- a/cfg/atari-cassette.cfg +++ b/cfg/atari-cassette.cfg @@ -22,8 +22,8 @@ SEGMENTS { CODE: load = MAIN, type = ro, define = yes; RODATA: load = MAIN, type = ro, optional = yes; DATA: load = MAIN, type = rw, optional = yes; + INIT: load = MAIN, type = bss, define = yes, optional = yes; BSS: load = MAIN, type = bss, define = yes, optional = yes; - INIT: load = MAIN, type = bss, optional = yes; } FEATURES { CONDES: type = constructor, diff --git a/cfg/atari-overlay.cfg b/cfg/atari-overlay.cfg index 60f98e453..1dde26331 100644 --- a/cfg/atari-overlay.cfg +++ b/cfg/atari-overlay.cfg @@ -52,7 +52,7 @@ SEGMENTS { CODE: load = MAIN, type = ro, define = yes; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - INIT: load = MAIN, type = bss, optional = yes; + INIT: load = MAIN, type = bss, define = yes, optional = yes; BSS: load = MAIN, type = bss, define = yes; AUTOSTRT: load = TRAILER, type = ro; OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes; diff --git a/cfg/atari-xex.cfg b/cfg/atari-xex.cfg index deab5c7a5..1ab60af2e 100644 --- a/cfg/atari-xex.cfg +++ b/cfg/atari-xex.cfg @@ -36,7 +36,7 @@ SEGMENTS { CODE: load = MAIN, type = ro, define = yes; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - INIT: load = MAIN, type = bss, optional = yes; + INIT: load = MAIN, type = bss, define = yes, optional = yes; BSS: load = MAIN, type = bss, define = yes; } FEATURES { diff --git a/cfg/atari.cfg b/cfg/atari.cfg index 37337ea53..0af121de3 100644 --- a/cfg/atari.cfg +++ b/cfg/atari.cfg @@ -40,7 +40,7 @@ SEGMENTS { CODE: load = MAIN, type = ro, define = yes; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - INIT: load = MAIN, type = bss, optional = yes; + INIT: load = MAIN, type = bss, define = yes, optional = yes; BSS: load = MAIN, type = bss, define = yes; AUTOSTRT: load = TRAILER, type = ro; } diff --git a/cfg/atarixl-largehimem.cfg b/cfg/atarixl-largehimem.cfg index 8f70597aa..6df9b3f80 100644 --- a/cfg/atarixl-largehimem.cfg +++ b/cfg/atarixl-largehimem.cfg @@ -67,7 +67,7 @@ SEGMENTS { CODE: load = MAIN, type = ro, define = yes; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - INIT: load = MAIN, type = bss, optional = yes; + INIT: load = MAIN, type = bss, define = yes, optional = yes; BSS: load = MAIN, type = bss, define = yes; AUTOSTRT: load = TRAILER, type = ro; } diff --git a/cfg/atarixl-overlay.cfg b/cfg/atarixl-overlay.cfg index 3b8da4256..5cfdcdbc5 100644 --- a/cfg/atarixl-overlay.cfg +++ b/cfg/atarixl-overlay.cfg @@ -78,7 +78,7 @@ SEGMENTS { CODE: load = MAIN, type = ro, define = yes; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - INIT: load = MAIN, type = bss, optional = yes; + INIT: load = MAIN, type = bss, define = yes, optional = yes; BSS: load = MAIN, type = bss, define = yes; AUTOSTRT: load = TRAILER, type = ro; diff --git a/cfg/atarixl-xex.cfg b/cfg/atarixl-xex.cfg index 853096c6f..a0a4a971d 100644 --- a/cfg/atarixl-xex.cfg +++ b/cfg/atarixl-xex.cfg @@ -58,7 +58,7 @@ SEGMENTS { CODE: load = MAIN, type = ro, define = yes; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - INIT: load = MAIN, type = bss, optional = yes; + INIT: load = MAIN, type = bss, define = yes, optional = yes; BSS: load = MAIN, type = bss, define = yes; SRPREPHDR: load = UNUSED, type = ro; SRPREPTRL: load = UNUSED, type = ro; diff --git a/cfg/atarixl.cfg b/cfg/atarixl.cfg index 1517afb5a..5e7199cd3 100644 --- a/cfg/atarixl.cfg +++ b/cfg/atarixl.cfg @@ -65,7 +65,7 @@ SEGMENTS { CODE: load = MAIN, type = ro, define = yes; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; - INIT: load = MAIN, type = bss, optional = yes; + INIT: load = MAIN, type = bss, define = yes, optional = yes; BSS: load = MAIN, type = bss, define = yes; AUTOSTRT: load = TRAILER, type = ro; } diff --git a/libsrc/atari/cashdr.s b/libsrc/atari/cashdr.s index c00ee98c2..c0d64a56b 100644 --- a/libsrc/atari/cashdr.s +++ b/libsrc/atari/cashdr.s @@ -10,10 +10,10 @@ .include "atari.inc" - .import __BSS_RUN__, __STARTADDRESS__, _cas_init + .import __INIT_RUN__, __STARTADDRESS__, _cas_init .export _cas_hdr -.assert ((__BSS_RUN__ - __STARTADDRESS__ + 127) / 128) < $101, error, "File to big to load from cassette" +.assert ((__INIT_RUN__ - __STARTADDRESS__ + 127) / 128) < $101, error, "File to big to load from cassette" ; for a description of the cassette header, see De Re Atari, appendix C @@ -22,7 +22,7 @@ _cas_hdr: .byte 0 ; ignored - .byte <((__BSS_RUN__ - __STARTADDRESS__ + 127) / 128) ; # of 128-byte records to read + .byte <((__INIT_RUN__ - __STARTADDRESS__ + 127) / 128) ; # of 128-byte records to read .word __STARTADDRESS__ ; load address .word _cas_init ; init address diff --git a/libsrc/atari/exehdr.s b/libsrc/atari/exehdr.s index 7abb7c1ac..fe17aeafd 100644 --- a/libsrc/atari/exehdr.s +++ b/libsrc/atari/exehdr.s @@ -1,11 +1,11 @@ ; This file defines the EXE header and main chunk load header for Atari executables .export __EXEHDR__: absolute = 1 - .import __MAIN_START__, __BSS_LOAD__ + .import __MAIN_START__, __INIT_LOAD__ .segment "EXEHDR" .word $FFFF .segment "MAINHDR" .word __MAIN_START__ - .word __BSS_LOAD__ - 1 + .word __INIT_LOAD__ - 1 From 04ada63935c6ac6eb57ab47ff08fb74ad0f19478 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Sun, 23 Feb 2025 01:06:08 +0100 Subject: [PATCH 389/707] Atari: let crt0.s always provide an (empty) INIT segment --- libsrc/atari/crt0.s | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libsrc/atari/crt0.s b/libsrc/atari/crt0.s index 381aa699f..50e3ca7b6 100644 --- a/libsrc/atari/crt0.s +++ b/libsrc/atari/crt0.s @@ -204,6 +204,10 @@ APPMHI_save: .res 2 ; ------------------------------------------------------------------------ +.segment "INIT" ; have at least one (empty) segment of INIT, exehdr.s needs its definition + +; ------------------------------------------------------------------------ + .segment "LOWCODE" ; have at least one (empty) segment of LOWCODE, so that the next line works even if the program doesn't make use of this segment .assert (__LOWCODE_RUN__ + __LOWCODE_SIZE__ <= $4000 || __LOWCODE_RUN__ > $7FFF || __LOWCODE_SIZE__ = 0), warning, "'lowcode area' reaches into $4000..$7FFF bank memory window" ; check for LOWBSS_SIZE = 0 not needed since the only file which uses LOWBSS (irq.s) also uses LOWCODE From b0220e545664d501b6fa2478f66e00567deac4b2 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Sun, 2 Mar 2025 09:26:31 +0100 Subject: [PATCH 390/707] fix problem in _get_tv for GEOS CBM Found by mkslack, see #2046 --- libsrc/geos-cbm/system/get_ostype.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/geos-cbm/system/get_ostype.s b/libsrc/geos-cbm/system/get_ostype.s index 6e6731952..9ba8b7982 100644 --- a/libsrc/geos-cbm/system/get_ostype.s +++ b/libsrc/geos-cbm/system/get_ostype.s @@ -82,8 +82,8 @@ tvmode: ; PAL/NTSC check here, result in A pha lda #IO_IN ; enable access to I/O sta CPU_DATA - bit rasreg - bpl tvmode ; wait for rasterline 127<x<256 +: bit rasreg + bpl :- ; wait for rasterline 127<x<256 lda #24 ; (rasterline now >=256!) modelp: cmp rasreg ; wait for rasterline = 24 (or 280 on PAL) From 16224cdd36b30c43d17d2b15a1096de1f24cc763 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 4 Mar 2025 23:07:13 +0100 Subject: [PATCH 391/707] atari5200: fix _clrscr to use correct screen size Could be different than default when linking with atari5200-conioscreen-20x12.o. --- cfg/atari5200.cfg | 2 +- libsrc/atari5200/clrscr.s | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cfg/atari5200.cfg b/cfg/atari5200.cfg index e8f6d44a5..a487bdcab 100644 --- a/cfg/atari5200.cfg +++ b/cfg/atari5200.cfg @@ -15,7 +15,7 @@ MEMORY { SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; EXTZP: load = ZP, type = zp, optional = yes; - DLIST: load = ROM , type = ro, define = yes, optional = yes; + DLIST: load = ROM, type = ro, define = yes, optional = yes; STARTUP: load = ROM, type = ro, define = yes, optional = yes; LOWCODE: load = ROM, type = ro, define = yes, optional = yes; ONCE: load = ROM, type = ro, optional = yes; diff --git a/libsrc/atari5200/clrscr.s b/libsrc/atari5200/clrscr.s index 041f34a67..d92419b9e 100644 --- a/libsrc/atari5200/clrscr.s +++ b/libsrc/atari5200/clrscr.s @@ -7,8 +7,9 @@ .export _clrscr .include "atari5200.inc" .importzp ptr1 + .importzp screen_width, screen_height -SCRSIZE = 480 ; 20x24: size of default conio atari5200 screen +SCRSIZE = screen_width * screen_height _clrscr:lda SAVMSC ; screen memory sta ptr1 From 02470a23432fe37dec69766319314931a57adb77 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Tue, 4 Mar 2025 23:39:38 +0100 Subject: [PATCH 392/707] atari5200: fix conio screen initialization Screen memory clearing was wrong, now uses _clrscr function. --- libsrc/atari5200/conioscreen.s | 20 +++----------------- libsrc/atari5200/extra/conioscreen-20x12.s | 20 +++----------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/libsrc/atari5200/conioscreen.s b/libsrc/atari5200/conioscreen.s index 8c78fd44f..0c77b14c7 100644 --- a/libsrc/atari5200/conioscreen.s +++ b/libsrc/atari5200/conioscreen.s @@ -7,6 +7,7 @@ SCREEN_BUF_SIZE = 20 * 24 SCREEN_BUF = $4000 - SCREEN_BUF_SIZE + .import _clrscr .export screen_setup .export screen_width, screen_height .export conio_color @@ -26,24 +27,10 @@ screen_setup: lda #>SCREEN_BUF sta SAVMSC+1 - ; initialize cursor position - lda #0 - sta COLCRS_5200 - sta ROWCRS_5200 - ; clear screen buffer - ldy #<(SCREEN_BUF_SIZE-1) - ldx #>(SCREEN_BUF_SIZE-1) -clrscr: sta (SAVMSC),y - dey - cpy #$FF - bne clrscr - dex - cpx #$FF - bne clrscr + jsr _clrscr ; set default colors - lda #GTIA_COLOR_WHITE sta COLOR0 lda #GTIA_COLOR_LIGHTRED @@ -55,7 +42,6 @@ clrscr: sta (SAVMSC),y sta COLOR4 ; background ; set display list - lda #<dlist sta SDLSTL lda #>dlist @@ -82,7 +68,7 @@ dlist: .repeat 3 .byte DL_CHR20x8x2 .endrepeat - .byte DL_JVB + .byte DL_JVB .word dlist ; end of display list diff --git a/libsrc/atari5200/extra/conioscreen-20x12.s b/libsrc/atari5200/extra/conioscreen-20x12.s index aeb11cb43..c2aa0a65f 100644 --- a/libsrc/atari5200/extra/conioscreen-20x12.s +++ b/libsrc/atari5200/extra/conioscreen-20x12.s @@ -7,6 +7,7 @@ SCREEN_BUF_SIZE = 20 * 12 SCREEN_BUF = $4000 - SCREEN_BUF_SIZE + .import _clrscr .export screen_setup .export screen_width, screen_height .export conio_color @@ -26,24 +27,10 @@ screen_setup: lda #>SCREEN_BUF sta SAVMSC+1 - ; initialize cursor position - lda #0 - sta COLCRS_5200 - sta ROWCRS_5200 - ; clear screen buffer - ldy #<(SCREEN_BUF_SIZE-1) - ldx #>(SCREEN_BUF_SIZE-1) -clrscr: sta (SAVMSC),y - dey - cpy #$FF - bne clrscr - dex - cpx #$FF - bne clrscr + jsr _clrscr ; set default colors - lda #GTIA_COLOR_WHITE sta COLOR0 lda #GTIA_COLOR_LIGHTRED @@ -55,7 +42,6 @@ clrscr: sta (SAVMSC),y sta COLOR4 ; background ; set display list - lda #<dlist sta SDLSTL lda #>dlist @@ -82,7 +68,7 @@ dlist: .repeat 3 .byte DL_CHR20x16x2 .endrepeat - .byte DL_JVB + .byte DL_JVB .word dlist ; end of display list From 020fe4028ac2a3c4ca56aa16cca9ca290e91392d Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Wed, 5 Mar 2025 18:26:13 +0100 Subject: [PATCH 393/707] Fix RANGE ERROR STOPPED AT 8214 On a 48k Apple II, the BLTU2 call throws an error, even when there is nothing to copy in the LC segment. Add an alternative LC copy, based on memcpy, to an extra file that the user can link in as with iobuf-0800. This memcpy-based version allows our programs to run on Integer ROM apple2. It costs 21 bytes in binary size, plus memcpy (60 bytes in binary size + RAM use) if it wasn't already linked in. --- libsrc/apple2/crt0.s | 4 +++- libsrc/apple2/extra/lc-copy-memcpy.s | 33 ++++++++++++++++++++++++++++ libsrc/apple2/lc-copy-applesoft.s | 9 ++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 libsrc/apple2/extra/lc-copy-memcpy.s create mode 100644 libsrc/apple2/lc-copy-applesoft.s diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index 42e26c27b..4b9a59153 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -10,6 +10,7 @@ .import initlib, _exit .import zerobss, callmain + .import bltu2 .import __ONCE_LOAD__, __ONCE_SIZE__ ; Linker generated .import __LC_START__, __LC_LAST__ ; Linker generated @@ -93,6 +94,7 @@ basic: lda HIMEM ; Call the module constructors. jsr initlib + ; Copy the LC segment to its destination ; Switch in LC bank 2 for W/O. bit $C081 bit $C081 @@ -120,7 +122,7 @@ basic: lda HIMEM ; Call into Applesoft Block Transfer Up -- which handles zero- ; sized blocks well -- to move the content of the LC memory area. - jsr $D39A ; BLTU2 + jsr bltu2 ; BLTU2 ; Switch in LC bank 2 for R/O and return. bit $C080 diff --git a/libsrc/apple2/extra/lc-copy-memcpy.s b/libsrc/apple2/extra/lc-copy-memcpy.s new file mode 100644 index 000000000..c4dc8d8ef --- /dev/null +++ b/libsrc/apple2/extra/lc-copy-memcpy.s @@ -0,0 +1,33 @@ +; +; Colin Leroy-Mira, 06.03.2025 +; +; Copy the LC segment from the end of the binary to the Language Card +; using _memcpy. This allows running apple2 programs on the original +; Integer ROM Apple ][. +; + + .export bltu2 + + .import _memcpy, pushax + .import __ONCE_LOAD__, __ONCE_SIZE__ ; Linker generated + .import __LC_START__, __LC_LAST__ ; Linker generated + + .segment "ONCE" + +bltu2: + ; Get the destination start address. + lda #<__LC_START__ + ldx #>__LC_START__ + jsr pushax + + ; Get the source start address. + lda #<(__ONCE_LOAD__ + __ONCE_SIZE__) + ldx #>(__ONCE_LOAD__ + __ONCE_SIZE__) + jsr pushax + + ; Set the length + lda #<(__LC_LAST__ - __LC_START__) + ldx #>(__LC_LAST__ - __LC_START__) + + ; And do the copy + jmp _memcpy diff --git a/libsrc/apple2/lc-copy-applesoft.s b/libsrc/apple2/lc-copy-applesoft.s new file mode 100644 index 000000000..70a04431d --- /dev/null +++ b/libsrc/apple2/lc-copy-applesoft.s @@ -0,0 +1,9 @@ +; +; Oliver Schmidt, 15.09.2009 +; +; Copy the LC segment from the end of the binary to the Language Card +; using AppleSoft's BLTU2 routine. +; + .export bltu2 + +bltu2 := $D39A From c8eb6e2dd55b4cf1a1e8dd481bfe0b7d66e5ace0 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Thu, 6 Mar 2025 17:20:23 +0100 Subject: [PATCH 394/707] Apple II: Document BLTU alternative --- doc/apple2.sgml | 21 +++++++++++++++++++ libsrc/apple2/crt0.s | 2 +- ...c-copy-memcpy.s => integer-basic-compat.s} | 0 3 files changed, 22 insertions(+), 1 deletion(-) rename libsrc/apple2/extra/{lc-copy-memcpy.s => integer-basic-compat.s} (100%) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index ffe0e2397..28120577a 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -92,7 +92,28 @@ several useful settings: </descrip><p> +<descrip> + <tag/Installing your code in the Language Card/ + The code in the LC segment will automatically be copied from the end of the + binary into the Language Card at startup, even if the segment is empty (a + 0-byte copy). This allows for tighter code. This code will be copied using the + Applesoft BLTU2 function that is available starting with the Apple ][+, + but not in the original Apple ][ with an Integer BASIC ROM. This shows as + a "RANGE ERROR. STOPPING AT ..." message on startup. + + If you want to target the Integer BASIC original Apple ][, you can link in an + alternative implementation of the LC segment loading, at the cost of linking + in memcpy (60 bytes): + + Using <tt/apple2-integer-basic-compat.o/ is as simple as placing it on the linker + command line like this: + + <tscreen><verb> + cl65 -t apple2 myprog.c apple2-integer-basic-compat.o + </verb></tscreen> + +</descrip> <sect>Linker configurations<label id="link-configs"><p> diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index 4b9a59153..628303687 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -122,7 +122,7 @@ basic: lda HIMEM ; Call into Applesoft Block Transfer Up -- which handles zero- ; sized blocks well -- to move the content of the LC memory area. - jsr bltu2 ; BLTU2 + jsr bltu2 ; Switch in LC bank 2 for R/O and return. bit $C080 diff --git a/libsrc/apple2/extra/lc-copy-memcpy.s b/libsrc/apple2/extra/integer-basic-compat.s similarity index 100% rename from libsrc/apple2/extra/lc-copy-memcpy.s rename to libsrc/apple2/extra/integer-basic-compat.s From fd4c1e193dea6a2bc3de79a8c745515e5b84559b Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 12 Mar 2025 14:19:20 +0100 Subject: [PATCH 395/707] Completely disable/enable 80 column firmware. The //e 80 column firmware allows to switch between 80 and 40 clumns without clearing the screen. So far, I made that feature available via videomode(). However thinking about it once more, I don't see a C program making use of it. A C program rather benefits from the consistent behavior of videomode() always clearing the screen. Apart from that, the (default) 40 column display and the 40 column display with 80 column firmware active, behave differently (CH vs. OURCH) which causes subtile issues. Those issues can be avoid altogether by simply always deactivating the 80 column firmware when switching from 80 column display to 40 column display. Of course, those issues are also relevant, if the 40 column display with 80 column firmware is already active when the C program starts. However, I have reasons to believe that running the Apple II in that mode was/is very unpopular. --- include/apple2enh.h | 4 ++-- libsrc/apple2/videomode.s | 42 +++++++-------------------------------- 2 files changed, 9 insertions(+), 37 deletions(-) diff --git a/include/apple2enh.h b/include/apple2enh.h index 3989d0b8d..864d24986 100644 --- a/include/apple2enh.h +++ b/include/apple2enh.h @@ -82,8 +82,8 @@ #define CH_F10 0xB0 /* Video modes */ -#define VIDEOMODE_40x24 0x0011 -#define VIDEOMODE_80x24 0x0012 +#define VIDEOMODE_40x24 0x15 +#define VIDEOMODE_80x24 0x00 #define VIDEOMODE_40COL VIDEOMODE_40x24 #define VIDEOMODE_80COL VIDEOMODE_80x24 diff --git a/libsrc/apple2/videomode.s b/libsrc/apple2/videomode.s index 13151a48a..414105b18 100644 --- a/libsrc/apple2/videomode.s +++ b/libsrc/apple2/videomode.s @@ -6,7 +6,6 @@ .ifdef __APPLE2ENH__ .export _videomode - .import COUT .include "apple2.inc" @@ -17,52 +16,25 @@ _videomode: bit RD80VID php - ; If we are in 80 column mode then the 80 column firmware is - ; known to be active so we can just print the ctrl-char code - ; (even if this only means staying in the current videomode) - bpl :+ - jsr COUT - bra done - - ; If we are in 40 column mode and want to set 40 column mode - ; then we explicitly do nothing as we neither know about the - ; current state of the 80 column firmware nor want to fix it -: cmp #$11 ; Ctrl-char code for 40 cols - beq done - - ; If we are in 40 column mode and want to set 80 column mode - ; then we first presume the 80 column firmware being already - ; active and print the ctrl-char code (this causes a garbage - ; char to be printed on the screen if isn't already active) - jsr COUT - - ; If we successfully switched to 80 column mode then the 80 - ; column firmware was in fact already active and we're done - bit RD80VID - bmi done - - ; The 80 column firmware isn't already active so we need to - ; initialize it - causing the screen to be cleared and thus - ; the garbage char printed above to be erased (but for some - ; reason the cursor horizontal position not to be zeroed) - stz CH - ; Initializing the 80 column firmware needs the ROM switched ; in, otherwise it would copy the F8 ROM to the LC (@ $CEF4) bit $C082 - ; Initialize 80 column firmware - jsr $C300 ; PR#3 + ; Call 80 column firmware with ctrl-char code + jsr $C300 ; Switch in LC bank 2 for R/O bit $C080 + ; Switch in alternate charset again + sta SETALTCHAR + ; Return ctrl-char code for setting previous ; videomode using the saved videomode flag -done: lda #$11 ; Ctrl-char code for 40 cols + lda #$15 ; Ctrl-char code for 40 cols plp bpl :+ - inc a ; Ctrl-char code for 80 cols + lda #$00 ; Ctrl-char code for 80 cols : rts ; X was preserved all the way .endif ; __APPLE2ENH__ From 7c2671be2a8c365f4254abec8682928ff72651de Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Wed, 12 Mar 2025 21:33:13 +0100 Subject: [PATCH 396/707] Disable interrupts during aux memory access. Interrupt handlers rather likely access text screen holes. Especially MSLOT is obligatory for every interrupt handler that requires access to an extension ROM ($C800-$CFFE) in order to be able to re-enable the extension ROM that was enabled when the interrupt occured. Those text screen holes only hold valid values in main memory so interrupts must be disabled while the aux memory text screen is mapped. --- libsrc/apple2/cgetc.s | 5 +++-- libsrc/apple2/cpeekc.s | 11 ++++++++--- libsrc/apple2/cputc.s | 16 +++++++++++----- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/libsrc/apple2/cgetc.s b/libsrc/apple2/cgetc.s index ecce9f9de..d2ebe5db8 100644 --- a/libsrc/apple2/cgetc.s +++ b/libsrc/apple2/cgetc.s @@ -9,6 +9,7 @@ .export _cgetc .import cursor, putchardirect + .include "zeropage.inc" .include "apple2.inc" _cgetc: @@ -22,7 +23,7 @@ _cgetc: .else lda #' ' | $40 ; Blank, flashing .endif - jsr putchardirect ; Returns old character in X + jsr putchardirect ; Saves old character in tmp3 ; Wait for keyboard strobe. : inc RNDL ; Increment random counter low @@ -37,7 +38,7 @@ _cgetc: ; Restore old character. pha - txa + lda tmp3 jsr putchardirect pla diff --git a/libsrc/apple2/cpeekc.s b/libsrc/apple2/cpeekc.s index a547f7867..200206177 100644 --- a/libsrc/apple2/cpeekc.s +++ b/libsrc/apple2/cpeekc.s @@ -11,18 +11,23 @@ _cpeekc: ldy CH .ifdef __APPLE2ENH__ + sec ; Assume main memory bit RD80VID ; In 80 column mode? bpl peek ; No, just go ahead tya lsr ; Div by 2 tay bcs peek ; Odd cols are in main memory + php + sei ; No valid MSLOT et al. in aux memory bit HISCR ; Assume SET80COL .endif peek: lda (BASL),Y ; Get character .ifdef __APPLE2ENH__ - bit LOWSCR ; Doesn't hurt in 40 column mode - .endif + bcs :+ ; In main memory + bit LOWSCR + plp +: .endif eor #$80 ; Invert high bit - ldx #$00 + ldx #>$0000 rts diff --git a/libsrc/apple2/cputc.s b/libsrc/apple2/cputc.s index 0a27abacd..2dcfa1e00 100644 --- a/libsrc/apple2/cputc.s +++ b/libsrc/apple2/cputc.s @@ -15,6 +15,7 @@ .import uppercasemask .endif + .include "zeropage.inc" .include "apple2.inc" .macpack cpu @@ -87,23 +88,28 @@ putchar: mask: and INVFLG ; Apply normal, inverse, flash putchardirect: - pha + tax .ifdef __APPLE2ENH__ lda CH + sec ; Assume main memory bit RD80VID ; In 80 column mode? bpl put ; No, just go ahead lsr ; Div by 2 bcs put ; Odd cols go in main memory + php + sei ; No valid MSLOT et al. in aux memory bit HISCR ; Assume SET80COL put: tay .else ldy CH .endif lda (BASL),Y ; Get current character - tax ; Return old character for _cgetc - pla + sta tmp3 ; Save old character for _cgetc + txa sta (BASL),Y .ifdef __APPLE2ENH__ - bit LOWSCR ; Doesn't hurt in 40 column mode - .endif + bcs :+ ; In main memory + bit LOWSCR + plp +: .endif rts From 3edb9592981c6cbcdfffafdf4799d2ae82fe3690 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 13 Mar 2025 21:31:01 +0100 Subject: [PATCH 397/707] Finally made CONIO and STDIO fully interoperable in 80 column mode. In order to avoid undefined behaviour of programs not aware of 80 column mode, the 80 column firmware deliberately doesn't use CH but OURCH. So in order to be fully interoperable, CONIO needs to do the same. This changes introduces that behavior. So far so good. But the 80 column firmware can also be active in 40 column mode. This scenario is not detectable with reasonable effort. Therefore the behaviour of CONIO in this scenario is _not_ improved. However, this scenario is supposed to be very uncommon - and a recent update to videomode() makes sure to not activate it anymore ourselves. Notes: * If a program wants to be 100% sure to not run in 40 column mode with 80 column firmware active it can call videomode(VIDEOMODE_40COL) to explicitly deactivate a potentially active 80 column firmware. However, this always implicitly clears the screen. * In 40 column mode (contrast to 80 column mode) the 80 column firmware updates CH to reflect OURCH. So as long as CONIO only reads CH, but doesn't update it, everything works as expected. Interestingly this makes a rather useful scenario of STDIO/CONIO interoperation work: Using STDIO for screen output and CONIO for keyboard input. When cgetc() is called after cursor(1), it has to write to the screen as there's no hardware cursor on the Apple II. Those writes work as expected even in 40 column mode with active 80 column firmware as CH is only read but not written. --- asminc/apple2.inc | 6 ++++++ libsrc/apple2/beep.s | 12 ++++++------ libsrc/apple2/bell.s | 20 -------------------- libsrc/apple2/cpeekc.s | 2 +- libsrc/apple2/cputc.s | 27 ++++++++++++++++++--------- libsrc/apple2/gotoxy.s | 5 +++++ libsrc/apple2/wherex.s | 7 ++++++- 7 files changed, 42 insertions(+), 37 deletions(-) delete mode 100644 libsrc/apple2/bell.s diff --git a/asminc/apple2.inc b/asminc/apple2.inc index 528c463a1..fb4a1b2f0 100644 --- a/asminc/apple2.inc +++ b/asminc/apple2.inc @@ -25,6 +25,12 @@ BRKVec := $03F0 ; Break vector SOFTEV := $03F2 ; Vector for warm start PWREDUP := $03F4 ; This must be = EOR #$A5 of SOFTEV+1 +;----------------------------------------------------------------------------- +; 80 column firmware + +OURCH := $057B ; Cursor horizontal position +OURCV := $05FB ; Cursor vertical position + ;----------------------------------------------------------------------------- ; Hardware diff --git a/libsrc/apple2/beep.s b/libsrc/apple2/beep.s index ebebb6e3f..84d132a3a 100644 --- a/libsrc/apple2/beep.s +++ b/libsrc/apple2/beep.s @@ -5,16 +5,16 @@ ; .export _beep - .import BELL .include "apple2.inc" .segment "LOWCODE" _beep: - lda CH ; Bell scrambles CH in 80col mode on IIgs, storing - pha ; it in OURCH and resetting CH to 0. Save it. - jsr BELL - pla - sta CH ; Restore CH + ; Switch in ROM and call BELL + bit $C082 + jsr $FF3A ; BELL + + ; Switch in LC bank 2 for R/O and return + bit $C080 rts diff --git a/libsrc/apple2/bell.s b/libsrc/apple2/bell.s deleted file mode 100644 index 28e6d24f8..000000000 --- a/libsrc/apple2/bell.s +++ /dev/null @@ -1,20 +0,0 @@ -; -; Colin Leroy-Mira, 2024 -; -; BELL routine -; - - .export BELL - - .include "apple2.inc" - - .segment "LOWCODE" - -BELL: - ; Switch in ROM and call BELL - bit $C082 - jsr $FF3A ; BELL - - ; Switch in LC bank 2 for R/O and return - bit $C080 - rts diff --git a/libsrc/apple2/cpeekc.s b/libsrc/apple2/cpeekc.s index 200206177..a6a082eab 100644 --- a/libsrc/apple2/cpeekc.s +++ b/libsrc/apple2/cpeekc.s @@ -14,7 +14,7 @@ _cpeekc: sec ; Assume main memory bit RD80VID ; In 80 column mode? bpl peek ; No, just go ahead - tya + lda OURCH lsr ; Div by 2 tay bcs peek ; Odd cols are in main memory diff --git a/libsrc/apple2/cputc.s b/libsrc/apple2/cputc.s index 2dcfa1e00..f60965f44 100644 --- a/libsrc/apple2/cputc.s +++ b/libsrc/apple2/cputc.s @@ -52,19 +52,29 @@ _cputc: cputdirect: jsr putchar + .ifdef __APPLE2ENH__ + bit RD80VID ; In 80 column mode? + bpl :+ + inc OURCH ; Bump to next column + lda OURCH + bra check ; Must leave CH alone +: .endif inc CH ; Bump to next column lda CH - cmp WNDWDTH - bcc :+ +check: cmp WNDWDTH + bcc done jsr newline left: - .if (.cpu .bitand CPU_ISET_65SC02) + .ifdef __APPLE2ENH__ stz CH ; Goto left edge of screen + bit RD80VID ; In 80 column mode? + bpl done + stz OURCH ; Goto left edge of screen .else lda #$00 ; Goto left edge of screen sta CH .endif -: rts +done: rts newline: inc CV ; Bump to next line @@ -89,21 +99,20 @@ mask: and INVFLG ; Apply normal, inverse, flash putchardirect: tax + ldy CH .ifdef __APPLE2ENH__ - lda CH sec ; Assume main memory bit RD80VID ; In 80 column mode? bpl put ; No, just go ahead + lda OURCH lsr ; Div by 2 + tay bcs put ; Odd cols go in main memory php sei ; No valid MSLOT et al. in aux memory bit HISCR ; Assume SET80COL -put: tay - .else - ldy CH .endif - lda (BASL),Y ; Get current character +put: lda (BASL),Y ; Get current character sta tmp3 ; Save old character for _cgetc txa sta (BASL),Y diff --git a/libsrc/apple2/gotoxy.s b/libsrc/apple2/gotoxy.s index 6755af8d8..2a0261eba 100644 --- a/libsrc/apple2/gotoxy.s +++ b/libsrc/apple2/gotoxy.s @@ -22,4 +22,9 @@ _gotoxy: _gotox: sta CH ; Store X + .ifdef __APPLE2ENH__ + bit RD80VID ; In 80 column mode? + bpl :+ + sta OURCH ; Store X +: .endif rts diff --git a/libsrc/apple2/wherex.s b/libsrc/apple2/wherex.s index bd717a22b..4d4f856f0 100644 --- a/libsrc/apple2/wherex.s +++ b/libsrc/apple2/wherex.s @@ -10,5 +10,10 @@ _wherex: lda CH - ldx #$00 + .ifdef __APPLE2ENH__ + bit RD80VID ; In 80 column mode? + bpl :+ + lda OURCH +: .endif + ldx #>$0000 rts From ee540678e6cc99aecf05912fec7c7ec21e66d27e Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Thu, 13 Mar 2025 22:03:37 +0100 Subject: [PATCH 398/707] Improved consistency of notation for return value promotion. --- libsrc/apple2/curdevice.s | 2 +- libsrc/apple2/diocommon.s | 2 +- libsrc/apple2/get_iigs_speed.s | 2 +- libsrc/apple2/getdevice.s | 2 +- libsrc/apple2/joy/a2.stdjoy.s | 4 ++-- libsrc/apple2/mou/a2.stdmou.s | 2 +- libsrc/apple2/open.s | 2 +- libsrc/apple2/oserror.s | 2 +- libsrc/apple2/revers.s | 2 +- libsrc/apple2/ser/a2.gs.s | 14 +++++++------- libsrc/apple2/ser/a2.ssc.s | 8 ++++---- libsrc/apple2/set_iigs_speed.s | 2 +- libsrc/apple2/stat.s | 2 +- libsrc/apple2/tgi/a2.hi.s | 2 +- libsrc/apple2/tgi/a2.lo.s | 2 +- libsrc/apple2/wherey.s | 2 +- 16 files changed, 26 insertions(+), 26 deletions(-) diff --git a/libsrc/apple2/curdevice.s b/libsrc/apple2/curdevice.s index 9781b8ad0..a450c605f 100644 --- a/libsrc/apple2/curdevice.s +++ b/libsrc/apple2/curdevice.s @@ -23,5 +23,5 @@ _getcurrentdevice: bne :+ lda #$FF ; INVALID_DEVICE -: ldx #$00 +: ldx #>$0000 rts diff --git a/libsrc/apple2/diocommon.s b/libsrc/apple2/diocommon.s index b18f0e6ef..6870ebb51 100644 --- a/libsrc/apple2/diocommon.s +++ b/libsrc/apple2/diocommon.s @@ -31,5 +31,5 @@ diocommon: dioepilog: ; Return success or error sta ___oserror - ldx #$00 + ldx #>$0000 rts diff --git a/libsrc/apple2/get_iigs_speed.s b/libsrc/apple2/get_iigs_speed.s index 1915d7773..b960516fa 100644 --- a/libsrc/apple2/get_iigs_speed.s +++ b/libsrc/apple2/get_iigs_speed.s @@ -16,7 +16,7 @@ _get_iigs_speed: lda CYAREG ; Check current setting bpl :+ lda #SPEED_FAST - ldx #$00 + ldx #>$0000 rts .assert SPEED_SLOW = 0, error : jmp return0 ; SPEED_SLOW diff --git a/libsrc/apple2/getdevice.s b/libsrc/apple2/getdevice.s index 0c674cad0..f3b0d5a86 100644 --- a/libsrc/apple2/getdevice.s +++ b/libsrc/apple2/getdevice.s @@ -30,5 +30,5 @@ next: inx bne next done: txa - ldx #$00 + ldx #>$0000 rts diff --git a/libsrc/apple2/joy/a2.stdjoy.s b/libsrc/apple2/joy/a2.stdjoy.s index 11be52eb4..b5e7a311b 100644 --- a/libsrc/apple2/joy/a2.stdjoy.s +++ b/libsrc/apple2/joy/a2.stdjoy.s @@ -92,7 +92,7 @@ COUNT: bvc noiic ; Not $4x dex ; Only one joystick for the //c noiic: txa ; Number of joysticks we support - ldx #$00 + ldx #>$0000 rts ; READ routine. Read a particular joystick passed in A. @@ -170,5 +170,5 @@ nogs2: lda #$00 ; 0 0 0 0 0 0 0 0 ; Finalize eor #%00010100 ; BTN_2 BTN_1 DOWN UP RIGHT LEFT 0 0 - ldx #$00 + ldx #>$0000 rts diff --git a/libsrc/apple2/mou/a2.stdmou.s b/libsrc/apple2/mou/a2.stdmou.s index 9b84c2f53..e48abbb41 100644 --- a/libsrc/apple2/mou/a2.stdmou.s +++ b/libsrc/apple2/mou/a2.stdmou.s @@ -353,7 +353,7 @@ SHOW: ; BUTTONS: Return the button mask in A/X. BUTTONS: lda info + MOUSE_INFO::BUTTONS - ldx #$00 + ldx #>$0000 rts ; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1. diff --git a/libsrc/apple2/open.s b/libsrc/apple2/open.s index 38793a13e..7ece7f18d 100644 --- a/libsrc/apple2/open.s +++ b/libsrc/apple2/open.s @@ -209,7 +209,7 @@ done: lda tmp1 ; Restore fd jsr popname ; Preserves A ; Return success - ldx #$00 + ldx #>$0000 stx ___oserror rts diff --git a/libsrc/apple2/oserror.s b/libsrc/apple2/oserror.s index 5f523340f..db4f146cd 100644 --- a/libsrc/apple2/oserror.s +++ b/libsrc/apple2/oserror.s @@ -23,7 +23,7 @@ ___osmaperrno: ; Found the code : lda ErrTab-1,x - ldx #$00 ; High byte always zero + ldx #>$0000 rts .rodata diff --git a/libsrc/apple2/revers.s b/libsrc/apple2/revers.s index 83fcb2ae7..86dfd0d19 100644 --- a/libsrc/apple2/revers.s +++ b/libsrc/apple2/revers.s @@ -18,5 +18,5 @@ normal: dex ; $00->$FF, $40->$3F stx INVFLG ; Save new flag value bmi :+ ; Jump if current value is $FF (normal) lda #$01 ; Return "inverse" -: ldx #$00 +: ldx #>$0000 rts diff --git a/libsrc/apple2/ser/a2.gs.s b/libsrc/apple2/ser/a2.gs.s index ea3e54cc1..3ad899fc2 100644 --- a/libsrc/apple2/ser/a2.gs.s +++ b/libsrc/apple2/ser/a2.gs.s @@ -295,7 +295,7 @@ SER_CLOSE: bcc IIgs lda #SER_ERR_NO_DEVICE ; Not a IIgs - ldx #$00 ; Promote char return value + ldx #>$0000 rts IIgs: @@ -500,7 +500,7 @@ BaudOK: SetupOut: plp ; Reenable interrupts if needed - ldx #$00 ; Promote char return value + ldx #>$0000 sty Opened rts @@ -539,7 +539,7 @@ SER_GET: rts NoData: lda #SER_ERR_NO_DATA - ldx #$00 ; Promote char return value + ldx #>$0000 rts ;---------------------------------------------------------------------------- @@ -560,7 +560,7 @@ SER_PUT: : ldy SendFreeCnt ; Do we have room to store byte? bne :+ lda #SER_ERR_OVERFLOW - ldx #$00 + ldx #>$0000 rts : ldy SendTail ; Put byte into send buffer & send @@ -571,7 +571,7 @@ SER_PUT: jsr TryToSend lda #SER_ERR_OK .assert SER_ERR_OK = 0, error - tax + tax ; Promote char return value rts ;---------------------------------------------------------------------------- @@ -608,11 +608,11 @@ SER_IOCTL: stx Channel .assert SER_ERR_OK = 0, error - tax + tax ; Promote char return value rts : lda #SER_ERR_INV_IOCTL - ldx #$00 ; Promote char return value + ldx #>$0000 rts ;---------------------------------------------------------------------------- diff --git a/libsrc/apple2/ser/a2.ssc.s b/libsrc/apple2/ser/a2.ssc.s index 88dc4572c..488a32540 100644 --- a/libsrc/apple2/ser/a2.ssc.s +++ b/libsrc/apple2/ser/a2.ssc.s @@ -345,7 +345,7 @@ BaudOK: sta tmp1 stx Index ; Mark port as open lda #SER_ERR_OK Out: - ldx #$00 ; Promote char return value + ldx #>$0000 rts ;---------------------------------------------------------------------------- @@ -360,7 +360,7 @@ SER_GET: cmp #$FF bne :+ lda #SER_ERR_NO_DATA - ldx #$00 ; Promote char return value + ldx #>$0000 rts : ldy Stopped ; Check for flow stopped @@ -408,7 +408,7 @@ SER_PUT: ldy SendFreeCnt ; Reload SendFreeCnt after TryToSend bne :+ lda #SER_ERR_OVERFLOW - ldx #$00 ; Promote char return value + ldx #>$0000 rts : ldy SendTail ; Put byte into send buffer @@ -456,7 +456,7 @@ SER_IOCTL: rts : lda #SER_ERR_INV_IOCTL - ldx #$00 ; Promote char return value + ldx #>$0000 rts ;---------------------------------------------------------------------------- diff --git a/libsrc/apple2/set_iigs_speed.s b/libsrc/apple2/set_iigs_speed.s index 5e2f2f722..f13e8ab6a 100644 --- a/libsrc/apple2/set_iigs_speed.s +++ b/libsrc/apple2/set_iigs_speed.s @@ -25,5 +25,5 @@ _set_iigs_speed: set_speed: sta CYAREG txa - ldx #$00 + ldx #>$0000 rts diff --git a/libsrc/apple2/stat.s b/libsrc/apple2/stat.s index f655b3e3f..e0564ae0c 100644 --- a/libsrc/apple2/stat.s +++ b/libsrc/apple2/stat.s @@ -121,7 +121,7 @@ eoferr: beq done lda #$FF done: - tax + tax ; Promote char return value rts .bss diff --git a/libsrc/apple2/tgi/a2.hi.s b/libsrc/apple2/tgi/a2.hi.s index aeb24f6be..1d5bdb68b 100644 --- a/libsrc/apple2/tgi/a2.hi.s +++ b/libsrc/apple2/tgi/a2.hi.s @@ -342,7 +342,7 @@ GETPIXEL: lda #$03 ; 3 (white) : bcc :+ adc #$03 ; += 4 (black -> black2, white -> white2) -: ldx #$00 +: ldx #>$0000 bit $C080 ; Switch in LC bank 2 for R/O rts diff --git a/libsrc/apple2/tgi/a2.lo.s b/libsrc/apple2/tgi/a2.lo.s index 6d1c6aa4a..8b00c5d20 100644 --- a/libsrc/apple2/tgi/a2.lo.s +++ b/libsrc/apple2/tgi/a2.lo.s @@ -321,7 +321,7 @@ GETPIXEL: jsr SCRN tax lda COL2TGI,x - ldx #$00 + ldx #>$0000 bit $C080 ; Switch in LC bank 2 for R/O rts diff --git a/libsrc/apple2/wherey.s b/libsrc/apple2/wherey.s index daacaaba7..a3843f606 100644 --- a/libsrc/apple2/wherey.s +++ b/libsrc/apple2/wherey.s @@ -12,5 +12,5 @@ _wherey: lda CV sec sbc WNDTOP - ldx #$00 + ldx #>$0000 rts From fb63a839bffd4845287cd5d4f8d4d3db5fb80824 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Wed, 12 Mar 2025 20:10:55 +0100 Subject: [PATCH 399/707] Optimize LZ4 decompressor Use a walking out pointer instead of &out[written]. This simplifies the code by 27 bytes and spares 15% cycles. Tested with both the unit test and code uncompressing 10kB of data. Renamed the labels for legibility. --- libsrc/common/lz4.s | 158 +++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 81 deletions(-) diff --git a/libsrc/common/lz4.s b/libsrc/common/lz4.s index 4702137bc..57773c86a 100644 --- a/libsrc/common/lz4.s +++ b/libsrc/common/lz4.s @@ -14,12 +14,11 @@ .export _decompress_lz4 out = regsave -written = regsave + 2 +end = regsave + 2 tmp = tmp1 token = tmp2 offset = ptr3 in = sreg -outlen = ptr4 ; --------------------------------------------------------------- ; void decompress_lz4 (const u8 *in, u8 * const out, const u16 outlen) @@ -29,37 +28,43 @@ outlen = ptr4 .proc _decompress_lz4: near - sta outlen - stx outlen+1 + sta tmp + stx tmp+1 +; +; end = out + outlen; +; jsr popax sta out - stx out+1 + clc + adc tmp + sta end + txa + sta out+1 + adc tmp+1 + sta end+1 jsr popax sta in stx in+1 ; -; written = 0; +; while (out < end) { ; - lda #$00 - sta written -; -; while (written < outlen) { -; - jmp L0046 + jmp check_len ; ; token = *in++; ; -L0004: ldy #$00 +get_token: + ldy #$00 lda (in),y - sta token + tay ; Backup token to Y inc in - bne L000A + bne :+ inc in+1 -L000A: + +: ; ; offset = token >> 4; ; @@ -74,7 +79,7 @@ L000A: ; token &= 0xf; ; token += 4; // Minmatch ; - lda token + tya ; Get token back from Y and #$0F clc adc #$04 @@ -84,7 +89,8 @@ L000A: ; lda offset cmp #$0F -L0013: bne L001A +moreliterals: + bne check_offset_not_zero ; ; tmp = *in++; ; @@ -93,9 +99,10 @@ L0013: bne L001A sta tmp inc in - bne L0017 + bne :+ inc in+1 -L0017: + +: ; ; offset += tmp; ; @@ -113,24 +120,20 @@ L0017: ; ; goto moreliterals; ; - jmp L0013 + jmp moreliterals ; ; if (offset) { ; -L001A: lda offset +check_offset_not_zero: + lda offset ora offset+1 - beq L001C + beq check_end ; -; memcpy(&out[written], in, offset); +; memcpy(out, in, offset); ; lda out - clc - adc written sta ptr2 - lda out+1 - adc written+1 - tax - lda ptr2 + ldx out+1 stx ptr2+1 jsr pushax lda in @@ -140,15 +143,15 @@ L001A: lda offset ; ldy #$00 - not needed as pushax zeroes Y jsr memcpy_upwards ; -; written += offset; +; out += offset; +; memcpy returned a pointer to out ; - lda offset clc - adc written - sta written - lda offset+1 - adc written+1 - sta written+1 + adc offset + sta out + txa + adc offset+1 + sta out+1 ; ; in += offset; ; @@ -160,21 +163,23 @@ L001A: lda offset adc in+1 sta in+1 ; -; if (written >= outlen) +; if (out >= end) ; -L001C: lda written - cmp outlen - lda written+1 - sbc outlen+1 +check_end: + lda out + cmp end + lda out+1 + sbc end+1 ; ; return; ; - bcc L0047 + bcc end_not_reached rts ; ; memcpy(&offset, in, 2); ; -L0047: ldy #$00 +end_not_reached: + ldy #$00 lda (in),y sta offset iny @@ -187,23 +192,18 @@ L0047: ldy #$00 clc adc in sta in - bcc L002F + bcc :+ inc in+1 + +: ; -; copysrc = out + written - offset; +; copysrc = out - offset; ; -L002F: lda out - clc - adc written - tay - lda out+1 - adc written+1 - tax - tya + lda out sec sbc offset sta ptr1 - txa + lda out+1 sbc offset+1 sta ptr1+1 ; @@ -217,7 +217,8 @@ L002F: lda out ; if (token == 19) { ; cmp #$13 -L0045: bne L003C +morematches: + bne token_not_19 ; ; tmp = *in++; ; @@ -226,9 +227,9 @@ L0045: bne L003C sta tmp inc in - bne L0039 + bne :+ inc in+1 -L0039: +: ; ; offset += tmp; ; @@ -246,41 +247,36 @@ L0039: ; ; goto morematches; ; - jmp L0045 + jmp morematches ; -; memcpy(&out[written], copysrc, offset); +; memcpy(out, copysrc, offset); ; -L003C: lda out - clc - adc written +token_not_19: + lda out sta ptr2 - lda out+1 - adc written+1 - tax - lda ptr2 + ldx out+1 stx ptr2+1 jsr pushax jsr memcpy_upwards ; -; written += offset; +; out += offset; ; - lda offset clc - adc written - sta written - lda offset+1 - adc written+1 -L0046: sta written+1 + adc offset + sta out + txa + adc offset+1 + sta out+1 ; 0 on the first loop iteration +check_len: ; -; while (written < outlen) { +; while (out < end) { ; - lda written - cmp outlen - lda written+1 - sbc outlen+1 - jcc L0004 + lda out + cmp end + lda out+1 + sbc end+1 + jcc get_token rts .endproc - From 1efe1227d6b89f68ee9f15ef55cb1edb1fa17109 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt <ol.sc@web.de> Date: Fri, 14 Mar 2025 16:24:25 +0100 Subject: [PATCH 400/707] Added apple2enh to the targets supporting waitvsync(). --- doc/funcref.sgml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index bc2424272..7c3b92230 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -8380,6 +8380,7 @@ only in the presence of a prototype. <descrip> <tag/Function/Wait until the start of the next video frame. <tag/Header/<tt/ +<ref id="apple2enh.h" name="apple2enh.h">, <ref id="atmos.h" name="atmos.h">, <ref id="cbm.h" name="cbm.h">, <ref id="gamate.h" name="gamate.h">, From 9f5a195dc27d0462fa9cfc0a29e04fedcc9135d4 Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Sat, 22 Mar 2025 00:17:03 +0100 Subject: [PATCH 401/707] samples/geos/Makefile: use C1541 variable for c1541 program --- samples/geos/Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/samples/geos/Makefile b/samples/geos/Makefile index 03f6b8cdc..578927760 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -3,6 +3,9 @@ # var. to build for another target system. SYS ?= geos-cbm +# Comes with the VICE emulator, see http://vice-emu.sourceforge.net/ +C1541 ?= c1541 + # If SYS was given on the commandline, redirect "c64" to "geos-cbm" and # "apple2enh" to "geos-apple" ifeq ($(origin SYS),command line) @@ -82,11 +85,11 @@ samples: $(EXELIST_$(SYS)) $(foreach dir,$(DIRLIST),$(SUBDIR_recipe)) define samples-geos -c1541 -attach $(0).d64 -geoswrite $(1); +$(C1541) -attach $(0).d64 -geoswrite $(1); endef samples-geos: $(EXELIST_$(SYS)) - c1541 -format "$@,01" d64 $@.d64 + $(C1541) -format "$@,01" d64 $@.d64 $(foreach tool,$(EXELIST_$(SYS)),$(call samples-geos,$(tool))) else samples: @@ -103,7 +106,7 @@ bitmap.c: logo.pcx bitmap-demo.cvt: bitmap.c bitmap-demores.grc bitmap-demo.c $(CL) -t $(SYS) -O -o $@ -m bitmap-demo.map bitmap-demores.grc bitmap-demo.c - + filesel.cvt: fileselres.grc filesel.c $(CL) -t $(SYS) -O -o $@ -m filesel.map fileselres.grc filesel.c @@ -134,7 +137,7 @@ vector-demo.cvt: vector-demores.grc vector-demo.c yesno.cvt: yesnores.grc yesno.c $(CL) -t $(SYS) -O -o $@ -m yesno.map yesnores.grc yesno.c - + clean: @$(DEL) overlay-demores.h 2>$(NULLDEV) @$(DEL) bitmap.c 2>$(NULLDEV) From 774e2759653f2f7ee654ab2987344abaa748e4e6 Mon Sep 17 00:00:00 2001 From: "Stefan A. Haubenthal" <polluks@sdf.org> Date: Mon, 24 Mar 2025 20:52:55 +0100 Subject: [PATCH 402/707] Fixed many comments --- libsrc/apple2/cputc.s | 2 +- libsrc/atari/getdevice.s | 2 +- libsrc/atari/graphics.s | 2 +- libsrc/atari/mou/atrtt.s | 6 +++--- libsrc/atari/read.s | 2 +- libsrc/atari/siocall.s | 2 +- libsrc/atari/write.s | 2 +- libsrc/atari5200/joy/atr5200std.s | 10 +++++----- libsrc/c128/break.s | 5 ++--- libsrc/c128/ser/c128-swlink.s | 4 ++-- libsrc/c128/tgi/c128-vdc.s | 2 +- libsrc/c128/tgi/c128-vdc2.s | 2 +- libsrc/c64/emd/c64-rrr.s | 14 +++++++------- libsrc/c64/joy/c64-hitjoy.s | 4 ++-- libsrc/c64/ser/c64-swlink.s | 2 +- libsrc/cbm/cbm_read.s | 2 +- libsrc/cbm/exec.c | 2 +- libsrc/cbm/getdevice.s | 2 +- libsrc/cbm/loadaddr.s | 2 +- libsrc/cbm510/joy/cbm510-std.s | 2 +- libsrc/common/ctype.s | 2 +- libsrc/common/mktime.s | 4 ++-- libsrc/common/realloc.s | 2 +- libsrc/common/strlen.s | 2 +- libsrc/common/vsprintf.s | 2 +- libsrc/cx16/getdevice.s | 2 +- libsrc/cx16/tgi/cx320p1.s | 4 ++-- libsrc/cx16/tgi/cx640p1.s | 4 ++-- libsrc/cx16/waitvsync.s | 2 +- libsrc/dbg/dbgdump.s | 2 +- libsrc/geos-common/const.inc | 2 +- libsrc/geos-common/symbols.txt | 18 +++++++++--------- libsrc/kim1/tapeio.s | 4 ++-- libsrc/lynx/bootldr.s | 2 +- libsrc/lynx/eeprom66.s | 2 +- libsrc/lynx/eeprom86.s | 2 +- libsrc/lynx/tgi/lynx-160-102-16.s | 4 ++-- libsrc/nes/ppubuf.s | 2 +- libsrc/pce/vga.s | 6 +++--- libsrc/pet/cbm_load.c | 4 ++-- libsrc/runtime/callirq.s | 2 +- libsrc/runtime/lshelp.s | 2 +- libsrc/runtime/ludiv.s | 2 +- libsrc/runtime/lumod.s | 2 +- libsrc/sim6502/exehdr.s | 2 +- libsrc/sym1/tapeio.s | 4 ++-- libsrc/telestrat/write.s | 2 +- libsrc/tgi/tgi_clippedline.s | 6 +++--- libsrc/tgi/tgi_init.s | 2 +- libsrc/vic20/joy/vic20-stdjoy.s | 2 +- 50 files changed, 84 insertions(+), 85 deletions(-) diff --git a/libsrc/apple2/cputc.s b/libsrc/apple2/cputc.s index f60965f44..fdf799357 100644 --- a/libsrc/apple2/cputc.s +++ b/libsrc/apple2/cputc.s @@ -39,7 +39,7 @@ _cputcxy: pla ; Restore C and run into _cputc _cputc: - cmp #$0D ; Test for \r = carrage return + cmp #$0D ; Test for \r = carriage return beq left cmp #$0A ; Test for \n = line feed beq newline diff --git a/libsrc/atari/getdevice.s b/libsrc/atari/getdevice.s index e0e700436..b98d3ad5f 100644 --- a/libsrc/atari/getdevice.s +++ b/libsrc/atari/getdevice.s @@ -50,7 +50,7 @@ check_device: lda #SIO_STAT sta DCOMND ; set command into DCB lda #%01000000 ; direction value, "receive data" - sta DSTATS ; set data flow directon + sta DSTATS ; set data flow direction lda #15 sta DTIMLO ; value got from DOS source lda #4 diff --git a/libsrc/atari/graphics.s b/libsrc/atari/graphics.s index 1f7844c39..8b4e8034d 100644 --- a/libsrc/atari/graphics.s +++ b/libsrc/atari/graphics.s @@ -23,7 +23,7 @@ .code -; set new grapics mode +; set new graphics mode ; gets new mode in A ; returns handle or -1 on error ; uses tmp1, tmp2, tmp3, tmp4 (in subroutines) diff --git a/libsrc/atari/mou/atrtt.s b/libsrc/atari/mou/atrtt.s index b1e53935e..f7c56e9f2 100644 --- a/libsrc/atari/mou/atrtt.s +++ b/libsrc/atari/mou/atrtt.s @@ -374,7 +374,7 @@ IRQ: ; The touch pad is read thru the paddle potentiometers. The possible ; values are 1..228. Since the maximum value is less than the X ; dimension we have to "stretch" this value. In order to use only -; divisions by powers of two, we use the following appoximation: +; divisions by powers of two, we use the following approximation: ; 320/227 = 1.4096 ; 1+1/2-1/8+1/32 = 1.4062 ; For Y we subtract 1/8 of it to get in the YMax ballpark. @@ -385,7 +385,7 @@ IRQ: ; X - ldx PADDL0 ; get X postion + ldx PADDL0 ; get X position dex ; decrement, since it's 1-based stx XPos txa @@ -445,7 +445,7 @@ IRQ: ; Y - ldx PADDL1 ; get Y postion + ldx PADDL1 ; get Y position dex ; decrement, since it's 1-based stx YPos lda #228 diff --git a/libsrc/atari/read.s b/libsrc/atari/read.s index 5078b321d..228ca9ee2 100644 --- a/libsrc/atari/read.s +++ b/libsrc/atari/read.s @@ -33,7 +33,7 @@ done: lda ICBLL,x ; buf len lo lda ICBLH,x ; get buf len hi tax ; to X okdone: lda #0 - sta ___oserror ; clear system dependend error code + sta ___oserror ; clear system dependent error code pla ; get buf len lo rts diff --git a/libsrc/atari/siocall.s b/libsrc/atari/siocall.s index 38cbb35d5..b1c19a2d0 100644 --- a/libsrc/atari/siocall.s +++ b/libsrc/atari/siocall.s @@ -23,7 +23,7 @@ .proc __sio_call sta DCOMND ; set command into DCB - stx DSTATS ; set data flow directon + stx DSTATS ; set data flow direction jsr popax ; get buffer address sta DBUFLO ; set buffer address into DCB stx DBUFHI diff --git a/libsrc/atari/write.s b/libsrc/atari/write.s index 2ddb88ee3..b745e5211 100644 --- a/libsrc/atari/write.s +++ b/libsrc/atari/write.s @@ -21,7 +21,7 @@ write9: lda ICBLH,x ; buf len high tax lda #0 - sta ___oserror ; clear system dependend error code + sta ___oserror ; clear system dependent error code pla rts diff --git a/libsrc/atari5200/joy/atr5200std.s b/libsrc/atari5200/joy/atr5200std.s index 980428d13..a717455f2 100644 --- a/libsrc/atari5200/joy/atr5200std.s +++ b/libsrc/atari5200/joy/atr5200std.s @@ -79,7 +79,7 @@ COUNT: ; CENTER = 228 / 2 -SENSIVITY = 16 +SENSITIVITY = 16 READJOY: and #3 ; put joystick number in range, just in case @@ -96,27 +96,27 @@ READJOY: ; Read joystick @notrg: ldy PADDL0,x ; get horizontal position - cpy #CENTER-SENSIVITY + cpy #CENTER-SENSITIVITY bcs @chkleft ora #4 ; JOY_LEFT bne @updown @chkleft: - cpy #CENTER+SENSIVITY + cpy #CENTER+SENSITIVITY bcc @updown ora #8 ; JOY_RIGHT @updown:ldy PADDL0+1,x ; get vertical position - cpy #CENTER-SENSIVITY + cpy #CENTER-SENSITIVITY bcs @chkdown ora #1 ; JOY_UP bne @done @chkdown: - cpy #CENTER+SENSIVITY + cpy #CENTER+SENSITIVITY bcc @done ora #2 ; JOY_DOWN diff --git a/libsrc/c128/break.s b/libsrc/c128/break.s index 092ca3469..450183dc3 100644 --- a/libsrc/c128/break.s +++ b/libsrc/c128/break.s @@ -125,11 +125,10 @@ uservec: jmp $FFFF ; Patched at runtime .data -; Old break vector preceeded by a jump opcode +; Old break vector preceded by a jump opcode brk_old: jmp $0000 -; Indirect vectors preceeded by a jump opcode +; Indirect vectors preceded by a jump opcode brk_ind: jmp $0000 - diff --git a/libsrc/c128/ser/c128-swlink.s b/libsrc/c128/ser/c128-swlink.s index b8f08159b..796dc3b3b 100644 --- a/libsrc/c128/ser/c128-swlink.s +++ b/libsrc/c128/ser/c128-swlink.s @@ -134,7 +134,7 @@ ParityTable: ; Interrupt stub that is copied into low RAM. The startup code uses a special ; memory configuration with just kernal and I/O enabled (anything else is RAM). ; The NMI handler in ROM will switch back to a configuration where just the -; low 16K RAM are accessible. So we have to copy a smal piece of code into +; low 16K RAM are accessible. So we have to copy a small piece of code into ; low RAM that enables the cc65 configuration and then jumps to the real NMI ; handler. @@ -296,7 +296,7 @@ SER_CLOSE: lda #%00001010 sta ACIA_CMD -; Initalize buffers. Returns zero in a +; Initialize buffers. Returns zero in a jsr InitBuffers diff --git a/libsrc/c128/tgi/c128-vdc.s b/libsrc/c128/tgi/c128-vdc.s index f48b530f6..edbdd6cd8 100644 --- a/libsrc/c128/tgi/c128-vdc.s +++ b/libsrc/c128/tgi/c128-vdc.s @@ -268,7 +268,7 @@ INIT: @L1: ldx #$FF stx BITMASK -; Remeber current color value +; Remember current color value ldx #VDC_COLORS jsr VDCReadReg sta OLDCOLOR diff --git a/libsrc/c128/tgi/c128-vdc2.s b/libsrc/c128/tgi/c128-vdc2.s index 4b7b17c57..6b75ee712 100644 --- a/libsrc/c128/tgi/c128-vdc2.s +++ b/libsrc/c128/tgi/c128-vdc2.s @@ -277,7 +277,7 @@ INIT: @L1: ldx #$FF stx BITMASK -; Remeber current color value +; Remember current color value ldx #VDC_COLORS jsr VDCReadReg sta OLDCOLOR diff --git a/libsrc/c64/emd/c64-rrr.s b/libsrc/c64/emd/c64-rrr.s index 4d175cd32..8632e5e64 100644 --- a/libsrc/c64/emd/c64-rrr.s +++ b/libsrc/c64/emd/c64-rrr.s @@ -212,8 +212,8 @@ MAP: cmp pagecount bcs return_null sta curpage - lda #<dummy ; load .A/.X with adress of data for COPYFROM-call (which expects the - ldx #>dummy ; adress in .A/.X) + lda #<dummy ; load .A/.X with address of data for COPYFROM-call (which expects the + ldx #>dummy ; address in .A/.X) jsr COPYFROM bcs return_win ; function returns pointer to window (returns always with carry set!) @@ -224,8 +224,8 @@ COMMIT: lda curpage cmp pagecount bcs return - lda #<dummy ; load .A/.X with adress of data for COPYTO-call (which expects the - ldx #>dummy ; adress in .A/.X) + lda #<dummy ; load .A/.X with address of data for COPYTO-call (which expects the + ldx #>dummy ; address in .A/.X) ;---------------------------------------------------------------------------------------- ;void __fastcall__ em_copyto (struct em_copy *copy_data); @@ -324,7 +324,7 @@ get_struct_data: ;read and process the values from the em_copy struct passed to as parameters rameter to the ;functions em_copyto and em_copyfrom - sta aux ;store adress of struct (passed in .A/.X) into a zp pointer + sta aux ;store address of struct (passed in .A/.X) into a zp pointer stx aux+1 ldy #0 ;index 0 @@ -347,7 +347,7 @@ get_struct_data: lsr lsr ;shift into bits 3 and 4 ora #$23 ;set bit 5 (select ram) and 1+2 (game/exrom setting for ULTIMAX-mode) - tax ;.X has now the value to write into $de00 to acess rr-ram at desired 16k-bank + tax ;.X has now the value to write into $de00 to access rr-ram at desired 16k-bank iny iny ;skip unused byte lda (aux),y ;read length lo-byte @@ -357,7 +357,7 @@ get_struct_data: iny lda (aux),y ;length hi-byte adc c64_ram+1 - sta len+1 ;tmp2: length, tmp3 contains end adress of transfer in c64-ram. + sta len+1 ;tmp2: length, tmp3 contains end address of transfer in c64-ram. rts ;55 bytes diff --git a/libsrc/c64/joy/c64-hitjoy.s b/libsrc/c64/joy/c64-hitjoy.s index a9d454fd0..c57f45780 100644 --- a/libsrc/c64/joy/c64-hitjoy.s +++ b/libsrc/c64/joy/c64-hitjoy.s @@ -102,7 +102,7 @@ readadapter: lda #%00010001 sta $dd0e ; control register a ; timer: start - ; continous + ; continuous ; forced load ; serial port: input @@ -110,7 +110,7 @@ readadapter: lda #%01010001 sta $dc0e ; control register a ; timer: start - ; continous + ; continuous ; forced load ; serial port: output diff --git a/libsrc/c64/ser/c64-swlink.s b/libsrc/c64/ser/c64-swlink.s index 067a7ca92..2c06bb39b 100644 --- a/libsrc/c64/ser/c64-swlink.s +++ b/libsrc/c64/ser/c64-swlink.s @@ -270,7 +270,7 @@ SER_CLOSE: lda #%00001010 sta ACIA_CMD -; Initalize buffers. Returns zero in a +; Initialize buffers. Returns zero in a jsr InitBuffers diff --git a/libsrc/cbm/cbm_read.s b/libsrc/cbm/cbm_read.s index 98e3c25c9..c449567b1 100644 --- a/libsrc/cbm/cbm_read.s +++ b/libsrc/cbm/cbm_read.s @@ -24,7 +24,7 @@ ; /* the kernal routine BASIN sets ST to EOF if the end of file ; ** is reached the first time, then we have store tmp. ; ** every subsequent call returns EOF and READ ERROR in ST, then -; ** we have to exit the loop here immediatly. +; ** we have to exit the loop here immediately. ; */ ; if (cbm_k_readst() & 0xBF) break; ; diff --git a/libsrc/cbm/exec.c b/libsrc/cbm/exec.c index b9c1bdc96..49ab53553 100644 --- a/libsrc/cbm/exec.c +++ b/libsrc/cbm/exec.c @@ -89,7 +89,7 @@ int __fastcall__ exec (const char* progname, const char* cmdline) } utoa (dv, basic.unit, 10); - /* Tape files can be openned only once; skip this test for the Datasette. */ + /* Tape files can be opened only once; skip this test for the Datasette. */ if (dv != 1) { /* Don't try to run a program that can't be found. */ fd = open (progname, O_RDONLY); diff --git a/libsrc/cbm/getdevice.s b/libsrc/cbm/getdevice.s index 08ba6d5f8..b68e716b4 100644 --- a/libsrc/cbm/getdevice.s +++ b/libsrc/cbm/getdevice.s @@ -54,7 +54,7 @@ next: inx lda ST -; Either the Kernal calls above were successfull or there was +; Either the Kernal calls above were successful or there was ; already a cmdchannel to the device open - which is a pretty ; good indication of its existence ;-) diff --git a/libsrc/cbm/loadaddr.s b/libsrc/cbm/loadaddr.s index 0675dd67d..4329f201f 100644 --- a/libsrc/cbm/loadaddr.s +++ b/libsrc/cbm/loadaddr.s @@ -2,7 +2,7 @@ ; Ullrich von Bassewitz, 2010-11-13 ; ; This module supplies the load address that is expected by Commodore -; machines in the first two bytes of an excutable disk file. +; machines in the first two bytes of an executable disk file. ; diff --git a/libsrc/cbm510/joy/cbm510-std.s b/libsrc/cbm510/joy/cbm510-std.s index f7cbb2cdc..640b0d2a8 100644 --- a/libsrc/cbm510/joy/cbm510-std.s +++ b/libsrc/cbm510/joy/cbm510-std.s @@ -117,7 +117,7 @@ READ: ldx #$0F ; Switch to the system bank lsr tmp1 lsr tmp1 -; Mask the relavant bits, get the push button bit +; Mask the relevant bits, get the push button bit @L2: asl a ; push button bit into carry lda tmp1 diff --git a/libsrc/common/ctype.s b/libsrc/common/ctype.s index 220ad79c1..d51b1bf2b 100644 --- a/libsrc/common/ctype.s +++ b/libsrc/common/ctype.s @@ -7,7 +7,7 @@ ; ; See "LICENSE" file for legal information. ; -; Character specification table, matching serveral consoles. +; Character specification table, matching several consoles. ; .include "ctypetable.inc" diff --git a/libsrc/common/mktime.s b/libsrc/common/mktime.s index ac5755a45..e84cee040 100644 --- a/libsrc/common/mktime.s +++ b/libsrc/common/mktime.s @@ -423,10 +423,10 @@ finish_calc: jsr tosaddeax ; Simple addition there ; No need to store/load/push the counter here, simply to push it - ; for the last substraction + ; for the last subtraction jsr pusheax - ; Substract timezone + ; Subtract timezone lda __tz+1+3 sta sreg+1 lda __tz+1+2 diff --git a/libsrc/common/realloc.s b/libsrc/common/realloc.s index 925ac3d19..176871dd5 100644 --- a/libsrc/common/realloc.s +++ b/libsrc/common/realloc.s @@ -110,7 +110,7 @@ _realloc: tya ; Put ___heapptr back in A sec ; Check if we have enough memory at heap top - sbc oldsize ; Substract oldsize + sbc oldsize ; Subtract oldsize sta newblock lda ___heapptr+1 sbc oldsize+1 diff --git a/libsrc/common/strlen.s b/libsrc/common/strlen.s index c20ab78f9..b28bffe7a 100644 --- a/libsrc/common/strlen.s +++ b/libsrc/common/strlen.s @@ -2,7 +2,7 @@ ; Ullrich von Bassewitz, 31.05.1998 ; ; Note: strspn & strcspn call internally this function and rely on -; the usage of only ptr4 here! Keep in mind when appling changes +; the usage of only ptr4 here! Keep in mind when applying changes ; and check the other implementations too! ; ; size_t __fastcall__ strlen (const char* s); diff --git a/libsrc/common/vsprintf.s b/libsrc/common/vsprintf.s index b4cb9c419..65a961955 100644 --- a/libsrc/common/vsprintf.s +++ b/libsrc/common/vsprintf.s @@ -30,7 +30,7 @@ _vsprintf: ldy #2 jsr staxysp -; Contine by jumping to vsnprintf, which expects ap on the CPU stack and will +; Continue by jumping to vsnprintf, which expects ap on the CPU stack and will ; cleanup the C stack jmp vsnprintf diff --git a/libsrc/cx16/getdevice.s b/libsrc/cx16/getdevice.s index 5f2e74af4..70f883db0 100644 --- a/libsrc/cx16/getdevice.s +++ b/libsrc/cx16/getdevice.s @@ -56,7 +56,7 @@ next: inx lda STATUS -; Either the Kernal calls above were successfull, or there was +; Either the Kernal calls above were successful, or there was ; already a cmdchannel to the device open -- which is a pretty ; good indication of its existence. ;-) diff --git a/libsrc/cx16/tgi/cx320p1.s b/libsrc/cx16/tgi/cx320p1.s index 2fcd9adf3..f42d91c33 100644 --- a/libsrc/cx16/tgi/cx320p1.s +++ b/libsrc/cx16/tgi/cx320p1.s @@ -91,7 +91,7 @@ Y2 := ptr4 .bss -; The colors are indicies into a TGI palette. The TGI palette is indicies into +; The colors are indices into a TGI palette. The TGI palette is indices into ; VERA's palette. Vera's palette is a table of Red, Green, and Blue levels. ; The first 16 RGB elements mimic the Commodore 64's colors. @@ -267,7 +267,7 @@ GETPALETTE: ; GETDEFPALETTE: Return the default palette for the driver in .XA. 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 changable) palette. +; of the (not changeable) palette. ; ; Must set an error code: NO (all drivers must have a default palette) diff --git a/libsrc/cx16/tgi/cx640p1.s b/libsrc/cx16/tgi/cx640p1.s index 287160f6b..815c4ab67 100644 --- a/libsrc/cx16/tgi/cx640p1.s +++ b/libsrc/cx16/tgi/cx640p1.s @@ -89,7 +89,7 @@ TEMP3 = sreg ; HORLINE .bss -; The colors are indicies into a TGI palette. The TGI palette is indicies into +; The colors are indices into a TGI palette. The TGI palette is indices into ; VERA's palette. Vera's palette is a table of Red, Green, and Blue levels. ; The first 16 RGB elements mimic the Commodore 64's colors. @@ -404,7 +404,7 @@ GETPALETTE: ; GETDEFPALETTE: Return the default palette for the driver in .XA. 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 changable) palette. +; of the (not changeable) palette. ; ; Must set an error code: NO (all drivers must have a default palette) diff --git a/libsrc/cx16/waitvsync.s b/libsrc/cx16/waitvsync.s index d75a7a735..e0d9f9768 100644 --- a/libsrc/cx16/waitvsync.s +++ b/libsrc/cx16/waitvsync.s @@ -6,7 +6,7 @@ ; ; VERA's vertical sync causes IRQs which increment the jiffy timer. ; -; Updated by ZeroByteOrg to use Kernal API RDTIM to retreive the TIMER variable +; Updated by ZeroByteOrg to use Kernal API RDTIM to retrieve the TIMER variable ; .export _waitvsync diff --git a/libsrc/dbg/dbgdump.s b/libsrc/dbg/dbgdump.s index 8ab646d21..bc6a4bd40 100644 --- a/libsrc/dbg/dbgdump.s +++ b/libsrc/dbg/dbgdump.s @@ -1,7 +1,7 @@ ; ; Ullrich von Bassewitz, 11.08.1998 ; -; char* __cdecl__ DbgMemDump (unsigend Addr, char* Buf, unsigned char Length); +; char* __cdecl__ DbgMemDump (unsigned Addr, char* Buf, unsigned char Length); ; .export _DbgMemDump diff --git a/libsrc/geos-common/const.inc b/libsrc/geos-common/const.inc index c0294e01d..ab45a19a2 100644 --- a/libsrc/geos-common/const.inc +++ b/libsrc/geos-common/const.inc @@ -1,5 +1,5 @@ ; -;GeosConst - various system constans sorted by function +;GeosConst - various system constants sorted by function ;reassembled by Maciej 'YTM/Elysium' Witkowiak ;4-2-99, 18-3-99 diff --git a/libsrc/geos-common/symbols.txt b/libsrc/geos-common/symbols.txt index d1893e376..b82954ec6 100644 --- a/libsrc/geos-common/symbols.txt +++ b/libsrc/geos-common/symbols.txt @@ -26,7 +26,7 @@ cardDataPntr $2c $2c $60 Word This is a pointer to the actual card graphics dat CPU_DATA $01 n/a n/a Word Address of 6510 data register that controls the hardware memory ... CPU_DDR $00 n/a n/a Byte Address of 6510 data direction register. curDevice $ba $ba n/a Byte This holds the current serial device number. -curDirHead $8200 $8200 $fa80 256 | 39 Bytes For CBM, it is the buffer containing header infomation ... +curDirHead $8200 $8200 $fa80 256 | 39 Bytes For CBM, it is the buffer containing header information ... curDrive $8489 $8489 $f60d Byte Holds the device number of the currently active disk drive. curEnable n/a $1300 $0951 Byte This is an image of the C64 mobenble register. curHeight $29 $29 $021b Byte Used to hold the card height in pixels of the current font in ... @@ -48,7 +48,7 @@ dblClickCount $8515 $8515 $0258 Byte Used to determine when an icon is double c devTabHi n/a n/a $fae7 4 Bytes For the Apple, these are the high and low bytes of the four ... devTabLo n/a n/a $faeb 4 Bytes For the Apple, these are the high and low bytes of the four ... devUnitTab n/a n/a $faef 4 Bytes The ProDos unit numbers of the four possible devices are kept ... -dir2Head $8900 $8900 n/a 256 Bytes This is the 2nd directory header block used for larger cpacity ... +dir2Head $8900 $8900 n/a 256 Bytes This is the 2nd directory header block used for larger capacity ... dirBlkno n/a n/a $f620 Word Block number of the key block of the directory containing ... dirEntryBuf $8400 $8400 $fa59 256 | 39 Bytes Buffer used to build a file's directory entry. dirPtr n/a n/a $f622 Word Pointer into diskBlkBuf for this file's entry. @@ -74,7 +74,7 @@ fileWritten $8498 $8498 $f61a Byte Flag indicating if a if the currently open f firstBoot $88c5 $88c5 $0281 Byte This flag is changed from 0 to $FF when the deskTop comes up ... fontData $850c $850c n/a(?) 9 Bytes Buffer for saving the user active font table when going into ... fontTable $26 $26 n/a(?) 8 Bytes fontTable is a label for the beginning of variables for the ... -grcntr12 $d016 $d016 n/a Byte Graphics control reqister #2. +grcntr12 $d016 $d016 n/a Byte Graphics control register #2. grcntrl1 $d011 $d011 n/a Byte Graphics control register #1. grirq $d019 $d019 n/a Byte Graphics chip interrupt register. grirqen $d01a $d01a n/a Byte Graphics chip interrupt enable register. @@ -89,7 +89,7 @@ intBotVector $849f $849f $0204 Word Vector to routine to call after the operati interleave $848c $848c n/a Byte Variable used by BlkAlloc routine as the desired interleave when ... intSource n/a n/a $02c6 Byte Byte to indicate where interrupts are coming from on the Apple. intTopVector $849d $849d $0202 Word Vector to routine to call before the operating system interrupt ... -invertBuffer n/a $1ced n/a 80 Bytes Buffer area used to speed up the 80 colunn InvertLine routine. +invertBuffer n/a $1ced n/a 80 Bytes Buffer area used to speed up the 80 column InvertLine routine. irqvec $0314 $0314 n/a Word IRQ vector. isGEOS $848b $848b n/a Byte Flag to indicate whether the current disk is a GEOS disk. keyData $8504 $8504 $0245 Byte Holds the ASCII value of the current last key that was pressed. @@ -152,7 +152,7 @@ msbxpos $d010 $d010 n/a Byte Most significant bits for x positions of sprites. msePicPtr $31 $31 n/a Word Pointer to the mouse graphics data. nationality $c010 $c010 $e00d Byte Byte to hold nationality of Kernal. nmivec $0318 $0318 n/a Word NMI vector. -noEraseSprites n/a n/a $0240 Byte Flag to stop routine TempHideMouse fron erasing sprites #2 ... +noEraseSprites n/a n/a $0240 Byte Flag to stop routine TempHideMouse from erasing sprites #2 ... numDrives $848d $848d $f60e Byte Set to number of drives on the system. obj0Pointer $8ff8 $8ff8 n/a Byte Pointer to the picture data for sprite 0. obj1Pointer $8ff9 $8ff9 n/a Byte Pointer to the picture data for sprite 1. @@ -169,7 +169,7 @@ PrntDiskName $8476 $8476 n/a 18 Bytes Disk name that current printer driver is o PrntFileName $8465 $8465 $08ac 17 | 16 Bytes Name of the current printer driver. ramBase $88c7 $88c7 n/a 4 Bytes RAM bank for each disk drive to use if the drive type is either ... ramExpSize $88c3 $88c3 n/a Byte Byte for number or RAM banks available in RAM expansion unit. -random $850a $850a $024c Word Variable incremented each interrupt to generate a randon nunber. +random $850a $850a $024c Word Variable incremented each interrupt to generate a randon number. rasreg $d012 $d012 n/a Byte Raster register. RecoverVector $84b1 $84b1 $0216 Word Pointer to routine that is called to recover the background ... reqXpos0 n/a n/a $0800 Word This variable corresponds to the Commodore VIC chip register ... @@ -193,7 +193,7 @@ shiftBuf n/a $1b45 $70 7 Bytes Buffer for shifting/doubling sprites. Located in shiftOutBuf n/a $1b4c $78 7 Bytes Buffer for shifting/doubling/oring sprites. Located in back ... sizeFlags n/a $1b53 $db1c Byte Height of sprite. softOnes n/a $1c2d $d000 192 Bytes Buffer used for putting sprite bitmaps up on screen without ... -softZeros n/a $1b6d $d0e0 192 Bytes Buffer used for putting sprite bitnaps up on screen without ... +softZeros n/a $1b6d $d0e0 192 Bytes Buffer used for putting sprite bitmaps up on screen without ... spr0pic $8a00 $8a00 n/a 64 Bytes This is where the graphics data for sprite 0 is kept on ... spr1pic $8a40 $8a40 n/a 64 Bytes This is where the graphics data for sprite 1 is kept on ... spr2pic $8a80 $8a80 n/a 64 Bytes This is where the graphics data for sprite 2 is kept on ... @@ -353,8 +353,8 @@ i_Rectangle $c19f $c19f $fe3c Inline Rectangle. ImprintLine n/a n/a $ff8f Imprint horizontal line to background buffer. ImprintRectangle $c250 $c250 $fe4e Imprint rectangular area to background buffer. InfoCard n/a n/a $670f Get I/O card attributes. -InitCard n/a n/a $6700 Intialize I/O card. -InitForDialog n/a n/a $ff4a Internal pre-dialog box intialization. +InitCard n/a n/a $6700 Initialize I/O card. +InitForDialog n/a n/a $ff4a Internal pre-dialog box initialization. InitForIO $c25c $c25c n/a Prepare CBM system for I/O across serial bus. InitForPrint $7900 $7900 $6000 Initialize printer (once per document). InitMouse $fe80 $fe80 $f000 Initialize input device. diff --git a/libsrc/kim1/tapeio.s b/libsrc/kim1/tapeio.s index 4a16d6b9c..4af2b3aa2 100644 --- a/libsrc/kim1/tapeio.s +++ b/libsrc/kim1/tapeio.s @@ -16,7 +16,7 @@ sta ID ; Tape record ID to P1L jsr LOADT ; Read data from tape bcs error - jmp return0 ; Return 0 if sucessful + jmp return0 ; Return 0 if successful error: jmp return1 ; or 1 if not .endproc @@ -33,7 +33,7 @@ error: jmp return1 ; or 1 if not ldx #$00 jsr DUMPT ; Write data to tape bcs error - jmp return0 ; Return 0 if sucessful + jmp return0 ; Return 0 if successful error: jmp return1 ; or 1 if not .endproc diff --git a/libsrc/lynx/bootldr.s b/libsrc/lynx/bootldr.s index ddc24faed..a0320886f 100644 --- a/libsrc/lynx/bootldr.s +++ b/libsrc/lynx/bootldr.s @@ -15,7 +15,7 @@ .segment "BOOTLDR" ;********************************** ; Here is the bootloader in plaintext -; The idea is to make the smalles possible encrypted loader as decryption +; The idea is to make the smallest possible encrypted loader as decryption ; is very slow. The minimum size is 49 bytes plus a zero byte. ;********************************** ; EXE = $fb68 diff --git a/libsrc/lynx/eeprom66.s b/libsrc/lynx/eeprom66.s index 6511cf8af..44b365f03 100644 --- a/libsrc/lynx/eeprom66.s +++ b/libsrc/lynx/eeprom66.s @@ -40,7 +40,7 @@ EE_C_WRITE = $14 EE_C_READ = $18 EE_C_ERASE = $1C EE_C_EWEN = $13 -EE_C_EWEN2 = $FF ;; C0 schould be enough +EE_C_EWEN2 = $FF ;; C0 should be enough EE_C_EWDS = $10 EE_C_EWDS2 = $00 diff --git a/libsrc/lynx/eeprom86.s b/libsrc/lynx/eeprom86.s index 73b342fae..8b829c5e8 100644 --- a/libsrc/lynx/eeprom86.s +++ b/libsrc/lynx/eeprom86.s @@ -41,7 +41,7 @@ EE_C_WRITE = $14 EE_C_READ = $18 EE_C_ERASE = $1C EE_C_EWEN = $13 -EE_C_EWEN2 = $FF ;; C0 schould be enough +EE_C_EWEN2 = $FF ;; C0 should be enough EE_C_EWDS = $10 EE_C_EWDS2 = $00 diff --git a/libsrc/lynx/tgi/lynx-160-102-16.s b/libsrc/lynx/tgi/lynx-160-102-16.s index c35b6a5aa..00a2059aa 100644 --- a/libsrc/lynx/tgi/lynx-160-102-16.s +++ b/libsrc/lynx/tgi/lynx-160-102-16.s @@ -43,7 +43,7 @@ libref: .addr $0000 ; Library reference ; to an RTS for test versions (function not implemented). A future version may ; allow for emulation: In this case the vector will be zero. Emulation means ; that the graphics kernel will emulate the function by using lower level -; primitives - for example ploting a line by using calls to SETPIXEL. +; primitives - for example plotting a line by using calls to SETPIXEL. .addr INSTALL .addr UNINSTALL @@ -258,7 +258,7 @@ GETERROR: ; ; The TGI lacks a way to draw sprites. As that functionality is vital to ; Lynx games we borrow this CONTROL function to implement the still -; missing tgi_draw_sprite funtion. To use this in your C-program +; missing tgi_draw_sprite function. To use this in your C-program ; do a #define tgi_draw_sprite(spr) tgi_ioctl(0, spr) ; ; To do a flip-screen call tgi_ioctl(1, 0) diff --git a/libsrc/nes/ppubuf.s b/libsrc/nes/ppubuf.s index f08fc1a71..0de6d1980 100644 --- a/libsrc/nes/ppubuf.s +++ b/libsrc/nes/ppubuf.s @@ -68,7 +68,7 @@ ; ------------------------------------------------------------------------ ; Flush PPU-Memory write buffer -; called from vblank interupt +; called from vblank interrupt .proc ppubuf_flush diff --git a/libsrc/pce/vga.s b/libsrc/pce/vga.s index 630fbe8db..067647cb8 100644 --- a/libsrc/pce/vga.s +++ b/libsrc/pce/vga.s @@ -3,9 +3,9 @@ .export _pce_font -; The character tiles use only two colors from each pallette. Color zero -; comes from pallette zero; color one is different in each pallette. The -; color of a character is set by choosing one of the 16 pallettes. +; The character tiles use only two colors from each palette. Color zero +; comes from palette zero; color one is different in each palette. The +; color of a character is set by choosing one of the 16 palettes. .rodata diff --git a/libsrc/pet/cbm_load.c b/libsrc/pet/cbm_load.c index 1823f6537..2c98d9581 100644 --- a/libsrc/pet/cbm_load.c +++ b/libsrc/pet/cbm_load.c @@ -22,14 +22,14 @@ unsigned int __fastcall__ cbm_load (const char* name, unsigned char device, void unsigned int size = 0; if (cbm_open (1, device, CBM_READ, name) != 0) { - /* Can't load from a file that can't be openned. */ + /* Can't load from a file that can't be opened. */ return 0; } /* Get the file's load address. */ if (cbm_read (1, &load, sizeof load) != sizeof load) { /* Either the file wasn't found, or it was too short. (Note: - ** the computer openned a file even if the drive couldn't open one.) + ** the computer opened a file even if the drive couldn't open one.) */ cbm_close (1); return 0; diff --git a/libsrc/runtime/callirq.s b/libsrc/runtime/callirq.s index 74a12c4db..2096e5c3b 100644 --- a/libsrc/runtime/callirq.s +++ b/libsrc/runtime/callirq.s @@ -12,7 +12,7 @@ ; ; 2. Reentrancy. The condes routines must use self modyfiying code, which ; means it is not reentrant. An IRQ using condes, that interrupts -; another use of condes will cause unpredicatble behaviour. The current +; another use of condes will cause unpredictable behaviour. The current ; code avoids this by using locking mechanisms, but it's complex and ; has a size and performance penalty. ; diff --git a/libsrc/runtime/lshelp.s b/libsrc/runtime/lshelp.s index 8a2fca139..ce1648d28 100644 --- a/libsrc/runtime/lshelp.s +++ b/libsrc/runtime/lshelp.s @@ -39,7 +39,7 @@ poplsargs: adc #$00 sta sreg+1 -L1: lda ptr4+1 ; Is the right operand nagative? +L1: lda ptr4+1 ; Is the right operand negative? sta tmp2 ; Remember the sign for later bpl L2 ; Jump if not diff --git a/libsrc/runtime/ludiv.s b/libsrc/runtime/ludiv.s index e2e27371e..77335d8f5 100644 --- a/libsrc/runtime/ludiv.s +++ b/libsrc/runtime/ludiv.s @@ -22,7 +22,7 @@ tosudiv0ax: .endif tosudiveax: - jsr getlop ; Get the paramameters + jsr getlop ; Get the parameters jsr udiv32 ; Do the division lda ptr1 ; Result is in ptr1:sreg ldx ptr1+1 diff --git a/libsrc/runtime/lumod.s b/libsrc/runtime/lumod.s index 09909c0c9..eb6176b35 100644 --- a/libsrc/runtime/lumod.s +++ b/libsrc/runtime/lumod.s @@ -22,7 +22,7 @@ tosumod0ax: .endif tosumodeax: - jsr getlop ; Get the paramameters + jsr getlop ; Get the parameters jsr udiv32 ; Do the division lda tmp3 ; Remainder is in ptr2:tmp3:tmp4 sta sreg diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s index 529ad9b94..6487e5b0c 100644 --- a/libsrc/sim6502/exehdr.s +++ b/libsrc/sim6502/exehdr.s @@ -22,7 +22,7 @@ .elseif (.cpu .bitand ::CPU_ISET_6502) .byte 0 .else - .error Unknow CPU type. + .error Unknown CPU type. .endif .byte sp ; sp address .addr __MAIN_START__ ; load address diff --git a/libsrc/sym1/tapeio.s b/libsrc/sym1/tapeio.s index 078ea7abd..f94e1336c 100644 --- a/libsrc/sym1/tapeio.s +++ b/libsrc/sym1/tapeio.s @@ -21,7 +21,7 @@ ldy #$80 jsr LOADT ; Read data from tape bcs error - jmp return0 ; Return 0 if sucessful + jmp return0 ; Return 0 if successful error: jmp return1 ; or 1 if not .endproc @@ -40,7 +40,7 @@ error: jmp return1 ; or 1 if not ldy #$80 jsr DUMPT ; Write data to tape bcs error - jmp return0 ; Return 0 if sucessful + jmp return0 ; Return 0 if successful error: jmp return1 ; or 1 if not .endproc diff --git a/libsrc/telestrat/write.s b/libsrc/telestrat/write.s index 37a896696..8509aa159 100644 --- a/libsrc/telestrat/write.s +++ b/libsrc/telestrat/write.s @@ -65,7 +65,7 @@ L2: ldy #0 cpx #$0A ; check for \n bne L3 BRK_TELEMON XWR0 ; macro send char to screen (channel 0 in telemon terms) - lda #$0D ; return to the beggining of the line + lda #$0D ; return to the beginning of the line BRK_TELEMON XWR0 ; macro diff --git a/libsrc/tgi/tgi_clippedline.s b/libsrc/tgi/tgi_clippedline.s index b0f1dd456..319bb7152 100644 --- a/libsrc/tgi/tgi_clippedline.s +++ b/libsrc/tgi/tgi_clippedline.s @@ -188,7 +188,7 @@ tgi_clip_sign: .res 1 ldx tgi_clip_dx+1 jsr udiv32by16r16 -; Check the sign of the final result and negate it if nessary +; Check the sign of the final result and negate it if necessary done: bit tmp1 jmi negax @@ -228,7 +228,7 @@ done: bit tmp1 ldx tgi_clip_dy+1 jsr udiv32by16r16 -; Check the sign of the final result and negate it if nessary +; Check the sign of the final result and negate it if necessary jmp muldiv_dydx::done @@ -279,7 +279,7 @@ L1: lda tgi_clip_o1 ; We must clip. If we haven't already done so, calculate dx/dy. -L2: lda tgi_clip_d ; Deltas alreay calculated? +L2: lda tgi_clip_d ; Deltas already calculated? bne HaveDeltas ; Jump if yes inc tgi_clip_d jsr calcdeltas diff --git a/libsrc/tgi/tgi_init.s b/libsrc/tgi/tgi_init.s index c8fd355d5..79651cbba 100644 --- a/libsrc/tgi/tgi_init.s +++ b/libsrc/tgi/tgi_init.s @@ -63,7 +63,7 @@ lda #<$100 ldx #>$100 jsr pushax ; Width scale = 1.0 - jsr pushax ; Heigh scale = 1.0 + jsr pushax ; Height scale = 1.0 jsr pusha ; Text direction = TGI_TEXT_HORIZONTAL jmp _tgi_settextstyle ; A = Font = TGI_FONT_BITMAP diff --git a/libsrc/vic20/joy/vic20-stdjoy.s b/libsrc/vic20/joy/vic20-stdjoy.s index b3de8766c..22ec0b638 100644 --- a/libsrc/vic20/joy/vic20-stdjoy.s +++ b/libsrc/vic20/joy/vic20-stdjoy.s @@ -82,7 +82,7 @@ COUNT: ; ------------------------------------------------------------------------ ; READ: Read a particular joystick passed in A. -; The current implemenation will ignore the joystick number because we do only +; The current implementation will ignore the joystick number because we do only ; have one joystick READ: lda #$7F ; mask for VIA2 JOYBIT: sw3 From 5ceb4f0d68c04a046b33e59f75ef80ee5767d22f Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Mon, 24 Mar 2025 21:27:55 +0100 Subject: [PATCH 403/707] Revert atr5200std.s --- libsrc/atari5200/joy/atr5200std.s | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libsrc/atari5200/joy/atr5200std.s b/libsrc/atari5200/joy/atr5200std.s index a717455f2..980428d13 100644 --- a/libsrc/atari5200/joy/atr5200std.s +++ b/libsrc/atari5200/joy/atr5200std.s @@ -79,7 +79,7 @@ COUNT: ; CENTER = 228 / 2 -SENSITIVITY = 16 +SENSIVITY = 16 READJOY: and #3 ; put joystick number in range, just in case @@ -96,27 +96,27 @@ READJOY: ; Read joystick @notrg: ldy PADDL0,x ; get horizontal position - cpy #CENTER-SENSITIVITY + cpy #CENTER-SENSIVITY bcs @chkleft ora #4 ; JOY_LEFT bne @updown @chkleft: - cpy #CENTER+SENSITIVITY + cpy #CENTER+SENSIVITY bcc @updown ora #8 ; JOY_RIGHT @updown:ldy PADDL0+1,x ; get vertical position - cpy #CENTER-SENSITIVITY + cpy #CENTER-SENSIVITY bcs @chkdown ora #1 ; JOY_UP bne @done @chkdown: - cpy #CENTER+SENSITIVITY + cpy #CENTER+SENSIVITY bcc @done ora #2 ; JOY_DOWN From 834388a9e1aad70bd7c0fe8afec5147459279f5f Mon Sep 17 00:00:00 2001 From: "Stefan A. Haubenthal" <polluks@sdf.org> Date: Sun, 6 Apr 2025 18:49:11 +0200 Subject: [PATCH 404/707] Added doc and some refs #2613 --- doc/apple2.sgml | 6 +++--- doc/apple2enh.sgml | 6 +++--- doc/atari.sgml | 5 +++-- doc/chrcvt65.sgml | 2 +- doc/funcref.sgml | 28 +++++++++++++++++++++++++++- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 28120577a..2cc62d7ae 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -310,9 +310,9 @@ the memory from $800 to $1FFF can be added to the heap by calling ProDOS 8 requires for every open file a page-aligned 1 KB I/O buffer. By default these buffers are allocated by the cc65 runtime system on the heap using -<tt/posix_memalign()/. While this is generally the best solution it means quite -some overhead for (especially rather small) cc65 programs which do open files -but don't make use of the heap otherwise. +<url url="funcref.html#posix_memalign" name="posix_memalign()">. While this is +generally the best solution it means quite some overhead for (especially rather +small) cc65 programs which do open files but don't make use of the heap otherwise. The apple2 package comes with the alternative ProDOS 8 I/O buffer allocation module <tt/apple2-iobuf-0800.o/ which uses the memory between $800 and diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index fce6127bd..987b63fd0 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -290,9 +290,9 @@ the memory from $800 to $1FFF can be added to the heap by calling ProDOS 8 requires for every open file a page-aligned 1 KB I/O buffer. By default these buffers are allocated by the cc65 runtime system on the heap using -<tt/posix_memalign()/. While this is generally the best solution it means quite -some overhead for (especially rather small) cc65 programs which do open files -but don't make use of the heap otherwise. +<url url="funcref.html#posix_memalign" name="posix_memalign()">. While this is +generally the best solution it means quite some overhead for (especially rather +small) cc65 programs which do open files but don't make use of the heap otherwise. The apple2enh package comes with the alternative ProDOS 8 I/O buffer allocation module <tt/apple2enh-iobuf-0800.o/ which uses the memory between $800 and diff --git a/doc/atari.sgml b/doc/atari.sgml index 3057cd8a6..060bc8ad4 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -412,8 +412,9 @@ Please mind that ANTIC has memory alignment requirements for "player missile graphics"-data, font data, display lists and screen memory. Creation of a special linker configuration with appropriate aligned segments and switching to that segment in the c-code is usually necessary. A more memory -hungry solution consists in using the "<tt/posix_memalign()/" function in -conjunction with copying your data to the allocated memory. +hungry solution consists in using the <url url="funcref.html#posix_memalign" +name="posix_memalign()"> function in conjunction with copying your data to the +allocated memory. <sect1>Character mapping<p> diff --git a/doc/chrcvt65.sgml b/doc/chrcvt65.sgml index a631a0004..00909e12f 100644 --- a/doc/chrcvt65.sgml +++ b/doc/chrcvt65.sgml @@ -19,7 +19,7 @@ the native format. chrcvt65 is a vector font converter. It is able to convert a "BGI Stroked Font" to a compact TGI native vector font. See the function <url -url="funcref.html#tgi_load_vectorfont" name="tgi_load_vectorfont"> for usage. +url="tgi.html#tgi_load_vectorfont" name="tgi_load_vectorfont"> for usage. diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 7c3b92230..5c603b130 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -738,7 +738,7 @@ communication, see also <tt>testcode/lib/ser-test.c</tt>. <item><ref id="ltoa" name="ltoa"> <item><ref id="malloc" name="malloc"> <item><ref id="perror" name="perror"> -<!-- <item><ref id="posix_memalign" name="posix_memalign"> --> +<item><ref id="posix_memalign" name="posix_memalign"> <!-- <item><ref id="putenv" name="putenv"> --> <item><ref id="qsort" name="qsort"> <item><ref id="rand" name="rand"> @@ -6223,6 +6223,32 @@ be used in presence of a prototype. </quote> +<sect1>posix_memalign<label id="posix_memalign"><p> + +<quote> +<descrip> +<tag/Function/Allocate aligned dynamic memory. +<tag/Header/<tt/<ref id="stdlib.h" name="stdlib.h">/ +<tag/Declaration/<tt/int __fastcall__ posix_memalign (void** memptr, size_t alignment, size_t size);/ +<tag/Description/Allocate a block of memory with the given "size", which is aligned to a +memory address that is a multiple of "alignment". "alignment" <em/must not/ be +zero, and <em/must/ be a power of two; otherwise, this function will return +EINVAL. The function returns ENOMEM if not enough memory is available +to satisfy the request. "memptr" must point to a variable; that variable +will return the address of the allocated memory. Use free() to release that +allocated block. +<tag/Notes/<itemize> +<item>The function is only available as fastcall function, so it may only +be used in presence of a prototype. +</itemize> +<tag/Availability/POSIX 1003.1 +<tag/See also/ +<ref id="free" name="free"> +<tag/Example/None. +</descrip> +</quote> + + <sect1>psg_delay<label id="psg_delay"><p> <quote> From f1ed5b7057d101a2297d207cb8c868719c197b06 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Mon, 7 Apr 2025 09:20:51 +0200 Subject: [PATCH 405/707] Fixed a typo in g_typeadjust(). Will fix #2611. --- src/cc65/codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 166176f5e..e55a318d6 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -1489,7 +1489,7 @@ unsigned g_typeadjust (unsigned lhs, unsigned rhs) ** both operands are converted to unsigned long int. */ if ((ltype == CF_LONG && rtype == CF_INT && (rhs & CF_UNSIGNED)) || - (rtype == CF_LONG && ltype == CF_INT && (rhs & CF_UNSIGNED))) { + (rtype == CF_LONG && ltype == CF_INT && (lhs & CF_UNSIGNED))) { /* long can represent all unsigneds, so we are in the first sub-case. */ return const_flag | CF_LONG; } From caa66aea951e8b0513b4fcc6d0aea4ad9ecbd655 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Mon, 7 Apr 2025 21:01:05 +0200 Subject: [PATCH 406/707] Add decompress_lz4 C implementation as comment For reference. --- libsrc/common/lz4.s | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/libsrc/common/lz4.s b/libsrc/common/lz4.s index 57773c86a..c53841897 100644 --- a/libsrc/common/lz4.s +++ b/libsrc/common/lz4.s @@ -6,6 +6,60 @@ ; Almost 7 times faster, uses no RAM (vs 14 bytes BSS), and takes 1/4 the space ; vs the official C source. ; +; +; C implementation was: + +; void decompress_lz4 (unsigned char *in, unsigned char *out, const int outlen) { +; unsigned char token, tmp; +; unsigned int offset; +; unsigned char *end = out+outlen; +; unsigned char *copysrc; +; +; while (out < end) { +; token = *in++; +; offset = token >> 4; +; +; token &= 0x0f; +; token += 4; // Minmatch +; +; if (offset == 15) { +; moreliterals: +; tmp = *in++; +; offset += tmp; +; if (tmp == 255) +; goto moreliterals; +; } +; +; if (offset) { +; memcpy(out, in, offset); +; out += offset; +; in += offset; +; } +; +; if (out >= end) { +; return; +; } +; +; offset = (*in); +; in++; +; offset += (*in)<<8; +; in++; +; +; copysrc = out - offset; +; offset = token; +; +; if (token == 19) { +; morematches: +; tmp = *in++; +; offset += tmp; +; if (tmp == 255) +; goto morematches; +; } +; +; memcpy(out, copysrc, offset); +; out += offset; +; } +; } .importzp sp, sreg, regsave, regbank .importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 From 5cb1bc60fc6079f5fb8ea6c00299671c2d77daeb Mon Sep 17 00:00:00 2001 From: Christian Groessler <chris@groessler.org> Date: Wed, 9 Apr 2025 22:51:11 +0200 Subject: [PATCH 407/707] Add 'define=yes' for INIT segment to atari-asm.cfg and atari-asm-xex.cfg linker configs. libsrc/atari/exehdr.s: Add (empty) INIT segment to cover assembler programs which link with exehdr.s. --- cfg/atari-asm-xex.cfg | 1 + cfg/atari-asm.cfg | 1 + libsrc/atari/exehdr.s | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/cfg/atari-asm-xex.cfg b/cfg/atari-asm-xex.cfg index f0a6291db..fddf95dd4 100644 --- a/cfg/atari-asm-xex.cfg +++ b/cfg/atari-asm-xex.cfg @@ -20,5 +20,6 @@ SEGMENTS { CODE: load = MAIN, type = rw, define = yes; RODATA: load = MAIN, type = ro optional = yes; DATA: load = MAIN, type = rw optional = yes; + INIT: load = MAIN, type = bss, optional = yes, define = yes; BSS: load = MAIN, type = bss, optional = yes, define = yes; } diff --git a/cfg/atari-asm.cfg b/cfg/atari-asm.cfg index 6fc1c2caa..f824eb264 100644 --- a/cfg/atari-asm.cfg +++ b/cfg/atari-asm.cfg @@ -25,6 +25,7 @@ SEGMENTS { CODE: load = MAIN, type = rw, define = yes; RODATA: load = MAIN, type = ro optional = yes; DATA: load = MAIN, type = rw optional = yes; + INIT: load = MAIN, type = bss, optional = yes, define = yes; BSS: load = MAIN, type = bss, optional = yes, define = yes; AUTOSTRT: load = TRAILER, type = ro, optional = yes; } diff --git a/libsrc/atari/exehdr.s b/libsrc/atari/exehdr.s index fe17aeafd..1ac9a0fbe 100644 --- a/libsrc/atari/exehdr.s +++ b/libsrc/atari/exehdr.s @@ -9,3 +9,7 @@ .segment "MAINHDR" .word __MAIN_START__ .word __INIT_LOAD__ - 1 + +; Define the INIT segment so that __INIT_LOAD__ from above '.import' is always defined. +; The segment is normally present when linking a C program, but not necessarily when linking an assembler program. +.segment "INIT" From 8cf802cee36808edd11decfeb53b34ce03a6c1f0 Mon Sep 17 00:00:00 2001 From: Max <mczonk@gmail.com> Date: Tue, 15 Apr 2025 16:57:13 +0200 Subject: [PATCH 408/707] Fix documentation about unnamed labels using an `@`. --- doc/ca65.sgml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index fd15d02a5..80224a84e 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -833,11 +833,9 @@ names like "Loop". Here is an example: <sect1>Unnamed labels<p> 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>. +an unnamed label, use sole <tt>:</tt>. -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. +To reference an unnamed label, use <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 @@ -847,12 +845,12 @@ Example: <tscreen><verb> cpy #0 - beq @++ - @: + beq :++ + : sta $2007 dey - bne @- - @: + bne :- + : rts </verb></tscreen> From 2085646e57c19f112fd1e986ad24593e82a9f5de Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Sat, 26 Apr 2025 12:56:57 +0200 Subject: [PATCH 409/707] Apple2: implement get_tv() get_tv() will return TV_NTSC or TV_PAL for any Apple II model with a way of checking vblank. For Apple ][ and ][+ it will return TV_OTHER and let the user figure it out in another way. --- doc/apple2.sgml | 1 + doc/apple2enh.sgml | 1 + doc/funcref.sgml | 39 +++++++-- include/apple2.h | 8 ++ libsrc/apple2/get_tv.s | 189 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 232 insertions(+), 6 deletions(-) create mode 100644 libsrc/apple2/get_tv.s diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 2cc62d7ae..9cff996b7 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -354,6 +354,7 @@ usage. <item>allow_lowercase <item>beep <item>dir_entry_count +<item>get_tv <item>get_ostype <item>gmtime_dt <item>mktime_dt diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 987b63fd0..094ddd93e 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -333,6 +333,7 @@ usage. <item>_datetime <item>beep <item>dir_entry_count +<item>get_tv <item>get_ostype <item>gmtime_dt <item>mktime_dt diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 5c603b130..eec04b929 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -98,6 +98,7 @@ function. <item>allow_lowercase <item><ref id="beep" name="beep"> <item><ref id="dir_entry_count" name="dir_entry_count"> +<item><ref id="get_tv" name="get_tv"> <item><ref id="get_ostype" name="get_ostype"> <item><ref id="gmtime_dt" name="gmtime_dt"> <item><ref id="mktime_dt" name="mktime_dt"> @@ -111,6 +112,7 @@ function. <item>_dos_type <item><ref id="beep" name="beep"> <item><ref id="dir_entry_count" name="dir_entry_count"> +<item><ref id="get_tv" name="get_tv"> <item><ref id="get_ostype" name="get_ostype"> <item><ref id="gmtime_dt" name="gmtime_dt"> <item><ref id="mktime_dt" name="mktime_dt"> @@ -140,7 +142,7 @@ function. <!-- <item><ref id="_setcolor_low" name="_setcolor_low"> --> <item><ref id="_sound" name="_sound"> <item><ref id="get_ostype" name="get_ostype"> -<!-- <item><ref id="get_tv" name="get_tv"> --> +<item><ref id="get_tv" name="get_tv"> </itemize> (incomplete) @@ -227,7 +229,7 @@ function. <!-- <item><ref id="cbm_readdir" name="cbm_readdir"> --> <!-- <item><ref id="cbm_save" name="cbm_save"> --> <!-- <item><ref id="cbm_write" name="cbm_write"> --> -<!-- <item><ref id="get_tv" name="get_tv"> --> +<item><ref id="get_tv" name="get_tv"> <item><ref id="kbrepeat" name="kbrepeat"> <item><ref id="waitvsync" name="waitvsync"> </itemize> @@ -348,7 +350,7 @@ function. <itemize> <!-- <item><ref id="get_numbanks" name="get_numbanks"> --> <item><ref id="get_ostype" name="get_ostype"> -<!-- <item><ref id="get_tv" name="get_tv"> --> +<item><ref id="get_tv" name="get_tv"> <!-- <item><ref id="set_tv" name="set_tv"> --> <!-- <item><ref id="vera_layer_enable" name="vera_layer_enable"> --> <!-- <item><ref id="vera_sprites_enable" name="vera_sprites_enable"> --> @@ -443,7 +445,7 @@ see also <tt>testcode/lib/em-test.c</tt> and <tt>samples/multidemo.c</tt>. <sect1><tt/gamate.h/<label id="gamate.h"><p> <itemize> -<!-- <item><ref id="get_tv" name="get_tv"> --> +<item><ref id="get_tv" name="get_tv"> <item><ref id="waitvsync" name="waitvsync"> </itemize> @@ -550,7 +552,7 @@ see also <tt>testcode/lib/em-test.c</tt> and <tt>samples/multidemo.c</tt>. <sect1><tt/nes.h/<label id="nes.h"><p> <itemize> -<!-- <item><ref id="get_tv" name="get_tv"> --> +<item><ref id="get_tv" name="get_tv"> <item><ref id="waitvsync" name="waitvsync"> </itemize> @@ -568,7 +570,7 @@ It does not declare any functions. <sect1><tt/pce.h/<label id="pce.h"><p> <itemize> -<!-- <item><ref id="get_tv" name="get_tv"> --> +<item><ref id="get_tv" name="get_tv"> <item><ref id="waitvsync" name="waitvsync"> </itemize> @@ -4108,6 +4110,31 @@ be used in presence of a prototype. </quote> +<sect1>get_tv<label id="get_tv"><p> + +<quote> +<descrip> +<tag/Function/The function returns the system's vertical blank frequency. +<tag/Header/<tt/<ref id="apple2.h" name="apple2.h">, +<ref id="atari.h" name="atari.h">, <ref id="cbm.h" name="cbm.h">, +<ref id="cx16.h" name="cx16.h">, <ref id="gamate.h" name="gamate.h">, +<ref id="nes.h" name="nes.h">, <ref id="pce.h" name="pce.h">/ +<tag/Declaration/<tt/unsigned char get_tv (void);/ +<tag/Description/<tt/get_tv/ is machine dependent and does not exist for +all supported targets. If it exists, it returns a number that identifies the +frequency at which the screen vertical blank happens (either 50 or 60Hz), +if possible. +<tag/Notes/<itemize> +<item>The function does not exist on all platforms. +<item>Return TV_NTSC for 60Hz systems, TV_PAL for 50Hz systems, or +TV_OTHER if the scan frequency can not be determined. +</itemize> +<tag/Availability/cc65 (not all platforms) +<tag/Example/None. +</descrip> +</quote> + + <sect1>get_ostype<label id="get_ostype"><p> <quote> diff --git a/include/apple2.h b/include/apple2.h index 15055f412..9f7526f59 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -122,6 +122,11 @@ #define APPLE_IIGS1 0x81 /* Apple IIgs (ROM 1) */ #define APPLE_IIGS3 0x83 /* Apple IIgs (ROM 3) */ +/* Return codes for get_tv() */ +#define TV_NTSC 0 +#define TV_PAL 1 +#define TV_OTHER 2 + extern unsigned char _dos_type; /* Valid _dos_type values: ** @@ -200,6 +205,9 @@ extern void a2_lo_tgi[]; void beep (void); /* Beep beep. */ +unsigned char get_tv (void); +/* Get the machine vblank frequency. Returns one of the TV_xxx codes. */ + unsigned char get_ostype (void); /* Get the machine type. Returns one of the APPLE_xxx codes. */ diff --git a/libsrc/apple2/get_tv.s b/libsrc/apple2/get_tv.s new file mode 100644 index 000000000..830cc4ac1 --- /dev/null +++ b/libsrc/apple2/get_tv.s @@ -0,0 +1,189 @@ +; +; Colin Leroy-Mira <colin@colino.net>, 2025 +; +; unsigned char __fastcall__ get_tv(void) +; + .export _get_tv + + .import _set_iigs_speed, _get_iigs_speed + .import ostype + + .constructor calibrate_tv, 2 + + .include "accelerator.inc" + .include "apple2.inc" + .include "get_tv.inc" + + .segment "ONCE" + +; Cycle wasters +waste_72: + jsr waste_36 +waste_36: + jsr waste_12 +waste_24: + jsr waste_12 +waste_12: + rts + +.proc calibrate_tv + lda ostype + bmi iigs + cmp #$20 + bcc iip + cmp #$40 + bcc iie + +iic: jmp calibrate_iic +iigs: jmp calibrate_iigs +iie: jmp calibrate_iie +iip: rts ; Keep TV::OTHER. +.endproc + + +; Magic numbers +WASTE_LOOP_CYCLES = 92 ; The wait loop total cycles +NTSC_LOOP_COUNT = 17030/WASTE_LOOP_CYCLES ; How many loops expected on NTSC +PAL_LOOP_COUNT = 20280/WASTE_LOOP_CYCLES ; How many loops expected on PAL +STOP_PTRIG = 16500/WASTE_LOOP_CYCLES ; Stop PTRIG at 16.5ms + +; Carry set at enter: wait for VBL + +; Carry clear at enter: wait for VBL - +; Increments X every 92 cycles. +.proc count_until_vbl_bit + lda #$10 ; BPL + bcc :+ + lda #$30 ; BMI +: sta sign + + ; Wait for VBLsign change with 92 cycles loops. + ; Hit PTRIG repeatedly so that accelerators will slow down. + ; But stop hitting PTRIG after 16.5ms cycles, so that on the //c, + ; the VBLINT will not be reset right before we get it. 16.5ms + ; is a good value because it's far enough from 17ms for NTSC + ; models, and close enough to 20.2ms for PAL models that accelerators + ; will stay slow until there. (5ms usually). + +: cpx #STOP_PTRIG ; 2 - see if we spent 16.5ms already + bcs notrig ; 4 / 5 - if so, stop hitting PTRIG + sta PTRIG ; 8 - otherwise hit it + bcc count ; 11 +notrig: + nop ; 7 - keep cycle count constant when not + nop ; 9 - hitting PTRIG + nop ; 11 +count: + inx ; 13 + jsr waste_72 ; 85 + bit RDVBLBAR ; 89 - Wait for VBL change +sign: + bpl :- ; 92 - patched with bpl/bmi + rts +.endproc + +.proc calibrate_iic + php + sei + + sta IOUDISOFF + lda RDVBLMSK + pha ; Back up for cleanup + + bit ENVBL + bit PTRIG ; Reset VBL interrupt flag +: bit RDVBLBAR ; Wait for one VBL + bpl :- + + bit PTRIG ; Reset VBL interrupt flag again + ldx #$00 + clc + jsr count_until_vbl_bit + + pla ; Cleanup + asl + bcs :+ ; VBL interrupts were already enabled + bit DISVBL +: sta IOUDISON ; IIc Tech Ref Man: The firmware normally leaves IOUDIS on. + + plp + jmp calibrate_done +.endproc + +.proc calibrate_iie +: bit RDVBLBAR ; Wait for bit 7 to be off (VBL start) + bmi :- +: bit RDVBLBAR ; Wait for bit 7 to be on (VBL end) + bpl :- + + ; Wait and count during a full cycle + ldx #$00 + sec + jsr count_until_vbl_bit + clc + jsr count_until_vbl_bit + + jmp calibrate_done +.endproc + +.proc calibrate_iigs + ; Backup speed and slow down + jsr _get_iigs_speed + pha + lda #SPEED_SLOW + jsr _set_iigs_speed + + ; The same as IIe, but reverted, because... something? +: bit RDVBLBAR ; Wait for bit 7 to be on (VBL start) + bpl :- +: bit RDVBLBAR ; Wait for bit 7 to be off (VBL end) + bmi :- + + ; Wait and count during a full cycle + ldx #$00 + clc + jsr count_until_vbl_bit + sec + jsr count_until_vbl_bit + + jsr calibrate_done + + ; Restore user speed + pla + jmp _set_iigs_speed +.endproc + +.proc calibrate_done + ; Consider X +/- 3 to be valid, + ; anything else is unknown. + + lda #TV::NTSC + cpx #NTSC_LOOP_COUNT-3 + bcc unexpected + cpx #NTSC_LOOP_COUNT+3 + bcc matched + + lda #TV::PAL + cpx #PAL_LOOP_COUNT-3 + bcc unexpected + cpx #PAL_LOOP_COUNT+3 + bcs unexpected + +matched: + sta tv + +unexpected: + rts +.endproc + + .code + +; The only thing remaining from that code after init +.proc _get_tv + lda tv + ldx #>$0000 + rts +.endproc + + .segment "INIT" + +tv: .byte TV::OTHER From 6a17aedd812059e3a71e2d3e2e655cc2c643270c Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Tue, 25 Feb 2025 02:09:30 -0800 Subject: [PATCH 410/707] conform to 6.4.4.4 for hex and octal escapes fixes problem noted in #2610 --- src/cc65/litpool.c | 26 ++++++---------- src/cc65/litpool.h | 5 --- src/cc65/scanner.c | 39 +++++++++++++++++++---- src/cc65/scanner.h | 1 + src/common/strbuf.c | 55 ++++++++++++++++++++++++++++++--- src/common/strbuf.h | 39 ++++++++++++++++++++--- src/common/tgttrans.c | 16 ++++++++-- test/val/bug2609.c | 72 +++++++++++++++++++++++++++++++++++++++++++ test/val/bug2610.c | 15 +++++++++ 9 files changed, 228 insertions(+), 40 deletions(-) create mode 100644 test/val/bug2609.c create mode 100644 test/val/bug2610.c diff --git a/src/cc65/litpool.c b/src/cc65/litpool.c index 5433f6d95..6d8827c60 100644 --- a/src/cc65/litpool.c +++ b/src/cc65/litpool.c @@ -92,7 +92,7 @@ static Collection LPStack = STATIC_COLLECTION_INITIALIZER; -static Literal* NewLiteral (const void* Buf, unsigned Len) +static Literal* NewLiteral (const StrBuf* S) /* Create a new literal and return it */ { /* Allocate memory */ @@ -103,7 +103,7 @@ static Literal* NewLiteral (const void* Buf, unsigned Len) L->RefCount = 0; L->Output = 0; SB_Init (&L->Data); - SB_AppendBuf (&L->Data, Buf, Len); + SB_Append (&L->Data, S); /* Return the new literal */ return L; @@ -162,7 +162,7 @@ void ReleaseLiteral (Literal* L) void TranslateLiteral (Literal* L) /* Translate a literal into the target charset */ { - TgtTranslateBuf (SB_GetBuf (&L->Data), SB_GetLen (&L->Data)); + TgtTranslateStrBuf (&L->Data); } @@ -468,18 +468,18 @@ void OutputGlobalLiteralPool (void) Literal* AddLiteral (const char* S) /* Add a literal string to the literal pool. Return the literal. */ { - return AddLiteralBuf (S, strlen (S) + 1); + StrBuf SB; + SB_InitFromString(&SB, S); + return AddLiteralStr(&SB); } -Literal* AddLiteralBuf (const void* Buf, unsigned Len) -/* Add a buffer containing a literal string to the literal pool. Return the -** literal. -*/ +Literal* AddLiteralStr (const StrBuf* S) +/* Add a literal string to the literal pool. Return the literal. */ { /* Create a new literal */ - Literal* L = NewLiteral (Buf, Len); + Literal* L = NewLiteral (S); /* Add the literal to the correct pool */ if (IS_Get (&WritableStrings)) { @@ -491,11 +491,3 @@ Literal* AddLiteralBuf (const void* Buf, unsigned Len) /* Return the new literal */ return L; } - - - -Literal* AddLiteralStr (const StrBuf* S) -/* Add a literal string to the literal pool. Return the literal. */ -{ - return AddLiteralBuf (SB_GetConstBuf (S), SB_GetLen (S)); -} diff --git a/src/cc65/litpool.h b/src/cc65/litpool.h index 5f444bfb8..959924e94 100644 --- a/src/cc65/litpool.h +++ b/src/cc65/litpool.h @@ -125,11 +125,6 @@ void OutputGlobalLiteralPool (void); Literal* AddLiteral (const char* S); /* Add a literal string to the literal pool. Return the literal. */ -Literal* AddLiteralBuf (const void* Buf, unsigned Len); -/* Add a buffer containing a literal string to the literal pool. Return the -** literal. -*/ - Literal* AddLiteralStr (const StrBuf* S); /* Add a literal string to the literal pool. Return the literal. */ diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 879925c7c..5186ff402 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -163,6 +163,12 @@ static const struct Keyword { typedef uint32_t scan_t; +/* ParseChar return values */ +typedef struct { + int Val; + int Cooked; +} parsedchar_t; + /*****************************************************************************/ /* code */ /*****************************************************************************/ @@ -326,13 +332,16 @@ static void SetTok (int tok) -static int ParseChar (void) +static parsedchar_t ParseChar (void) /* Parse a character token. Converts escape chars into character codes. */ { + parsedchar_t Result; int C; int HadError; int Count; + Result.Cooked = 1; + /* Check for escape chars */ if (CurC == '\\') { NextChar (); @@ -373,6 +382,7 @@ static int ParseChar (void) case 'x': case 'X': /* Hex character constant */ + Result.Cooked = 0; if (!IsXDigit (NextC)) { Error ("\\x used with no following hex digits"); C = ' '; @@ -401,6 +411,7 @@ static int ParseChar (void) case '6': case '7': /* Octal constant */ + Result.Cooked = 0; Count = 1; C = HexVal (CurC); while (IsODigit (NextC) && Count++ < 3) { @@ -423,7 +434,12 @@ static int ParseChar (void) NextChar (); /* Do correct sign extension */ - return SignExtendChar (C); + Result.Val = SignExtendChar(C); + if (Result.Cooked) { + Result.Cooked = Result.Val; + } + + return Result; } @@ -431,7 +447,7 @@ static int ParseChar (void) static void CharConst (void) /* Parse a character constant token */ { - int C; + parsedchar_t C; if (CurC == 'L') { /* Wide character constant */ @@ -457,7 +473,8 @@ static void CharConst (void) } /* Translate into target charset */ - NextTok.IVal = SignExtendChar (C); + NextTok.IVal = SignExtendChar (C.Val); + NextTok.Cooked = C.Cooked; /* Character constants have type int */ NextTok.Type = type_int; @@ -468,6 +485,9 @@ static void CharConst (void) static void StringConst (void) /* Parse a quoted string token */ { + /* result from ParseChar */ + parsedchar_t ParsedChar; + /* String buffer */ StrBuf S = AUTO_STRBUF_INITIALIZER; @@ -494,7 +514,8 @@ static void StringConst (void) Error ("Unexpected newline"); break; } - SB_AppendChar (&S, ParseChar ()); + ParsedChar = ParseChar (); + SB_AppendCharCooked(&S, ParsedChar.Val, ParsedChar.Cooked); } /* Skip closing quote char if there was one */ @@ -689,6 +710,7 @@ static void NumericConst (void) /* Set the value and the token */ NextTok.IVal = IVal; + NextTok.Cooked = 0; NextTok.Tok = TOK_ICONST; } else { @@ -805,7 +827,12 @@ static void GetNextInputToken (void) if (NextTok.Tok == TOK_SCONST || NextTok.Tok == TOK_WCSCONST) { TranslateLiteral (NextTok.SVal); } else if (NextTok.Tok == TOK_CCONST || NextTok.Tok == TOK_WCCONST) { - NextTok.IVal = SignExtendChar (TgtTranslateChar (NextTok.IVal)); + if (NextTok.Cooked) { + NextTok.IVal = SignExtendChar (TgtTranslateChar (NextTok.IVal)); + } + else { + NextTok.IVal = SignExtendChar (NextTok.IVal); + } } } diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index 6fc3e5370..a8b8a8ab2 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -213,6 +213,7 @@ typedef struct Token Token; struct Token { token_t Tok; /* The token itself */ long IVal; /* The integer attribute */ + int Cooked; /* The "cooked" flag for char constants */ Double FVal; /* The float attribute */ struct Literal* SVal; /* String literal is any */ ident Ident; /* Identifier if IDENT */ diff --git a/src/common/strbuf.c b/src/common/strbuf.c index 79419f1c4..c5b27ee63 100644 --- a/src/common/strbuf.c +++ b/src/common/strbuf.c @@ -82,6 +82,7 @@ StrBuf* SB_InitFromString (StrBuf* B, const char* S) B->Len = strlen (S); B->Index = 0; B->Buf = (char*) S; + B->Cooked = (char*) S; return B; } @@ -92,6 +93,7 @@ void SB_Done (StrBuf* B) { if (B->Allocated) { xfree (B->Buf); + xfree (B->Cooked); } } @@ -146,10 +148,12 @@ void SB_Realloc (StrBuf* B, unsigned NewSize) */ if (B->Allocated) { /* Just reallocate the block */ - B->Buf = xrealloc (B->Buf, NewAllocated); + B->Buf = xrealloc (B->Buf, NewAllocated); + B->Cooked = xrealloc (B->Cooked, NewAllocated); } else { /* Allocate a new block and copy */ - B->Buf = memcpy (xmalloc (NewAllocated), B->Buf, B->Len); + B->Buf = memcpy (xmalloc (NewAllocated), B->Buf, B->Len); + B->Cooked = memcpy (xmalloc (NewAllocated), B->Cooked, B->Len); } /* Remember the new block size */ @@ -178,10 +182,12 @@ static void SB_CheapRealloc (StrBuf* B, unsigned NewSize) /* Free the old buffer if there is one */ if (B->Allocated) { xfree (B->Buf); + xfree (B->Cooked); } /* Allocate a fresh block */ - B->Buf = xmalloc (NewAllocated); + B->Buf = xmalloc (NewAllocated); + B->Cooked = xmalloc (NewAllocated); /* Remember the new block size */ B->Allocated = NewAllocated; @@ -222,6 +228,7 @@ void SB_Terminate (StrBuf* B) SB_Realloc (B, NewLen); } B->Buf[B->Len] = '\0'; + B->Cooked[B->Len] = '\0'; } @@ -234,6 +241,22 @@ void SB_CopyBuf (StrBuf* Target, const char* Buf, unsigned Size) SB_CheapRealloc (Target, Size); } memcpy (Target->Buf, Buf, Size); + memcpy (Target->Cooked, Buf, Size); /* nothing raw */ + } + Target->Len = Size; +} + + + +void SB_CopyBufCooked (StrBuf* Target, const char* Buf, const char* Cooked, unsigned Size) +/* Copy Buf and Cooked to Target, discarding the old contents of Target */ +{ + if (Size) { + if (Target->Allocated < Size) { + SB_CheapRealloc (Target, Size); + } + memcpy (Target->Buf, Buf, Size); + memcpy (Target->Cooked, Cooked, Size); } Target->Len = Size; } @@ -254,7 +277,7 @@ void SB_CopyStr (StrBuf* Target, const char* S) void SB_Copy (StrBuf* Target, const StrBuf* Source) /* Copy Source to Target, discarding the old contents of Target */ { - SB_CopyBuf (Target, Source->Buf, Source->Len); + SB_CopyBufCooked (Target, Source->Buf, Source->Cooked, Source->Len); Target->Index = Source->Index; } #endif @@ -269,6 +292,21 @@ void SB_AppendChar (StrBuf* B, int C) SB_Realloc (B, NewLen); } B->Buf[B->Len] = (char) C; + B->Cooked[B->Len] = (char) C; + B->Len = NewLen; +} + + + +void SB_AppendCharCooked (StrBuf* B, int C, int Cooked) +/* Append a character to a string buffer */ +{ + unsigned NewLen = B->Len + 1; + if (NewLen > B->Allocated) { + SB_Realloc (B, NewLen); + } + B->Buf[B->Len] = (char) C; + B->Cooked[B->Len] = (char) (Cooked ? C : 0); B->Len = NewLen; } @@ -282,6 +320,7 @@ void SB_AppendBuf (StrBuf* B, const char* S, unsigned Size) SB_Realloc (B, NewLen); } memcpy (B->Buf + B->Len, S, Size); + memcpy (B->Cooked + B->Len, S, Size); B->Len = NewLen; } @@ -301,7 +340,13 @@ void SB_AppendStr (StrBuf* B, const char* S) void SB_Append (StrBuf* Target, const StrBuf* Source) /* Append the contents of Source to Target */ { - SB_AppendBuf (Target, Source->Buf, Source->Len); + unsigned NewLen = Target->Len + Source->Len; + if (NewLen > Target->Allocated) { + SB_Realloc (Target, NewLen); + } + memcpy (Target->Buf + Target->Len, Source->Buf, Source->Len); + memcpy (Target->Cooked + Target->Len, Source->Cooked, Source->Len); + Target->Len = NewLen; } #endif diff --git a/src/common/strbuf.h b/src/common/strbuf.h index e0602a6c8..372b1be0b 100644 --- a/src/common/strbuf.h +++ b/src/common/strbuf.h @@ -53,10 +53,17 @@ /*****************************************************************************/ +/* We want to track whether a character is "raw" or not. */ +/* "raw" characters should NOT be translated when translating a string. */ +/* We do this by keeping a second array parallel to "Buf" called "Cooked". */ +/* Think of "cooked" as the inverse of "raw". */ +/* If Cooked[n] is 0, then the character is raw and should not be translated. */ +/* This was done to keep LIT_STR_BUFFER sane. */ typedef struct StrBuf StrBuf; struct StrBuf { char* Buf; /* Pointer to buffer */ + char* Cooked; /* Pointer to cooked buffer */ unsigned Len; /* Length of the string */ unsigned Index; /* Used for reading (Get and friends) */ unsigned Allocated; /* Size of allocated memory */ @@ -66,13 +73,13 @@ struct StrBuf { extern const StrBuf EmptyStrBuf; /* Initializer for static string bufs */ -#define STATIC_STRBUF_INITIALIZER { 0, 0, 0, 0 } +#define STATIC_STRBUF_INITIALIZER { 0, 0, 0, 0, 0 } /* Initializer for auto string bufs */ -#define AUTO_STRBUF_INITIALIZER { 0, 0, 0, 0 } +#define AUTO_STRBUF_INITIALIZER { 0, 0, 0, 0, 0 } /* Initialize with a string literal (beware: evaluates str twice!) */ -#define LIT_STRBUF_INITIALIZER(str) { (char*)str, sizeof(str)-1, 0, 0 } +#define LIT_STRBUF_INITIALIZER(str) { (char*)str, (char *)str, sizeof(str)-1, 0, 0 } @@ -164,6 +171,16 @@ INLINE char* SB_GetBuf (StrBuf* B) # define SB_GetBuf(B) (B)->Buf #endif +#if defined(HAVE_INLINE) +INLINE char* SB_GetCooked (StrBuf* B) +/* Return a cooked pointer */ +{ + return B->Cooked; +} +#else +# define SB_GetCooked(B) (B)->Cooked +#endif + #if defined(HAVE_INLINE) INLINE char SB_At (const StrBuf* B, unsigned Index) /* Get a character from the buffer */ @@ -310,6 +327,9 @@ void SB_Terminate (StrBuf* B); void SB_CopyBuf (StrBuf* Target, const char* Buf, unsigned Size); /* Copy Buf to Target, discarding the old contents of Target */ +void SB_CopyBufCooked (StrBuf* Target, const char* Buf, const char *Cooked, unsigned Size); +/* Copy Buf and Cooked to Target, discarding the old contents of Target */ + #if defined(HAVE_INLINE) INLINE void SB_CopyStr (StrBuf* Target, const char* S) /* Copy S to Target, discarding the old contents of Target */ @@ -325,7 +345,7 @@ void SB_CopyStr (StrBuf* Target, const char* S); INLINE void SB_Copy (StrBuf* Target, const StrBuf* Source) /* Copy Source to Target, discarding the old contents of Target */ { - SB_CopyBuf (Target, Source->Buf, Source->Len); + SB_CopyBufCooked (Target, Source->Buf, Source->Cooked, Source->Len); Target->Index = Source->Index; } #else @@ -336,6 +356,9 @@ void SB_Copy (StrBuf* Target, const StrBuf* Source); void SB_AppendChar (StrBuf* B, int C); /* Append a character to a string buffer */ +void SB_AppendCharCooked (StrBuf* B, int C, int Cooked); +/* Append a character to a string buffer, raw if Cooked == 0 */ + void SB_AppendBuf (StrBuf* B, const char* S, unsigned Size); /* Append a character buffer to the end of the string buffer */ @@ -354,7 +377,13 @@ void SB_AppendStr (StrBuf* B, const char* S); INLINE void SB_Append (StrBuf* Target, const StrBuf* Source) /* Append the contents of Source to Target */ { - SB_AppendBuf (Target, Source->Buf, Source->Len); + unsigned NewLen = Target->Len + Source->Len; + if (NewLen > Target->Allocated) { + SB_Realloc (Target, NewLen); + } + memcpy (Target->Buf + Target->Len, Source->Buf, Source->Len); + memcpy (Target->Cooked + Target->Len, Source->Cooked, Source->Len); + Target->Len = NewLen; } #else void SB_Append (StrBuf* Target, const StrBuf* Source); diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index 3310eab81..3ac41f09e 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -121,7 +121,19 @@ void TgtTranslateStrBuf (StrBuf* Buf) ** system character set. */ { - TgtTranslateBuf (SB_GetBuf (Buf), SB_GetLen (Buf)); + unsigned char* B = (unsigned char*)SB_GetBuf(Buf); + unsigned char* Cooked = (unsigned char*)SB_GetCooked(Buf); + unsigned Len = SB_GetLen(Buf); + + /* Translate */ + while (Len--) { + if (*Cooked) { + *B = Tab[*B]; + } + /* else { *B = *B; } */ + ++B; + ++Cooked; + } } @@ -129,7 +141,7 @@ void TgtTranslateStrBuf (StrBuf* Buf) void TgtTranslateSet (unsigned Index, unsigned char C) /* Set the translation code for the given character */ { - CHECK (Index < sizeof (Tab)); + CHECK (Index < (sizeof (Tab) / sizeof(Tab[0]))); Tab[Index] = C; } diff --git a/test/val/bug2609.c b/test/val/bug2609.c new file mode 100644 index 000000000..418673e98 --- /dev/null +++ b/test/val/bug2609.c @@ -0,0 +1,72 @@ +/* Bug #2609 - charmap translation violates C specification 6.4.4.4 Character constant */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#pragma charmap (0x07, 0x62) /* map \a to b */ +static_assert('\a' == 0x62); +static_assert('\07' == 0x07); +static_assert('\x07' == 0x07); + +#pragma charmap (0x07, 0x63) /* map \a to c */ +static_assert('\a' == 0x63); +static_assert('\07' == 0x07); +static_assert('\x07' == 0x07); + +#pragma charmap (0x07, 0x07) /* map \a back to x07 */ +static_assert('\a' == 0x07); +static_assert('\07' == 0x07); +static_assert('\x07' == 0x07); + +#pragma charmap (0x07, 0x61) /* map \a to a */ + +char *s = "\07\a\x07"; +char t[] = { 7, 0x61, 7, 0 }; + +static_assert('\a' == 0x61); +static_assert('\07' == 0x07); +static_assert('\x07' == 0x07); + +char c_back_a = '\a'; +char c_hex_07 = '\x07'; +char c_oct_07 = '\07'; +int i_back_a = '\a'; +int i_hex_07 = '\x07'; +int i_oct_07 = '\07'; + +#define TEST(a,b) \ + if (a != b) { printf("\n\n !FAIL! %s = %04x not %04x\n\n", #a, a, b); return EXIT_FAILURE; } + +int main (void) { + int i; + + TEST(c_back_a, 0x61) + TEST(c_hex_07, 0x07) + TEST(c_oct_07, 07) + + TEST(i_back_a, 0x61) + TEST(i_hex_07, 0x07) + TEST(i_oct_07, 07) + + assert('\a' == 0x61); + assert('\07' == 0x07); + assert('\x07' == 0x07); + + if (strcmp(s,t) || s[0] == s[1]) { + printf("\n\n !FAIL! strcmp\n"); + for (i = 0; i < 4; i++) { + printf("%02x ", s[i]); + } + printf("\n"); + for (i = 0; i < 4; i++) { + printf("%02x ", t[i]); + } + printf("\n"); + printf("\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/test/val/bug2610.c b/test/val/bug2610.c new file mode 100644 index 000000000..75169b81d --- /dev/null +++ b/test/val/bug2610.c @@ -0,0 +1,15 @@ +#include <stdio.h> +#if '\x0A' != 0x0A +#error "Suspicious character set translation" +#endif +int main() +{ + char c = '\x0A'; + if (c == 0x0A) { + printf("Ok\n"); + return 0; + } else { + printf("Failed\n"); + return 1; + } +} From 060522a740e6d610a05c4a43e766bade556e391e Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Fri, 2 May 2025 05:43:14 +0000 Subject: [PATCH 411/707] issue #2633 print unambiguous success message --- test/Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index fbdf8c5d1..24851ee7b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -12,7 +12,7 @@ endif WORKDIR = ../testwrk -.PHONY: test continue mostlyclean clean +.PHONY: test continue mostlyclean clean success_message test: @$(MAKE) mostlyclean @@ -27,6 +27,12 @@ continue: @$(MAKE) -C standard all @$(MAKE) -C misc all @$(MAKE) -C todo all + @$(MAKE) success_message + +success_message: + $(info ###################################) + $(info ### validation suite successful ###) + $(info ###################################) mostlyclean: @$(MAKE) -C asm clean From f13f2cb6196ec0dc2d091c64e6f87cd1f5c5aead Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Sat, 3 May 2025 02:36:44 +0000 Subject: [PATCH 412/707] fixes issue #2637 --- src/cc65/preproc.c | 3 ++- test/misc/Makefile | 6 ++++++ test/misc/bug2637.c | 15 +++++++++++++++ test/misc/bug2637.ref | 0 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 test/misc/bug2637.c create mode 100644 test/misc/bug2637.ref diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index d033520b8..5cdec3142 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -2647,8 +2647,9 @@ static void DoDefine (void) ** "There shall be white-space between the identifier and the ** replacement list in the definition of an object-like macro." ** Note: C89 doesn't have this constraint. + ** Note: if there is no replacement list, a space is not required. */ - if (Std == STD_C99 && !IsSpace (CurC)) { + if (Std == STD_C99 && !IsSpace (CurC) && CurC != 0) { PPWarning ("ISO C99 requires whitespace after the macro name"); } diff --git a/test/misc/Makefile b/test/misc/Makefile index ebae0964e..f5225b14b 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -110,6 +110,12 @@ $(WORKDIR)/bug2515.$1.$2.prg: bug2515.c | $(WORKDIR) $(NOT) $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< 2>$(WORKDIR)/bug2515.$1.$2.out $(ISEQUAL) $(WORKDIR)/bug2515.$1.$2.out bug2515.ref +# should not issue any warnings in C99 mode +$(WORKDIR)/bug2637.$1.$2.prg: bug2637.c | $(WORKDIR) + $(if $(QUIET),echo misc/bug2637.$1.$2.prg) + $(CC65) --standard c99 -t sim$2 -$1 -o $$(@:.prg=.s) $$< 2>$(WORKDIR)/bug2637.$1.$2.out + $(ISEQUAL) $(WORKDIR)/bug2637.$1.$2.out bug2637.ref + # this one requires -Werror $(WORKDIR)/bug1768.$1.$2.prg: bug1768.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1768.$1.$2.prg) diff --git a/test/misc/bug2637.c b/test/misc/bug2637.c new file mode 100644 index 000000000..f6b716465 --- /dev/null +++ b/test/misc/bug2637.c @@ -0,0 +1,15 @@ +#include <stdarg.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +// compile with --standard c99 +int main() +{ + return 0; +} diff --git a/test/misc/bug2637.ref b/test/misc/bug2637.ref new file mode 100644 index 000000000..e69de29bb From f48fb035405ca65f9b0a27e2cf2f7b1eb8f15631 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Fri, 2 May 2025 07:02:07 +0000 Subject: [PATCH 413/707] issue #2607, enable '\e' character escape for --standard cc65 --- doc/cc65.sgml | 10 +++++ src/cc65/scanner.c | 9 +++++ test/Makefile | 2 + test/readme.txt | 8 +++- test/standard/issue2607_cc65.c | 14 +++++++ test/standard_err/Makefile | 55 ++++++++++++++++++++++++++ test/standard_err/issue2607_not_cc65.c | 14 +++++++ 7 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 test/standard/issue2607_cc65.c create mode 100644 test/standard_err/Makefile create mode 100644 test/standard_err/issue2607_not_cc65.c diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 781e460a8..6793603d5 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1053,6 +1053,16 @@ This cc65 version has some extensions to the ISO C standard. unsigned char foo = 0b101; // sets it to 5 </verb></tscreen> +<item> The character escape '\e', a GCC C extension, is accepted. + In ASCII this is the escape character 0x1B, which may be + remapped in other character sets via a #pragma charmap. + It can be disabled with the <tt><ref id="option--standard" + name="--standard"></tt> option. + + <tscreen><verb> + unsigned char foo = '\e'; // sets it to 0x1B or equivalent + </verb></tscreen> + </itemize> <p> diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 879925c7c..7369d7fde 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -346,6 +346,14 @@ static int ParseChar (void) case 'b': C = '\b'; break; + case 'e': + if (IS_Get(&Standard) != STD_CC65) { + goto IllegalEscape; + } + /* we'd like to use \e here, but */ + /* not all build systems support it */ + C = '\x1B'; + break; case 'f': C = '\f'; break; @@ -411,6 +419,7 @@ static int ParseChar (void) Error ("Octal character constant out of range"); break; default: +IllegalEscape: C = CurC; Error ("Illegal escaped character: 0x%02X", CurC); break; diff --git a/test/Makefile b/test/Makefile index fbdf8c5d1..af18ddd7d 100644 --- a/test/Makefile +++ b/test/Makefile @@ -25,6 +25,7 @@ continue: @$(MAKE) -C ref all @$(MAKE) -C err all @$(MAKE) -C standard all + @$(MAKE) -C standard_err all @$(MAKE) -C misc all @$(MAKE) -C todo all @@ -35,6 +36,7 @@ mostlyclean: @$(MAKE) -C ref clean @$(MAKE) -C err clean @$(MAKE) -C standard clean + @$(MAKE) -C standard_err clean @$(MAKE) -C misc clean @$(MAKE) -C todo clean diff --git a/test/readme.txt b/test/readme.txt index d3f17148e..0aa8799b9 100644 --- a/test/readme.txt +++ b/test/readme.txt @@ -12,6 +12,8 @@ compiler is working as expected (when the tests behave as described): /val - The bulk of tests are contained here, individual tests should exit with an exit code of EXIT_SUCCESS when they pass, or EXIT_FAILURE on error. +/err - contains tests that MUST NOT compile + /standard - like the tests in /val, the tests must exit with EXIT_SUCCESS on success. Unlike the tests in /val these are not compiled for every combination of optimizer options, but instead always with -Osir and then @@ -19,6 +21,10 @@ compiler is working as expected (when the tests behave as described): to check for regressions in standard conformance of the compiler and the library. +/standard_err - like the tests in /err, these tests MUST NOT compile, and like + the tests in /standard, these are compiled -Osir and then for each + supported C-Standard. + /ref - These tests produce output that must be compared with reference output. Normally the reference output is produced by compiling the program on the host (using gcc mostly) and then running them on the host. Tests should @@ -43,8 +49,6 @@ compiler is working as expected (when the tests behave as described): only ever use this as a last resort when something can not be tested by other means. -/err - contains tests that MUST NOT compile - /todo and /misc generally contain the tests that fail because of known bugs: diff --git a/test/standard/issue2607_cc65.c b/test/standard/issue2607_cc65.c new file mode 100644 index 000000000..82ff9d1aa --- /dev/null +++ b/test/standard/issue2607_cc65.c @@ -0,0 +1,14 @@ +#include <stdio.h> +#include <stdlib.h> + +/* this should succeed on all three standards + * yet use only \e on CC65 + */ +int main(void) { + +#if __CC65_STD__ == __CC65_STD_CC65__ + printf("\e"); +#endif + + return EXIT_SUCCESS; +} diff --git a/test/standard_err/Makefile b/test/standard_err/Makefile new file mode 100644 index 000000000..700a52eea --- /dev/null +++ b/test/standard_err/Makefile @@ -0,0 +1,55 @@ +# Makefile for the tests that MUST NOT compile + +ifneq ($(shell echo),) + CMD_EXE = 1 +endif + +ifdef CMD_EXE + S = $(subst /,\,/) + NOT = - # Hack + NULLDEV = nul: + MKDIR = mkdir $(subst /,\,$1) + RMDIR = -rmdir /s /q $(subst /,\,$1) +else + S = / + NOT = ! + NULLDEV = /dev/null + MKDIR = mkdir -p $1 + RMDIR = $(RM) -r $1 +endif + +ifdef QUIET + .SILENT: + NULLERR = 2>$(NULLDEV) +endif + +CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) + +WORKDIR = ../../testwrk/standard_err + +OPTIONS = c89 c99 cc65 + +.PHONY: all clean + +SOURCES := $(wildcard *.c) +TESTS = $(foreach option,$(OPTIONS),$(SOURCES:%.c=$(WORKDIR)/%.$(option).6502.prg)) + +all: $(TESTS) + +$(WORKDIR): + $(call MKDIR,$(WORKDIR)) + +define PRG_template + +$(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) + $(if $(QUIET),echo standard_err/$$*.$1.$2.prg) + $(NOT) $(CC65) -t sim$2 $$(CC65FLAGS) -Osir --add-source --standard $1 -o $$(@:.prg=.s) $$< $(NULLERR) + +endef # PRG_template + +$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),6502))) + +#$(foreach option,$(OPTIONS),$(eval $(call PRG_template,$(option),65c02))) + +clean: + @$(call RMDIR,$(WORKDIR)) diff --git a/test/standard_err/issue2607_not_cc65.c b/test/standard_err/issue2607_not_cc65.c new file mode 100644 index 000000000..5e56df557 --- /dev/null +++ b/test/standard_err/issue2607_not_cc65.c @@ -0,0 +1,14 @@ +#include <stdio.h> +#include <stdlib.h> + +/* this should fail on all three standards + */ +int main(void) { + +#if __CC65_STD__ != __CC65_STD_CC65__ + printf("\e"); +#else +#error "this needs to error on CC65 to make it through validation" +#endif + return EXIT_SUCCESS; +} From 1b85ab698545c14f14da2b975984f4c9270ced2f Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Tue, 6 May 2025 03:02:18 +0000 Subject: [PATCH 414/707] C style character translation in ca65 --- libsrc/common/fgets.s | 17 +----- src/ca65/scanner.c | 131 +++++++++++++++++++++++++++++++++--------- 2 files changed, 104 insertions(+), 44 deletions(-) diff --git a/libsrc/common/fgets.s b/libsrc/common/fgets.s index d5ea900d0..c25664f19 100644 --- a/libsrc/common/fgets.s +++ b/libsrc/common/fgets.s @@ -90,22 +90,7 @@ read_loop: bne :+ inc ptr4+1 - ; The next code line: - ; - ; .byte $c9, "\n" - ; - ; corresponds to a CMP #imm with the target-specific newline value as its operand. - ; This works because (with the 'string_escapes' feature enabled), the "\n" string - ; assembles to the target-specific value for the newline character. - ; - ; It would be better if we could just write: - ; - ; cmp #'\n' - ; - ; Unfortunately, ca65 doesn't currently handle escape characters in character - ; constants. In the longer term, fixing that would be the preferred solution. - -: .byte $c9, "\n" ; cmp #'\n' +: cmp #'\n' ; #'\n' should get translated properly beq done bne read_loop diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 89ff851fc..8b910e672 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -46,6 +46,7 @@ #include "check.h" #include "filestat.h" #include "fname.h" +#include "tgttrans.h" #include "xmalloc.h" /* ca65 */ @@ -788,14 +789,33 @@ static void ReadIdent (void) static void ReadStringConst (int StringTerm) /* Read a string constant into SVal. */ { + int NeedNext; + /* Skip the leading string terminator */ NextChar (); /* Read the string */ while (1) { + int Cooked = 1; + NeedNext = 1; + + if (StringTerm == 0 && SB_GetLen(&CurTok.SVal) == 1) { + if (C == '\'') { + break; + } + else if (MissingCharTerm) { + NeedNext = 0; + break; + } + else { + Error ("Illegal character constant"); + } + } + if (C == StringTerm) { break; } + if (C == '\n' || C == EOF) { Error ("Newline in string constant"); break; @@ -808,20 +828,74 @@ static void ReadStringConst (int StringTerm) case EOF: Error ("Unterminated escape sequence in string constant"); break; - case '\\': - case '\'': - case '"': + case '?': + C = '\?'; break; - case 't': - C = '\x09'; + case 'a': + C = '\a'; + break; + case 'b': + C = '\b'; + break; + case 'e': + C = '\x1B'; /* see comments in cc65/scanner.c */ + break; + case 'f': + C = '\f'; break; case 'r': - C = '\x0D'; + C = '\r'; break; case 'n': - C = '\x0A'; + C = '\n'; break; + case 't': + C = '\t'; + break; + case 'v': + C = '\v'; + break; + case '\\': + C = '\\'; /* unnecessary but more readable */ + break; + case '\'': + C = '\''; /* unnecessary but more readable */ + if (StringTerm == 0) { + /* special case used by character constants + ** when LooseStringTerm not set. this will + ** cause '\' to be a valid character constant + */ + C = '\\'; + NeedNext = 0; + } + break; + case '\"': + C = '\"'; /* unnecessary but more readable */ + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { /* brace needed for scoping */ + int Count = 1; + int Final = DigitVal(C); + Cooked = 0; + NextChar (); + while (IsODigit (C) && Count++ < 3) { + Final = (Final << 3) | DigitVal(C); + NextChar(); + } + if (C >= 256) + Error ("Octal character constant out of range"); + } + break; + case 'X': case 'x': + Cooked = 0; NextChar (); if (IsXDigit (C)) { char high_nibble = DigitVal (C) << 4; @@ -839,14 +913,19 @@ static void ReadStringConst (int StringTerm) } /* Append the char to the string */ - SB_AppendChar (&CurTok.SVal, C); + SB_AppendCharCooked (&CurTok.SVal, C, Cooked); - /* Skip the character */ - NextChar (); + if (NeedNext) { + /* Skip the character */ + NextChar (); + NeedNext = 1; + } } - /* Skip the trailing terminator */ - NextChar (); + if (NeedNext) { + /* Skip the trailing terminator */ + NextChar (); + } /* Terminate the string */ SB_Terminate (&CurTok.SVal); @@ -1465,12 +1544,13 @@ CharAgain: return; case '\'': - /* Hack: If we allow ' as terminating character for strings, read - ** the following stuff as a string, and check for a one character - ** string later. - */ if (LooseStringTerm) { + /* Hack: If we allow ' as terminating character for strings, read + ** the following stuff as a string, and check for a one character + ** string later. + */ ReadStringConst ('\''); + TgtTranslateStrBuf(&CurTok.SVal); if (SB_GetLen (&CurTok.SVal) == 1) { CurTok.IVal = SB_AtUnchecked (&CurTok.SVal, 0); CurTok.Tok = TOK_CHARCON; @@ -1478,22 +1558,17 @@ CharAgain: CurTok.Tok = TOK_STRCON; } } else { - /* Always a character constant */ - NextChar (); - if (C == EOF || IsControl (C)) { + /* Always a character constant + ** Hack: Pass 0 to ReadStringConst for special handling. + */ + ReadStringConst(0); + TgtTranslateStrBuf(&CurTok.SVal); + if (SB_GetLen(&CurTok.SVal) != 1) { Error ("Illegal character constant"); goto CharAgain; } - CurTok.IVal = C; + CurTok.IVal = SB_AtUnchecked (&CurTok.SVal, 0); CurTok.Tok = TOK_CHARCON; - NextChar (); - if (C != '\'') { - if (!MissingCharTerm) { - Error ("Illegal character constant"); - } - } else { - NextChar (); - } } return; From c5a3dbdf382c2163abefe5cc403542d297108688 Mon Sep 17 00:00:00 2001 From: Jimmy Dansbo <jimmy@dansbo.dk> Date: Tue, 6 May 2025 09:09:07 +0200 Subject: [PATCH 415/707] Add additional video modes that were added in ROM Pre Release 43 --- include/cx16.h | 7 ++++++- libsrc/cx16/videomode.s | 25 ++++++++++++++++--------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/include/cx16.h b/include/cx16.h index 5bbd21247..ad8afe200 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -3,7 +3,7 @@ /* cx16.h */ /* */ /* CX16 system-specific definitions */ -/* For prerelease 39 */ +/* For prerelease 43 */ /* */ /* */ /* This software is provided "as-is", without any expressed or implied */ @@ -176,6 +176,11 @@ enum { #define VIDEOMODE_40x15 0x04 #define VIDEOMODE_20x30 0x05 #define VIDEOMODE_20x15 0x06 +#define VIDEOMODE_22x23 0x07 +#define VIDEOMODE_64x50 0x08 +#define VIDEOMODE_64x25 0x09 +#define VIDEOMODE_32x50 0x0A +#define VIDEOMODE_32x25 0x0B #define VIDEOMODE_80COL VIDEOMODE_80x60 #define VIDEOMODE_40COL VIDEOMODE_40x30 #define VIDEOMODE_320x240 0x80 diff --git a/libsrc/cx16/videomode.s b/libsrc/cx16/videomode.s index 998316858..03374642f 100644 --- a/libsrc/cx16/videomode.s +++ b/libsrc/cx16/videomode.s @@ -2,15 +2,22 @@ ; 2022-03-28, Greg King ; ; /* Video mode defines */ -; #define VIDEOMODE_80x60 0x00 -; #define VIDEOMODE_80x30 0x01 -; #define VIDEOMODE_40x60 0x02 -; #define VIDEOMODE_40x30 0x03 -; #define VIDEOMODE_40x15 0x04 -; #define VIDEOMODE_20x30 0x05 -; #define VIDEOMODE_20x15 0x06 -; #define VIDEOMODE_320x240 0x80 -; #define VIDEOMODE_SWAP (-1) +; #define VIDEOMODE_80x60 0x00 +; #define VIDEOMODE_80x30 0x01 +; #define VIDEOMODE_40x60 0x02 +; #define VIDEOMODE_40x30 0x03 +; #define VIDEOMODE_40x15 0x04 +; #define VIDEOMODE_20x30 0x05 +; #define VIDEOMODE_20x15 0x06 +; #define VIDEOMODE_22x23 0x07 +; #define VIDEOMODE_64x50 0x08 +; #define VIDEOMODE_64x25 0x09 +; #define VIDEOMODE_32x50 0x0A +; #define VIDEOMODE_32x25 0x0B +; #define VIDEOMODE_80COL VIDEOMODE_80x60 +; #define VIDEOMODE_40COL VIDEOMODE_40x30 +; #define VIDEOMODE_320x240 0x80 +; #define VIDEOMODE_SWAP (-1) ; ; signed char __fastcall__ videomode (signed char Mode); ; /* Set the video mode, return the old mode. From d4a37f77778d8925ad707828c3e46562c368e609 Mon Sep 17 00:00:00 2001 From: Jimmy Dansbo <jimmy@dansbo.dk> Date: Tue, 6 May 2025 09:16:12 +0200 Subject: [PATCH 416/707] Changed tabs to spaces --- include/cx16.h | 10 +++++----- libsrc/cx16/videomode.s | 32 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/cx16.h b/include/cx16.h index ad8afe200..6a3705631 100644 --- a/include/cx16.h +++ b/include/cx16.h @@ -176,11 +176,11 @@ enum { #define VIDEOMODE_40x15 0x04 #define VIDEOMODE_20x30 0x05 #define VIDEOMODE_20x15 0x06 -#define VIDEOMODE_22x23 0x07 -#define VIDEOMODE_64x50 0x08 -#define VIDEOMODE_64x25 0x09 -#define VIDEOMODE_32x50 0x0A -#define VIDEOMODE_32x25 0x0B +#define VIDEOMODE_22x23 0x07 +#define VIDEOMODE_64x50 0x08 +#define VIDEOMODE_64x25 0x09 +#define VIDEOMODE_32x50 0x0A +#define VIDEOMODE_32x25 0x0B #define VIDEOMODE_80COL VIDEOMODE_80x60 #define VIDEOMODE_40COL VIDEOMODE_40x30 #define VIDEOMODE_320x240 0x80 diff --git a/libsrc/cx16/videomode.s b/libsrc/cx16/videomode.s index 03374642f..46f461fca 100644 --- a/libsrc/cx16/videomode.s +++ b/libsrc/cx16/videomode.s @@ -2,22 +2,22 @@ ; 2022-03-28, Greg King ; ; /* Video mode defines */ -; #define VIDEOMODE_80x60 0x00 -; #define VIDEOMODE_80x30 0x01 -; #define VIDEOMODE_40x60 0x02 -; #define VIDEOMODE_40x30 0x03 -; #define VIDEOMODE_40x15 0x04 -; #define VIDEOMODE_20x30 0x05 -; #define VIDEOMODE_20x15 0x06 -; #define VIDEOMODE_22x23 0x07 -; #define VIDEOMODE_64x50 0x08 -; #define VIDEOMODE_64x25 0x09 -; #define VIDEOMODE_32x50 0x0A -; #define VIDEOMODE_32x25 0x0B -; #define VIDEOMODE_80COL VIDEOMODE_80x60 -; #define VIDEOMODE_40COL VIDEOMODE_40x30 -; #define VIDEOMODE_320x240 0x80 -; #define VIDEOMODE_SWAP (-1) +; #define VIDEOMODE_80x60 0x00 +; #define VIDEOMODE_80x30 0x01 +; #define VIDEOMODE_40x60 0x02 +; #define VIDEOMODE_40x30 0x03 +; #define VIDEOMODE_40x15 0x04 +; #define VIDEOMODE_20x30 0x05 +; #define VIDEOMODE_20x15 0x06 +; #define VIDEOMODE_22x23 0x07 +; #define VIDEOMODE_64x50 0x08 +; #define VIDEOMODE_64x25 0x09 +; #define VIDEOMODE_32x50 0x0A +; #define VIDEOMODE_32x25 0x0B +; #define VIDEOMODE_80COL VIDEOMODE_80x60 +; #define VIDEOMODE_40COL VIDEOMODE_40x30 +; #define VIDEOMODE_320x240 0x80 +; #define VIDEOMODE_SWAP (-1) ; ; signed char __fastcall__ videomode (signed char Mode); ; /* Set the video mode, return the old mode. From 8fbb4c39c42d0205135cb83175edd74681e1ed29 Mon Sep 17 00:00:00 2001 From: Max <mczonk@gmail.com> Date: Tue, 13 May 2025 09:14:03 +0200 Subject: [PATCH 417/707] Fixed a typo in Granularity --- src/da65/attrtab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/da65/attrtab.c b/src/da65/attrtab.c index b70e017a1..e35530afd 100644 --- a/src/da65/attrtab.c +++ b/src/da65/attrtab.c @@ -149,7 +149,7 @@ unsigned GetGranularity (attr_t Style) case atSkip: default: - Internal ("GetGraularity called for style = %d", Style); + Internal ("GetGranularity called for style = %d", Style); return 0; } } From cfbfaa559cbc75c6af62294dcbaaa4f9dada3306 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Tue, 13 May 2025 21:26:47 +0200 Subject: [PATCH 418/707] Add ZX02 and LZSA (1,2) decompressors --- doc/funcref.sgml | 79 +++++++ include/lzsa.h | 56 +++++ include/zx02.h | 44 ++++ libsrc/common/lzsa1.s | 207 ++++++++++++++++++ libsrc/common/lzsa2.s | 308 +++++++++++++++++++++++++++ libsrc/common/zx02.s | 148 +++++++++++++ test/val/lzsa1.c | 478 ++++++++++++++++++++++++++++++++++++++++++ test/val/lzsa2.c | 438 ++++++++++++++++++++++++++++++++++++++ test/val/zx02.c | 416 ++++++++++++++++++++++++++++++++++++ 9 files changed, 2174 insertions(+) create mode 100644 include/lzsa.h create mode 100644 include/zx02.h create mode 100644 libsrc/common/lzsa1.s create mode 100644 libsrc/common/lzsa2.s create mode 100644 libsrc/common/zx02.s create mode 100644 test/val/lzsa1.c create mode 100644 test/val/lzsa2.c create mode 100644 test/val/zx02.c diff --git a/doc/funcref.sgml b/doc/funcref.sgml index eec04b929..e534b47be 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -521,6 +521,14 @@ see also <tt>testcode/lib/em-test.c</tt> and <tt>samples/multidemo.c</tt>. </itemize> +<sect1><tt/lzsa.h/<label id="lzsa.h"><p> + +<itemize> +<item><ref id="decompress_lzsa1" name="decompress_lzsa1"> +<item><ref id="decompress_lzsa2" name="decompress_lzsa2"> +</itemize> + + <sect1><tt/modload.h/<label id="modload.h"><p> <itemize> @@ -893,6 +901,13 @@ communication, see also <tt>testcode/lib/ser-test.c</tt>. (incomplete) +<sect1><tt/zx02.h/<label id="zx02.h"><p> + +<itemize> +<item><ref id="decompress_zx02" name="decompress_zx02"> +</itemize> + + <sect>Alphabetical function reference<p> <sect1>_DE_ISDIR<label id="_DE_ISDIR"><p> @@ -3381,6 +3396,70 @@ used in presence of a prototype. <tag/Description/<tt/decompress_lz4/ uncompresses a LZ4-compressed buffer. <tag/Notes/<itemize> <item>Use LZ4_compress_HC with compression level 16 for best compression. +<item>Your program will need to know the uncompressed size of the buffer as +there is no end-of-stream marker. +<item>LZ4 is the biggest and second-slowest decompressor shipped in cc65 runtime. +It is also the least efficient compression algorithm. +</itemize> +<tag/Availability/cc65 +<tag/Example/None. +</descrip> +</quote> + + +<sect1>decompress_lzsa1<label id="decompress_lzsa1"><p> + +<quote> +<descrip> +<tag/Function/Uncompress a LZSA buffer with format 1. +<tag/Header/<tt/<ref id="lzsa.h" name="lzsa.h">/ +<tag/Declaration/<tt/void decompress_lzsa1 (const unsigned char* src, unsigned char* const dst);/ +<tag/Description/<tt/decompress_lz4/ uncompresses a LZSA buffer with format 1. +<tag/Notes/<itemize> +<item>Use <tt/lzsa -f 1 -r input.bin output.lzsa1/ to compress your input. +<item>The project and compressor can be found at <url url="https://github.com/emmanuel-marty/lzsa"> +<item>LZSA1 is the fastest decompressor shipped in cc65 runtime, but data is less +compressed than with LZSA2 and ZX02. +</itemize> +<tag/Availability/cc65 +<tag/Example/None. +</descrip> +</quote> + + +<sect1>decompress_lzsa2<label id="decompress_lzsa2"><p> + +<quote> +<descrip> +<tag/Function/Uncompress a LZSA buffer with format 2. +<tag/Header/<tt/<ref id="lzsa.h" name="lzsa.h">/ +<tag/Declaration/<tt/void decompress_lzsa2 (const unsigned char* src, unsigned char* const dst);/ +<tag/Description/<tt/decompress_lz4/ uncompresses a LZSA buffer with format 2. +<tag/Notes/<itemize> +<item>Use <tt/lzsa -f 2 -r input.bin output.lzsa2/ to compress your input. +<item>The project and compressor can be found at <url url="https://github.com/emmanuel-marty/lzsa"> +<item>LZSA2 is the second fastest decompressor shipped in cc65 runtime, but data is less +compressed than with ZX02. +</itemize> +<tag/Availability/cc65 +<tag/Example/None. +</descrip> +</quote> + + +<sect1>decompress_zx02<label id="decompress_zx02"><p> + +<quote> +<descrip> +<tag/Function/Uncompress a ZX02 buffer. +<tag/Header/<tt/<ref id="zx02.h" name="zx02.h">/ +<tag/Declaration/<tt/void decompress_zx02 (const unsigned char* src, unsigned char* const dst);/ +<tag/Description/<tt/decompress_zx02/ uncompresses a ZX02 buffer with format 2. +<tag/Notes/<itemize> +<item>Use <tt/zx02 input.bin output.zx02/ to compress your input. +<item>The project and compressor can be found at <url url="https://github.com/dmsc/zx02"> +<item>ZX02 is the slowest decompressor shipped with cc65 runtime, but is also the +smallest and has the best compression ratio. </itemize> <tag/Availability/cc65 <tag/Example/None. diff --git a/include/lzsa.h b/include/lzsa.h new file mode 100644 index 000000000..9b0eb82e5 --- /dev/null +++ b/include/lzsa.h @@ -0,0 +1,56 @@ +/*****************************************************************************/ +/* */ +/* lzsa.h */ +/* */ +/* Decompression routine for the 'lzsa' format */ +/* */ +/* */ +/* */ +/* (C) 2022 John Brandwood */ +/* */ +/* */ +/* Boost license: */ +/* Distributed under the Boost Software License, Version 1.0. */ +/* Boost Software License - Version 1.0 - August 17th, 2003 */ +/* */ +/* Permission is hereby granted, free of charge, to any person or */ +/* organization */ +/* obtaining a copy of the software and accompanying documentation covered by*/ +/* this license (the "Software") to use, reproduce, display, distribute, */ +/* execute, and transmit the Software, and to prepare derivative works of the*/ +/* Software, and to permit third-parties to whom the Software is furnished to*/ +/* do so, all subject to the following: */ +/* */ +/* The copyright notices in the Software and this entire statement, including*/ +/* the above license grant, this restriction and the following disclaimer, */ +/* must be included in all copies of the Software, in whole or in part, and */ +/* all derivative works of the Software, unless such copies or derivative */ +/* works are solely in the form of machine-executable object code generated */ +/* by a source language processor. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*/ +/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */ +/* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT */ +/* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE */ +/* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR */ +/* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE */ +/* USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*****************************************************************************/ + + + +#ifndef _LZSA_H +#define _LZSA_H + +void __fastcall__ decompress_lzsa1 (const unsigned char* src, unsigned char* const dst); +/* Decompresses the source buffer into the destination buffer. +** compress with lzsa -r -f 1 input.bin output.lzsa1 + */ + +void __fastcall__ decompress_lzsa2 (const unsigned char* src, unsigned char* const dst); +/* Decompresses the source buffer into the destination buffer. +** compress with lzsa -r -f 2 input.bin output.lzsa2 + */ + +/* end of lzsa.h */ +#endif diff --git a/include/zx02.h b/include/zx02.h new file mode 100644 index 000000000..b3e711d56 --- /dev/null +++ b/include/zx02.h @@ -0,0 +1,44 @@ +/*****************************************************************************/ +/* */ +/* zx02.h */ +/* */ +/* Decompression routine for the 'zx02' format */ +/* */ +/* */ +/* */ +/* (C) 2022 DMSC */ +/* */ +/* */ +/* MIT license: */ +/* Permission is hereby granted, free of charge, to any person obtaining a */ +/* copy of this software and associated documentation files (the “Software”),*/ +/* to deal in the Software without restriction, including without limitation */ +/* the rights to use, copy, modify, merge, publish, distribute, sublicense, */ +/* and/or sell copies of the Software, and to permit persons to whom the */ +/* Software is furnished to do so, subject to the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be included */ +/* in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS */ +/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN */ +/* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, */ +/* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR */ +/* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE */ +/* USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*****************************************************************************/ + + + +#ifndef _ZX02_H +#define _ZX02_H + +void __fastcall__ decompress_zx02 (const unsigned char* src, unsigned char* const dst); +/* Decompresses the source buffer into the destination buffer. +** compress with zx02 input.bin output.zx02 + */ + + +/* end of zx02.h */ +#endif diff --git a/libsrc/common/lzsa1.s b/libsrc/common/lzsa1.s new file mode 100644 index 000000000..bbff728f7 --- /dev/null +++ b/libsrc/common/lzsa1.s @@ -0,0 +1,207 @@ +; void __fastcall__ decompress_lzsa1(const void *src, void *dest) +; +; NMOS 6502 decompressor for data stored in Emmanuel Marty's LZSA1 format. +; +; Compress with: +; lzsa -r -f 1 input.bin output.lzsa1 +; +; Copyright John Brandwood 2021. +; +; Distributed under the Boost Software License, Version 1.0. +; Boost Software License - Version 1.0 - August 17th, 2003 +; +; Permission is hereby granted, free of charge, to any person or organization +; obtaining a copy of the software and accompanying documentation covered by +; this license (the "Software") to use, reproduce, display, distribute, +; execute, and transmit the Software, and to prepare derivative works of the +; Software, and to permit third-parties to whom the Software is furnished to +; do so, all subject to the following: +; +; The copyright notices in the Software and this entire statement, including +; the above license grant, this restriction and the following disclaimer, +; must be included in all copies of the Software, in whole or in part, and +; all derivative works of the Software, unless such copies or derivative +; works are solely in the form of machine-executable object code generated by +; a source language processor. +; +; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +; FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +; SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +; FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +; DEALINGS IN THE SOFTWARE. + + .export _decompress_lzsa1 + + .import popax + .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3 + +lzsa_cmdbuf = tmp1 ; 1 byte. +lzsa_winptr = ptr1 ; 1 word. +lzsa_srcptr = ptr2 ; 1 word. +lzsa_dstptr = ptr3 ; 1 word. + +lzsa_offset = lzsa_winptr + +.proc _decompress_lzsa1 + sta lzsa_dstptr + stx lzsa_dstptr+1 + jsr popax + sta lzsa_srcptr + stx lzsa_srcptr+1 + +lzsa1_unpack: ldy #0 ; Initialize source index. + ldx #0 ; Initialize hi-byte of length. + + ; + ; Copy bytes from compressed source data. + ; + ; N.B. X=0 is expected and guaranteed when we get here. + ; + +cp_length: lda (lzsa_srcptr),y + inc lzsa_srcptr + bne cp_skip0 + inc lzsa_srcptr+1 + +cp_skip0: sta lzsa_cmdbuf ; Preserve this for later. + and #$70 ; Extract literal length. + lsr ; Set CC before ... + beq lz_offset ; Skip directly to match? + + lsr ; Get 3-bit literal length. + lsr + lsr + cmp #$07 ; Extended length? + bcc cp_got_len + + jsr get_length ; X=0, CS from CMP, returns CC. + stx cp_npages+1 ; Hi-byte of length. + +cp_got_len: tax ; Lo-byte of length. + +cp_byte: lda (lzsa_srcptr),y ; CC throughout the execution of + sta (lzsa_dstptr),y ; of this .cp_page loop. + inc lzsa_srcptr + bne cp_skip1 + inc lzsa_srcptr+1 +cp_skip1: inc lzsa_dstptr + bne cp_skip2 + inc lzsa_dstptr+1 +cp_skip2: dex + bne cp_byte +cp_npages: lda #0 ; Any full pages left to copy? + beq lz_offset + + dec cp_npages+1 ; Unlikely, so can be slow. + bcc cp_byte ; Always true! + + ; + ; Copy bytes from decompressed window. + ; + ; Longer but faster. + ; + ; N.B. X=0 is expected and guaranteed when we get here. + ; + +lz_offset: lda (lzsa_srcptr),y ; Get offset-lo. + inc lzsa_srcptr + bne offset_lo + inc lzsa_srcptr+1 + +offset_lo: sta lzsa_offset + + lda #$FF ; Get offset-hi. + bit lzsa_cmdbuf + bpl offset_hi + + lda (lzsa_srcptr),y + inc lzsa_srcptr + bne offset_hi + inc lzsa_srcptr+1 + +offset_hi: sta lzsa_offset+1 + +lz_length: lda lzsa_cmdbuf ; X=0 from previous loop. + and #$0F + adc #$03 ; Always CC from .cp_page loop. + cmp #$12 ; Extended length? + bcc got_lz_len + + jsr get_length ; X=0, CS from CMP, returns CC. + +got_lz_len: inx ; Hi-byte of length+256. + + eor #$FF ; Negate the lo-byte of length + tay + eor #$FF + +get_lz_dst: adc lzsa_dstptr ; Calc address of partial page. + sta lzsa_dstptr ; Always CC from previous CMP. + iny + bcs get_lz_win + beq get_lz_win ; Is lo-byte of length zero? + dec lzsa_dstptr+1 + +get_lz_win: clc ; Calc address of match. + adc lzsa_offset ; N.B. Offset is negative! + sta lzsa_winptr + lda lzsa_dstptr+1 + adc lzsa_offset+1 + sta lzsa_winptr+1 + +lz_byte: lda (lzsa_winptr),y + sta (lzsa_dstptr),y + iny + bne lz_byte + inc lzsa_dstptr+1 + dex ; Any full pages left to copy? + bne lz_more + + jmp cp_length ; Loop around to the beginning. + +lz_more: inc lzsa_winptr+1 ; Unlikely, so can be slow. + bne lz_byte ; Always true! + + ; + ; Get 16-bit length in X:A register pair, return with CC. + ; + ; N.B. X=0 is expected and guaranteed when we get here. + ; + +get_length: clc ; Add on the next byte to get + adc (lzsa_srcptr),y ; the length. + inc lzsa_srcptr + bne skip_inc + inc lzsa_srcptr+1 + +skip_inc: bcc got_length ; No overflow means done. + clc ; MUST return CC! + tax ; Preserve overflow value. + +extra_byte: jsr get_byte ; So rare, this can be slow! + pha + txa ; Overflow to 256 or 257? + beq extra_word + +check_length: pla ; Length-lo. + bne got_length ; Check for zero. + dex ; Do one less page loop if so. +got_length: rts + +extra_word: jsr get_byte ; So rare, this can be slow! + tax + bne check_length ; Length-hi == 0 at EOF. + +finished: pla ; Length-lo. + pla ; Decompression completed, pop + pla ; return address. + rts + +get_byte: lda (lzsa_srcptr),y ; Subroutine version for when + inc lzsa_srcptr ; inlining isn't advantageous. + bne got_byte + inc lzsa_srcptr+1 ; Inc & test for bank overflow. +got_byte: rts +.endproc diff --git a/libsrc/common/lzsa2.s b/libsrc/common/lzsa2.s new file mode 100644 index 000000000..e851970e1 --- /dev/null +++ b/libsrc/common/lzsa2.s @@ -0,0 +1,308 @@ +; void __fastcall__ decompress_lzsa2(const void *src, void *dest) +; +; NMOS 6502 decompressor for data stored in Emmanuel Marty's LZSA2 format. +; +; Compress with: +; lzsa -r -f 2 input.bin output.lzsa2 +; +; Copyright John Brandwood 2021. +; +; Distributed under the Boost Software License, Version 1.0. +; Boost Software License - Version 1.0 - August 17th, 2003 +; +; Permission is hereby granted, free of charge, to any person or organization +; obtaining a copy of the software and accompanying documentation covered by +; this license (the "Software") to use, reproduce, display, distribute, +; execute, and transmit the Software, and to prepare derivative works of the +; Software, and to permit third-parties to whom the Software is furnished to +; do so, all subject to the following: +; +; The copyright notices in the Software and this entire statement, including +; the above license grant, this restriction and the following disclaimer, +; must be included in all copies of the Software, in whole or in part, and +; all derivative works of the Software, unless such copies or derivative +; works are solely in the form of machine-executable object code generated by +; a source language processor. +; +; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +; FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +; SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +; FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +; DEALINGS IN THE SOFTWARE. + + .export _decompress_lzsa2 + + .import popax + .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3 + +lzsa_length = lzsa_winptr ; 1 word. + +lzsa_cmdbuf = tmp1 ; 1 byte. +lzsa_nibflg = tmp2 ; 1 byte. +lzsa_nibble = tmp3 ; 1 byte. +lzsa_offset = ptr1 ; 1 word. +lzsa_winptr = ptr2 ; 1 word. +lzsa_srcptr = ptr3 ; 1 word. +lzsa_dstptr = ptr4 ; 1 word. + +.proc _decompress_lzsa2 + sta lzsa_dstptr + stx lzsa_dstptr+1 + jsr popax + sta lzsa_srcptr + stx lzsa_srcptr+1 + +lzsa2_unpack: + ldx #$00 ; Hi-byte of length or offset. + ldy #$00 ; Initialize source index. + sty lzsa_nibflg ; Initialize nibble buffer. + + ; + ; Copy bytes from compressed source data. + ; + ; N.B. X=0 is expected and guaranteed when we get here. + ; + +cp_length: + lda (lzsa_srcptr),y + inc lzsa_srcptr + bne cp_skip0 + inc lzsa_srcptr+1 + +cp_skip0: + sta lzsa_cmdbuf ; Preserve this for later. + and #$18 ; Extract literal length. + beq lz_offset ; Skip directly to match? + + lsr ; Get 2-bit literal length. + lsr + lsr + cmp #$03 ; Extended length? + bcc cp_got_len + + jsr get_length ; X=0 for literals, returns CC. + stx cp_npages+1 ; Hi-byte of length. + +cp_got_len: + tax ; Lo-byte of length. + +cp_byte: + lda (lzsa_srcptr),y ; CC throughout the execution of + sta (lzsa_dstptr),y ; of this .cp_page loop. + inc lzsa_srcptr + bne cp_skip1 + inc lzsa_srcptr+1 +cp_skip1: + inc lzsa_dstptr + bne cp_skip2 + inc lzsa_dstptr+1 +cp_skip2: + dex + bne cp_byte +cp_npages: + lda #0 ; Any full pages left to copy? + beq lz_offset + + dec cp_npages+1 ; Unlikely, so can be slow + bcc cp_byte ; Always true! + + ; + ; Copy bytes from decompressed window. + ; + ; N.B. X=0 is expected and guaranteed when we get here. + ; + ; xyz + ; =========================== + ; 00z 5-bit offset + ; 01z 9-bit offset + ; 10z 13-bit offset + ; 110 16-bit offset + ; 111 repeat offset + ; + +lz_offset: + lda lzsa_cmdbuf + asl + bcs get_13_16_rep + +get_5_9_bits: + dex ; X=$FF for a 5-bit offset. + asl + bcs get_9_bits ; Fall through if 5-bit. + +get_13_bits: + asl ; Both 5-bit and 13-bit read + php ; a nibble. + jsr get_nibble + plp + rol ; Shift into position, clr C. + eor #$E1 + cpx #$00 ; X=$FF for a 5-bit offset. + bne set_offset + sbc #2 ; 13-bit offset from $FE00. + bne set_hi_8 ; Always NZ from previous SBC. + +get_9_bits: + asl ; X=$FF if CC, X=$FE if CS. + bcc get_lo_8 + dex + bcs get_lo_8 ; Always CS from previous BCC. + +get_13_16_rep: + asl + bcc get_13_bits ; Shares code with 5-bit path. + +get_16_rep: + bmi lz_length ; Repeat previous offset. + +get_16_bits: + jsr get_byte ; Get hi-byte of offset. + +set_hi_8: + tax + +get_lo_8: + lda (lzsa_srcptr),y ; Get lo-byte of offset. + inc lzsa_srcptr + bne set_offset + inc lzsa_srcptr+1 + +set_offset: + sta lzsa_offset ; Save new offset. + stx lzsa_offset+1 + +lz_length: + ldx #1 ; Hi-byte of length+256. + + lda lzsa_cmdbuf + and #$07 + clc + adc #$02 + cmp #$09 ; Extended length? + bcc got_lz_len + + jsr get_length ; X=1 for match, returns CC. + inx ; Hi-byte of length+256. + +got_lz_len: + eor #$FF ; Negate the lo-byte of length. + tay + eor #$FF + +get_lz_dst: + adc lzsa_dstptr ; Calc address of partial page. + sta lzsa_dstptr ; Always CC from previous CMP. + iny + bcs get_lz_win + beq get_lz_win ; Is lo-byte of length zero? + dec lzsa_dstptr+1 + +get_lz_win: + clc ; Calc address of match. + adc lzsa_offset ; N.B. Offset is negative! + sta lzsa_winptr + lda lzsa_dstptr+1 + adc lzsa_offset+1 + sta lzsa_winptr+1 + +lz_byte: + lda (lzsa_winptr),y + sta (lzsa_dstptr),y + iny + bne lz_byte + inc lzsa_dstptr+1 + dex ; Any full pages left to copy? + bne lz_more + + jmp cp_length ; Loop around to the beginning. + +lz_more: + inc lzsa_winptr+1 ; Unlikely, so can be slow. + bne lz_byte ; Always true! + + ; + ; Lookup tables to differentiate literal and match lengths. + ; + +nibl_len_tbl: + .byte 3 ; 0+3 (for literal). + .byte 9 ; 2+7 (for match). + +byte_len_tbl: + .byte 18 - 1 ; 0+3+15 - CS (for literal). + .byte 24 - 1 ; 2+7+15 - CS (for match). + + ; + ; Get 16-bit length in X:A register pair, return with CC. + ; + +get_length: + jsr get_nibble + cmp #$0F ; Extended length? + bcs byte_length + adc nibl_len_tbl,x ; Always CC from previous CMP. + +got_length: + ldx #$00 ; Set hi-byte of 4 & 8 bit + rts ; lengths. + +byte_length: + jsr get_byte ; So rare, this can be slow! + adc byte_len_tbl,x ; Always CS from previous CMP + bcc got_length + beq finished + +word_length: + clc ; MUST return CC! + jsr get_byte ; So rare, this can be slow! + pha + jsr get_byte ; So rare, this can be slow! + tax + pla + bne got_word ; Check for zero lo-byte. + dex ; Do one less page loop if so. +got_word: + rts + +get_byte: + lda (lzsa_srcptr),y ; Subroutine version for when + inc lzsa_srcptr ; inlining isn't advantageous. + bne got_byte + inc lzsa_srcptr+1 +got_byte: + rts + +finished: + pla ; Decompression completed, pop + pla ; return address. + rts + + ; + ; Get a nibble value from compressed data in A. + ; + +get_nibble: + lsr lzsa_nibflg ; Is there a nibble waiting? + lda lzsa_nibble ; Extract the lo-nibble. + bcs got_nibble + + inc lzsa_nibflg ; Reset the flag. + + lda (lzsa_srcptr),y + inc lzsa_srcptr + bne set_nibble + inc lzsa_srcptr+1 + +set_nibble: + sta lzsa_nibble ; Preserve for next time. + lsr ; Extract the hi-nibble. + lsr + lsr + lsr + +got_nibble: + and #$0F + rts +.endproc diff --git a/libsrc/common/zx02.s b/libsrc/common/zx02.s new file mode 100644 index 000000000..02256a768 --- /dev/null +++ b/libsrc/common/zx02.s @@ -0,0 +1,148 @@ +; void __fastcall__ decompress_zx02(const void *src, void *dest) +; +; De-compressor for ZX02 files +; +; Compress with: +; zx02 input.bin output.zx0 +; +; (c) 2022 DMSC +; Code under MIT license, see LICENSE file. + + .export _decompress_zx02 + + .import popax + .importzp ptr1, ptr2, ptr3, tmp1, tmp2 + +offset_hi = tmp1 +ZX0_src = ptr1 +ZX0_dst = ptr2 +bitr = tmp2 +pntr = ptr3 + +.proc _decompress_zx02 + sta ZX0_dst + stx ZX0_dst+1 + + jsr popax + sta ZX0_src + stx ZX0_src+1 + + ; Init values + lda #$80 + sta bitr + ldy #$FF + sty pntr + iny + sty offset_hi ; Y = 0 at end of init + +; Decode literal: Copy next N bytes from compressed file +; Elias(length) byte[1] byte[2] ... byte[N] +decode_literal: + ldx #$01 + jsr get_elias + +cop0: + lda (ZX0_src), y + inc ZX0_src + bne :+ + inc ZX0_src+1 + +: sta (ZX0_dst),y + inc ZX0_dst + bne :+ + inc ZX0_dst+1 + +: dex + bne cop0 + + asl bitr + bcs dzx0s_new_offset + + ; Copy from last offset (repeat N bytes from last offset) + ; Elias(length) + inx + jsr get_elias + +dzx0s_copy: + lda ZX0_dst+1 + sbc offset_hi ; C=0 from get_elias + sta pntr+1 + +cop1: + ldy ZX0_dst + lda (pntr), y + ldy #0 + sta (ZX0_dst),y + inc ZX0_dst + bne :+ + inc ZX0_dst+1 + inc pntr+1 +: dex + bne cop1 + + asl bitr + bcc decode_literal + +; Copy from new offset (repeat N bytes from new offset) +; Elias(MSB(offset)) LSB(offset) Elias(length-1) +dzx0s_new_offset: + ; Read elias code for high part of offset + inx + jsr get_elias + beq exit ; Read a 0, signals the end + + ; Decrease and divide by 2 + dex + txa + lsr + sta offset_hi + + ; Get low part of offset, a literal 7 bits + lda (ZX0_src), y + inc ZX0_src + bne :+ + inc ZX0_src+1 + +: ; Divide by 2 + ror + eor #$ff + sta pntr + + ; And get the copy length. + ; Start elias reading with the bit already in carry: + ldx #1 + jsr elias_skip1 + + inx + bcc dzx0s_copy + +; Read an elias-gamma interlaced code. +elias_get: + ; Read next data bit to result + asl bitr + rol + tax + +get_elias: + ; Get one bit + asl bitr + bne elias_skip1 + + ; Read new bit from stream + lda (ZX0_src), y + inc ZX0_src + bne :+ + inc ZX0_src+1 + +: ; sec ; not needed, C=1 guaranteed from last bit + rol + sta bitr + +elias_skip1: + txa + bcs elias_get + + ; Got ending bit, stop reading +exit: + rts +.endproc diff --git a/test/val/lzsa1.c b/test/val/lzsa1.c new file mode 100644 index 000000000..9e627295a --- /dev/null +++ b/test/val/lzsa1.c @@ -0,0 +1,478 @@ +/* + !!DESCRIPTION!! lzsa1 decompression + !!ORIGIN!! cc65 regression tests + !!LICENCE!! BSD 2-clause + !!AUTHOR!! Colin Leroy-Mira +*/ + +#include <zlib.h> +#include <stdio.h> +#include <lzsa.h> + +/* The sample data is the original lz4.h, compressed with: + * lzsa -r -f 1 lz4.h lz4.lzsa1 + * + * We reused lz4.h from the LZ4 test to have a matching adler32 sum. + */ +static const unsigned char compressed[] = { + 0x71, 0x22, 0x2f, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x4c, 0x5a, 0x34, 0x20, 0x2d, 0x20, 0x46, 0x61, + 0x73, 0x74, 0x20, 0x4c, 0x5a, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x20, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0xd9, 0x71, 0x04, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x20, 0x46, 0x69, 0x6c, 0x65, 0xf1, 0x70, 0x16, 0x43, 0x6f, 0x70, 0x79, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x32, + 0x30, 0x31, 0x35, 0x2c, 0x20, 0x59, 0x61, 0x6e, 0x6e, 0xe2, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2e, + 0x0a, 0xd6, 0x73, 0x2a, 0x42, 0x53, 0x44, 0x20, 0x32, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, + 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x6f, 0x72, 0x67, 0x2f, 0x6c, 0xdd, 0x64, 0x73, 0x2f, 0x62, 0x73, 0x64, 0x2d, 0xf3, 0x52, 0x2e, + 0x70, 0x68, 0x70, 0x29, 0xb2, 0x72, 0x04, 0x52, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x5d, 0x31, 0x6e, 0x64, 0x20, 0xa8, 0x33, 0x69, 0x6e, 0x20, 0xbd, 0x02, 0xee, 0x70, + 0x08, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x2c, 0x20, 0x77, + 0x3d, 0x32, 0x20, 0x6f, 0x72, 0xf8, 0x31, 0x6f, 0x75, 0x74, 0xba, 0x71, 0x01, 0x6d, 0x6f, 0x64, + 0x69, 0x66, 0x69, 0x63, 0x61, 0xbc, 0x70, 0x0f, 0x2c, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0xf7, 0x40, + 0x74, 0x68, 0x61, 0x74, 0xfb, 0x30, 0x65, 0x20, 0x66, 0x32, 0xd0, 0x6f, 0x77, 0x69, 0x6e, 0x67, + 0xe2, 0xfe, 0x31, 0x6e, 0x64, 0x69, 0xcb, 0x11, 0x73, 0xcb, 0x02, 0xb6, 0x30, 0x65, 0x74, 0x3a, + 0x67, 0x03, 0xff, 0x1c, 0x2a, 0x61, 0x44, 0x73, 0x20, 0x6f, 0x66, 0x68, 0x00, 0xc5, 0xd0, 0x64, + 0x65, 0x20, 0x6d, 0x75, 0x9a, 0xfe, 0x62, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 0xa6, 0x40, 0x61, + 0x62, 0x6f, 0x76, 0xe5, 0x84, 0xb4, 0xfe, 0x02, 0x65, 0x30, 0x6e, 0x6f, 0x74, 0x0c, 0x10, 0x2c, + 0xe1, 0x40, 0x69, 0x73, 0x20, 0x6c, 0xb3, 0x00, 0xbc, 0x0a, 0x88, 0x2c, 0x6e, 0x64, 0x6b, 0x00, + 0x8e, 0x7f, 0x01, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x77, 0x08, 0xa9, 0x69, 0x6e, + 0xea, 0xfe, 0x05, 0x77, 0x00, 0x14, 0x46, 0x64, 0x75, 0x63, 0x65, 0x74, 0x01, 0x2d, 0x07, 0x71, + 0x0f, 0x74, 0x2b, 0x01, 0xb6, 0x04, 0x1a, 0xf5, 0x02, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x61, 0x4d, 0xfe, 0x50, 0x2f, 0x6f, 0x72, 0x20, 0x6f, 0xe6, 0xf6, 0x04, 0x72, 0x20, 0x6d, + 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x89, 0xfe, 0x83, 0x51, 0xfe, 0x22, 0x74, 0x68, + 0x75, 0x09, 0x3c, 0x83, 0xb2, 0xfd, 0x71, 0x3c, 0x54, 0x48, 0x49, 0x53, 0x20, 0x53, 0x4f, 0x46, + 0x54, 0x57, 0x41, 0x52, 0x45, 0x20, 0x49, 0x53, 0x20, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x44, 0x45, + 0x44, 0x20, 0x42, 0x59, 0x20, 0x54, 0x48, 0x45, 0x20, 0x43, 0x4f, 0x50, 0x59, 0x52, 0x49, 0x47, + 0x48, 0x54, 0x20, 0x48, 0x4f, 0x4c, 0x44, 0x45, 0x52, 0x53, 0x20, 0x41, 0x4e, 0x44, 0x20, 0x43, + 0x4f, 0x4e, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x4f, 0x52, 0x53, 0xb9, 0x30, 0x22, 0x41, 0x53, + 0xc3, 0x12, 0x22, 0xe4, 0x70, 0x0d, 0x41, 0x4e, 0x59, 0x20, 0x45, 0x58, 0x50, 0x52, 0x45, 0x53, + 0x53, 0x20, 0x4f, 0x52, 0x20, 0x49, 0x4d, 0x50, 0x4c, 0x49, 0xb0, 0x00, 0x9f, 0x70, 0x0d, 0x52, + 0x41, 0x4e, 0x54, 0x49, 0x45, 0x53, 0x2c, 0x20, 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x44, 0x49, 0x4e, + 0x47, 0x2c, 0x20, 0xbc, 0xc2, 0x20, 0x4e, 0x4f, 0x54, 0xc6, 0xfc, 0x40, 0x49, 0x4d, 0x49, 0x54, + 0xd6, 0x32, 0x54, 0x4f, 0x2c, 0x85, 0x0e, 0xc6, 0x00, 0xb0, 0x72, 0x0a, 0x46, 0x20, 0x4d, 0x45, + 0x52, 0x43, 0x48, 0x41, 0x4e, 0x54, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x8d, 0x41, 0x46, + 0x49, 0x54, 0x4e, 0x91, 0x31, 0x46, 0x4f, 0x52, 0xb7, 0x71, 0x0e, 0x41, 0x20, 0x50, 0x41, 0x52, + 0x54, 0x49, 0x43, 0x55, 0x4c, 0x41, 0x52, 0x20, 0x50, 0x55, 0x52, 0x50, 0x4f, 0x53, 0x45, 0x20, + 0x20, 0x70, 0x04, 0x44, 0x49, 0x53, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x45, 0x44, 0x2e, 0x7c, 0x00, + 0x88, 0x7a, 0x05, 0x20, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x20, 0x53, 0x48, 0x41, 0x4c, 0x4c, 0x11, + 0x02, 0x6f, 0x50, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x3c, 0x0a, 0x11, 0x30, 0x20, 0x42, 0x45, 0x56, + 0x41, 0x41, 0x42, 0x4c, 0x45, 0x91, 0x02, 0x12, 0x61, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x29, + 0x07, 0xf6, 0x40, 0x43, 0x49, 0x44, 0x45, 0x5b, 0x21, 0x4c, 0x2c, 0xb7, 0x50, 0x53, 0x50, 0x45, + 0x43, 0x49, 0xf4, 0x60, 0x20, 0x45, 0x58, 0x45, 0x4d, 0x50, 0x6a, 0x24, 0x59, 0x2c, 0xa9, 0x40, + 0x53, 0x45, 0x51, 0x55, 0xd8, 0x00, 0xe3, 0x60, 0x20, 0x44, 0x41, 0x4d, 0x41, 0x47, 0x1c, 0x9f, + 0x28, 0xe2, 0xfe, 0x0f, 0x81, 0x5b, 0xfe, 0x51, 0x43, 0x55, 0x52, 0x45, 0x4d, 0x44, 0xf2, 0x0b, + 0x4f, 0x46, 0x20, 0x53, 0x55, 0x42, 0x53, 0x54, 0x49, 0x54, 0x55, 0x54, 0x45, 0x20, 0x47, 0x4f, + 0x4f, 0x44, 0x89, 0xfe, 0xf2, 0x06, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x53, 0x3b, 0x20, + 0x4c, 0x4f, 0x53, 0xc7, 0xfe, 0x32, 0x55, 0x53, 0x45, 0x73, 0x41, 0x44, 0x41, 0x54, 0x41, 0x81, + 0x01, 0xba, 0x51, 0x46, 0x49, 0x54, 0x53, 0x3b, 0xf4, 0xc2, 0x42, 0x55, 0x53, 0x49, 0xbd, 0xfe, + 0x70, 0x0d, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x52, 0x55, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x29, 0x20, + 0x48, 0x4f, 0x57, 0x45, 0x56, 0x45, 0x56, 0x10, 0x41, 0xc2, 0x92, 0x44, 0x94, 0xfe, 0x21, 0x4f, + 0x4e, 0x0c, 0x83, 0xc4, 0xfd, 0x41, 0x45, 0x4f, 0x52, 0x59, 0xa5, 0xa4, 0x4c, 0x49, 0x72, 0xfe, + 0x50, 0x2c, 0x20, 0x57, 0x48, 0x45, 0xe8, 0x10, 0x52, 0xb8, 0x83, 0xca, 0xfe, 0x91, 0x41, 0xf1, + 0xfe, 0x69, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, 0xd9, 0x20, 0x4f, 0x52, 0x37, 0x11, 0x52, 0x27, + 0x08, 0x10, 0x71, 0x04, 0x20, 0x4e, 0x45, 0x47, 0x4c, 0x49, 0x47, 0x45, 0x4e, 0x43, 0x45, 0xdf, + 0x11, 0x4f, 0xb7, 0xd0, 0x57, 0x49, 0x53, 0x45, 0x29, 0x43, 0xfe, 0x21, 0x49, 0x53, 0xdf, 0x12, + 0x49, 0x83, 0x30, 0x20, 0x57, 0x41, 0x89, 0x11, 0x55, 0x04, 0x01, 0x7b, 0x01, 0x26, 0x82, 0x51, + 0xfe, 0x9b, 0x46, 0x31, 0xfd, 0x92, 0x2c, 0x22, 0xfe, 0x70, 0x01, 0x20, 0x49, 0x46, 0x20, 0x41, + 0x44, 0x56, 0x49, 0x40, 0x05, 0xd0, 0x53, 0x50, 0x4f, 0x53, 0x53, 0x49, 0x76, 0x83, 0xc1, 0xfe, + 0xa4, 0x43, 0x48, 0x82, 0xfe, 0x83, 0xeb, 0xfc, 0xf1, 0x00, 0x59, 0x6f, 0x75, 0x20, 0x63, 0x61, + 0x6e, 0x65, 0xfc, 0xc3, 0x74, 0x61, 0x63, 0x74, 0x31, 0xfc, 0xe0, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x20, 0x3d, 0xfb, 0x11, 0x3a, 0xdd, 0x91, 0x2d, 0x18, 0xfa, 0x84, 0x74, 0xfb, 0x81, 0x07, 0xfc, + 0xd0, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0xf2, 0xfb, 0xa1, 0x3a, 0x20, 0x76, 0xfa, 0x77, 0x14, 0x73, + 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x79, + 0x61, 0x6e, 0x34, 0x39, 0x37, 0x33, 0x2f, 0x6c, 0x7a, 0x34, 0xc3, 0xe1, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0xc0, 0xfb, 0x29, 0x75, 0x6d, 0xc8, 0x72, 0x05, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0xc1, 0x02, 0xde, 0x32, 0x2f, 0x23, 0x21, 0xf8, 0x01, 0xbc, + 0x71, 0x20, 0x63, 0x0a, 0x2a, 0x2f, 0x0a, 0x23, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x20, 0x6f, + 0x6e, 0x63, 0x65, 0x0a, 0x0a, 0x23, 0x69, 0x66, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, + 0x20, 0x28, 0x5f, 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0xfc, 0xf1, 0x10, 0x29, 0x0a, 0x65, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x20, 0x22, 0x43, 0x22, 0x20, 0x7b, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, + 0x66, 0x0a, 0x0a, 0x55, 0xf9, 0x20, 0x2a, 0x20, 0xb5, 0xa5, 0x2e, 0x68, 0xd6, 0xfb, 0xfa, 0x00, + 0x73, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0xf9, 0xc2, 0x66, 0x75, 0x6e, 0x63, 0x65, 0xfb, + 0x92, 0x2c, 0x64, 0xfb, 0x50, 0x67, 0x69, 0x76, 0x65, 0x73, 0xeb, 0xf2, 0x02, 0x6c, 0x6c, 0x20, + 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0xde, 0xfe, 0x61, 0x72, 0x6f, 0x6c, 0x20, 0x74, 0x6f, 0xb9, + 0xc3, 0x67, 0x72, 0x61, 0x6d, 0xc9, 0xfa, 0xe0, 0x2a, 0x20, 0x49, 0x66, 0x20, 0x79, 0xb9, 0xfe, + 0x41, 0x6e, 0x65, 0x65, 0x64, 0xe2, 0xf1, 0x00, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0xa6, + 0xf9, 0x00, 0x71, 0x30, 0x2d, 0x6f, 0x70, 0xf2, 0x36, 0x62, 0x6c, 0x65, 0x92, 0x00, 0xda, 0x60, + 0x64, 0x61, 0x74, 0x61, 0x20, 0x28, 0xf3, 0x20, 0x70, 0x65, 0x8b, 0xa2, 0x6e, 0x67, 0xdb, 0xfe, + 0x10, 0x66, 0xad, 0x21, 0x65, 0x20, 0xed, 0x86, 0x9f, 0xf9, 0x20, 0x29, 0x2c, 0xa0, 0x01, 0x70, + 0x82, 0x5c, 0xfe, 0xa3, 0x6c, 0x65, 0x60, 0xfe, 0xc1, 0x6c, 0x69, 0x62, 0x72, 0x71, 0xfa, 0x10, + 0x68, 0xe7, 0x10, 0x6c, 0x99, 0xf1, 0x0e, 0x74, 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x20, 0x6d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x2c, 0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x24, 0xf9, 0x01, 0x0a, + 0x02, 0xaa, 0x20, 0x2e, 0x68, 0x73, 0xe1, 0x73, 0x74, 0x65, 0x61, 0x64, 0x2e, 0xb0, 0xfe, 0x3f, + 0x0a, 0x2f, 0x2a, 0xff, 0x13, 0xf1, 0x00, 0x0a, 0x2a, 0x20, 0x20, 0x56, 0x65, 0x72, 0xe0, 0xfe, + 0x1f, 0x0a, 0xce, 0x14, 0xb3, 0x2f, 0x0a, 0x23, 0x65, 0xfe, 0x01, 0x2e, 0xd0, 0x5f, 0x56, 0x45, + 0x52, 0x53, 0xa4, 0xfc, 0xe1, 0x5f, 0x4d, 0x41, 0x4a, 0x4f, 0x52, 0xa3, 0xf9, 0x11, 0x31, 0xfb, + 0xa1, 0x2f, 0x2a, 0xf7, 0xfd, 0x60, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x04, 0x83, 0xd9, 0xfe, + 0xa1, 0x66, 0x61, 0x17, 0xf9, 0x00, 0x2e, 0x5f, 0x67, 0x65, 0x73, 0x20, 0x20, 0xb8, 0x06, 0x23, + 0x49, 0x4e, 0xb8, 0x18, 0x37, 0xb8, 0x75, 0x02, 0x6e, 0x65, 0x77, 0x20, 0x28, 0x6e, 0x6f, 0x6e, + 0x2d, 0xaf, 0x19, 0x29, 0xae, 0xe0, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x8b, 0xf9, 0x2f, 0x65, + 0x73, 0xaa, 0x06, 0x7b, 0x00, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x62, 0x20, 0x74, 0x77, + 0xb3, 0xa0, 0x73, 0x2c, 0x03, 0xfe, 0x60, 0x67, 0x2d, 0x66, 0x69, 0x78, 0x65, 0xf5, 0x00, 0xea, + 0xf1, 0x00, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6e, 0xf9, 0x0f, 0xb2, 0x06, 0xc0, 0x4e, + 0x55, 0x4d, 0x42, 0xec, 0xfb, 0x1f, 0x28, 0x00, 0x00, 0x41, 0x2a, 0x31, 0x30, 0x30, 0xfc, 0x2f, + 0x20, 0x2b, 0x2b, 0x01, 0x06, 0xe7, 0x0e, 0x68, 0x20, 0x29, 0x0a, 0x31, 0x02, 0xe7, 0x93, 0x76, + 0x75, 0xfe, 0xff, 0x07, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x28, 0x76, 0x6f, 0x69, 0x64, + 0x29, 0x3b, 0x33, 0xfe, 0x1b, 0xb1, 0x54, 0x75, 0x6e, 0x8e, 0xfe, 0xa1, 0x70, 0x61, 0xeb, 0xfd, + 0xbf, 0x74, 0x65, 0x72, 0x2a, 0xfe, 0x16, 0x83, 0xbb, 0xfc, 0x02, 0x7b, 0xb0, 0x4d, 0x45, 0x4d, + 0xf6, 0xfa, 0xb0, 0x5f, 0x55, 0x53, 0xbd, 0xfb, 0x21, 0x20, 0x3a, 0xea, 0x92, 0x4d, 0x88, 0xfd, + 0xe2, 0x20, 0x75, 0x73, 0x61, 0x67, 0x65, 0xdd, 0xf7, 0x71, 0x25, 0x75, 0x6c, 0x61, 0x20, 0x3a, + 0x20, 0x4e, 0x2d, 0x3e, 0x32, 0x5e, 0x4e, 0x20, 0x42, 0x79, 0x74, 0x65, 0x73, 0x20, 0x28, 0x65, + 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x20, 0x3a, 0x20, 0x31, 0x30, 0x20, 0x2d, 0x3e, 0x20, + 0x31, 0x4b, 0x42, 0x3b, 0x20, 0x31, 0x32, 0xf5, 0x40, 0x34, 0x4b, 0x42, 0x20, 0xf4, 0x11, 0x36, + 0xf4, 0x21, 0x36, 0x34, 0xe8, 0x13, 0x32, 0xdd, 0x10, 0x4d, 0xf5, 0xd2, 0x65, 0x74, 0x63, 0x2e, + 0x29, 0x9a, 0xfc, 0x61, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x40, 0x19, 0x6d, 0x8e, 0xa1, 0x69, + 0x6d, 0x2a, 0xfc, 0xaa, 0x65, 0x73, 0x32, 0xfc, 0x91, 0x72, 0xc1, 0xfc, 0x93, 0x0a, 0x33, 0xf7, + 0x4b, 0x75, 0x63, 0x65, 0x64, 0xcd, 0x34, 0x63, 0x61, 0x6e, 0xc9, 0x82, 0x90, 0xfc, 0xe0, 0x65, + 0x64, 0x2c, 0x20, 0x64, 0x75, 0x35, 0xf7, 0x10, 0x6f, 0xe6, 0xd0, 0x63, 0x68, 0x65, 0x20, 0x65, + 0x0f, 0xfc, 0x21, 0x63, 0x74, 0xc1, 0x70, 0x05, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, + 0x76, 0x61, 0x6c, 0x75, 0x95, 0x51, 0x73, 0x20, 0x31, 0x34, 0x2c, 0x1c, 0x00, 0x52, 0xa0, 0x4b, + 0x42, 0xe0, 0xf5, 0xe0, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6e, 0x16, 0xf7, 0xe1, 0x6c, 0x79, 0x20, + 0x66, 0x69, 0x74, 0xd3, 0xf6, 0x20, 0x74, 0x6f, 0x55, 0x73, 0x03, 0x74, 0x65, 0x6c, 0x20, 0x78, + 0x38, 0x36, 0x20, 0x4c, 0x31, 0xad, 0x99, 0x0a, 0xd1, 0xfd, 0x8e, 0xb9, 0xfe, 0xbf, 0x31, 0x34, + 0x0a, 0x39, 0xfe, 0x1b, 0xa1, 0x53, 0x69, 0xb4, 0xfe, 0xa5, 0x20, 0x46, 0x4d, 0xfb, 0x8f, 0x39, + 0xfe, 0x17, 0x86, 0xb5, 0xfd, 0x85, 0xd4, 0xfe, 0x23, 0x5f, 0x64, 0x1f, 0x20, 0x28, 0x63, 0xb9, + 0x91, 0x74, 0x7f, 0xfc, 0xa4, 0x72, 0x2a, 0x15, 0xfa, 0x14, 0x2c, 0xf2, 0x51, 0x64, 0x65, 0x73, + 0x74, 0x2c, 0x28, 0x04, 0xe8, 0x43, 0x53, 0x69, 0x7a, 0x65, 0xf0, 0x40, 0x6d, 0x61, 0x78, 0x44, + 0xe3, 0x01, 0xef, 0x26, 0x29, 0x3b, 0xa5, 0x26, 0x64, 0x65, 0xa3, 0x5f, 0x73, 0x61, 0x66, 0x65, + 0x20, 0xa5, 0x12, 0x88, 0xe4, 0xfa, 0x0c, 0xa1, 0x0b, 0xe7, 0x83, 0x11, 0xfd, 0x1f, 0x0a, 0x3e, + 0x03, 0x93, 0x29, 0x52, 0xf9, 0x25, 0x20, 0x43, 0xce, 0x37, 0x73, 0x20, 0x27, 0x4e, 0xb2, 0x27, + 0x20, 0x62, 0x77, 0xfd, 0xc4, 0x66, 0x72, 0x6f, 0x6d, 0x2e, 0xfa, 0x05, 0xe1, 0x11, 0x27, 0xc9, + 0x83, 0x47, 0xfe, 0xb0, 0x61, 0x6c, 0x72, 0xdc, 0xfa, 0x10, 0x79, 0xf8, 0xc1, 0x6c, 0x6f, 0x63, + 0x61, 0x2d, 0xf4, 0x11, 0x27, 0x5c, 0x14, 0x27, 0xce, 0x82, 0x6c, 0xf4, 0x00, 0xb3, 0x28, 0x20, + 0x27, 0x05, 0x2a, 0x27, 0x2e, 0x89, 0xb1, 0x69, 0x6f, 0x6e, 0xd8, 0xfd, 0xa0, 0x67, 0x75, 0x9c, + 0xfc, 0xa4, 0x6e, 0x74, 0xed, 0xf9, 0x41, 0x73, 0x75, 0x63, 0x63, 0xf5, 0x2b, 0x69, 0x66, 0xc5, + 0xba, 0x20, 0x3e, 0x3d, 0x71, 0xfe, 0x67, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x4a, 0x13, 0x29, + 0xa4, 0x20, 0x49, 0x74, 0x6e, 0x60, 0x73, 0x6f, 0x20, 0x72, 0x75, 0x6e, 0x3e, 0xa0, 0x61, 0x73, + 0x46, 0xfc, 0x20, 0x2c, 0x20, 0xf0, 0xb0, 0x69, 0x74, 0x27, 0xb6, 0xf4, 0xa1, 0x20, 0x72, 0xda, + 0xfe, 0xb1, 0x6d, 0x65, 0x6e, 0xfd, 0xf4, 0xb1, 0x73, 0x65, 0x74, 0xaf, 0xf9, 0x04, 0xc8, 0x91, + 0x66, 0x9c, 0xf4, 0x86, 0x25, 0xf9, 0x81, 0x08, 0xfd, 0xa7, 0x6e, 0x6f, 0x93, 0xfe, 0x86, 0xff, + 0xfe, 0x04, 0x03, 0xc1, 0x20, 0x6d, 0x6f, 0x72, 0xa2, 0xf9, 0x2a, 0x6d, 0x69, 0x06, 0xc2, 0x64, + 0x67, 0x65, 0x74, 0xb2, 0xf6, 0x8a, 0x9e, 0xfc, 0xc0, 0x73, 0x74, 0x6f, 0x70, 0xad, 0xfa, 0x10, + 0x69, 0x87, 0xc0, 0x64, 0x69, 0x61, 0x74, 0xff, 0xfc, 0x92, 0x2a, 0xc6, 0xf8, 0x0b, 0x8e, 0x00, + 0xd2, 0xb1, 0x75, 0x6c, 0x74, 0xef, 0xfe, 0x43, 0x7a, 0x65, 0x72, 0x6f, 0x6a, 0x11, 0x41, 0x4c, + 0x81, 0xeb, 0xfd, 0xd0, 0x65, 0x71, 0x75, 0x65, 0x6e, 0xf2, 0xfd, 0x04, 0x95, 0x82, 0x9e, 0xf8, + 0x22, 0x65, 0x6e, 0xd2, 0xa2, 0x6e, 0x6f, 0x8c, 0xfc, 0x23, 0x69, 0x64, 0xcd, 0x47, 0x54, 0x68, + 0x69, 0x73, 0xab, 0xc0, 0x6e, 0x65, 0x76, 0x65, 0x6c, 0xf2, 0xa1, 0x72, 0x69, 0x2f, 0xfe, 0xc0, + 0x6f, 0x75, 0x74, 0x73, 0x2d, 0xf8, 0x8b, 0x57, 0xfe, 0x10, 0x2c, 0xbf, 0xa1, 0x72, 0x20, 0x34, + 0xfe, 0x05, 0xe0, 0x05, 0x14, 0x03, 0xde, 0x88, 0x10, 0xf3, 0x88, 0x2a, 0xfd, 0x90, 0x20, 0x63, + 0xfb, 0xb0, 0x4d, 0x61, 0x78, 0x52, 0xfe, 0xc0, 0x70, 0x70, 0x6f, 0x72, 0xfc, 0xfe, 0x86, 0x09, + 0xfc, 0x83, 0x4d, 0xfc, 0x75, 0x07, 0x41, 0x58, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x56, + 0x41, 0x4c, 0x55, 0x45, 0xbf, 0x89, 0xf9, 0xfc, 0xa3, 0x20, 0x3a, 0xcd, 0xf7, 0xa1, 0x6f, 0x72, + 0x9c, 0xfa, 0xc3, 0x74, 0x69, 0x61, 0x6c, 0xd0, 0xfd, 0x24, 0x6f, 0x66, 0x89, 0x05, 0x59, 0x92, + 0x28, 0xc6, 0xfb, 0x83, 0xb4, 0xf2, 0xaf, 0x62, 0x65, 0x88, 0xfd, 0x00, 0x16, 0x29, 0xa2, 0xc0, + 0x72, 0x65, 0x74, 0x75, 0x2c, 0xf7, 0x92, 0x3a, 0xa8, 0xfe, 0x93, 0x6e, 0x05, 0xfa, 0xa4, 0x6f, + 0x66, 0x32, 0xfd, 0xa1, 0x77, 0x72, 0x87, 0xf1, 0x92, 0x6e, 0x40, 0xfe, 0x0d, 0x9e, 0xb0, 0x6e, + 0x65, 0x63, 0x55, 0xfe, 0xb0, 0x61, 0x72, 0x69, 0x65, 0xfb, 0x21, 0x3c, 0x3d, 0x5a, 0x52, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x58, 0x00, 0xa1, 0x09, 0xff, 0x01, 0x50, 0xcb, 0x30, 0x20, 0x69, 0x66, + 0xef, 0xf6, 0xef, 0x61, 0x69, 0x6c, 0x73, 0x0a, 0x0a, 0x2d, 0xfc, 0x01, 0x85, 0x95, 0xfc, 0x88, + 0x4a, 0xfc, 0x04, 0x03, 0x22, 0x69, 0x73, 0x59, 0x00, 0xeb, 0xc1, 0x63, 0x69, 0x73, 0x65, 0xf4, + 0xfe, 0x86, 0xff, 0xfe, 0x01, 0xe7, 0x08, 0xcf, 0x83, 0x7e, 0xf6, 0xa6, 0x2e, 0x0a, 0xbf, 0xfe, + 0x0f, 0xb4, 0x05, 0x06, 0xc1, 0x01, 0x2a, 0xa2, 0x69, 0x6e, 0xf8, 0xf1, 0x86, 0x1b, 0xfe, 0x8f, + 0xbb, 0xfe, 0x0d, 0xaf, 0x2e, 0x0a, 0xbf, 0xfe, 0x0f, 0x18, 0x64, 0x88, 0x82, 0xba, 0xfe, 0x0f, + 0x98, 0x01, 0x8e, 0xb5, 0xfe, 0x0e, 0x50, 0x8e, 0xaf, 0xfe, 0x1f, 0x49, 0x50, 0x02, 0x85, 0x28, + 0xfd, 0xc0, 0x6c, 0x61, 0x72, 0x67, 0x9c, 0xf9, 0x62, 0x6e, 0x6f, 0x75, 0x67, 0x68, 0x2c, 0x7e, + 0x91, 0x64, 0x2b, 0xf9, 0xc2, 0x77, 0x69, 0x6c, 0x6c, 0xaa, 0xfc, 0x82, 0xba, 0xfc, 0x92, 0x6f, + 0x54, 0xfe, 0x00, 0xf5, 0xe3, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xfc, 0xef, 0x5d, 0x28, 0x3c, + 0x30, 0x29, 0x2e, 0x96, 0x01, 0x28, 0x85, 0x62, 0xf4, 0x61, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x97, 0xe1, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x07, 0xf9, 0xa1, 0x61, 0x6c, 0x6c, 0xf8, 0xba, + 0x65, 0x64, 0x2c, 0x66, 0xfc, 0x07, 0x91, 0x06, 0x7e, 0x01, 0x88, 0x85, 0xd2, 0xfe, 0x50, 0x61, + 0x20, 0x6e, 0x65, 0x67, 0x43, 0xa4, 0x76, 0x65, 0x3d, 0xfc, 0x09, 0x89, 0x8e, 0x6f, 0xfc, 0x92, + 0x69, 0x7c, 0xf0, 0x04, 0x8f, 0xb1, 0x61, 0x67, 0x61, 0x94, 0xf5, 0x86, 0xcd, 0xfa, 0xc0, 0x76, + 0x65, 0x72, 0x66, 0x1d, 0xf0, 0xe0, 0x20, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0xdd, 0xf8, 0x81, 0x23, + 0xfa, 0x31, 0x63, 0x6c, 0x75, 0x8e, 0x01, 0x63, 0xe3, 0x69, 0x63, 0x69, 0x6f, 0x75, 0x73, 0xee, + 0xf4, 0x7d, 0x00, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x1d, 0x9f, 0x74, 0x0e, 0xfc, 0x03, + 0x84, 0xdd, 0xfe, 0x8e, 0x0e, 0xfc, 0x07, 0xdf, 0x27, 0x69, 0x6e, 0xe0, 0x81, 0x08, 0xf5, 0x8f, + 0x9b, 0xf8, 0x1c, 0xd0, 0x41, 0x64, 0x76, 0x61, 0x6e, 0xc5, 0xf7, 0x87, 0x99, 0xf8, 0x8f, 0xfc, + 0xf4, 0x1e, 0x8c, 0xca, 0xfb, 0x45, 0x53, 0x49, 0x5a, 0x45, 0x2c, 0x52, 0x30, 0x78, 0x37, 0x45, + 0x30, 0xff, 0x83, 0x8d, 0xf5, 0xf4, 0x06, 0x32, 0x20, 0x31, 0x31, 0x33, 0x20, 0x39, 0x32, 0x39, + 0x20, 0x32, 0x31, 0x36, 0x64, 0xfd, 0x0c, 0xb7, 0xb2, 0x43, 0x4f, 0x4d, 0x97, 0xef, 0xf1, 0x01, + 0x42, 0x4f, 0x55, 0x4e, 0x44, 0x28, 0x69, 0x73, 0x8a, 0xfd, 0xc0, 0x20, 0x20, 0x28, 0x28, 0xec, + 0xf9, 0x65, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x29, 0xec, 0x27, 0x3e, 0x20, 0xec, 0x0f, 0x7e, 0x01, + 0x65, 0x3f, 0x20, 0x30, 0x20, 0x3a, 0x20, 0xd3, 0x34, 0x2b, 0x20, 0x28, 0xf5, 0x41, 0x2f, 0x32, + 0x35, 0x35, 0xf0, 0xb2, 0x31, 0x36, 0x29, 0x9b, 0xf8, 0x8e, 0x68, 0xf9, 0x86, 0x09, 0xfc, 0x95, + 0x50, 0xba, 0xf2, 0xb1, 0x74, 0x68, 0x65, 0xf3, 0xfc, 0xc2, 0x69, 0x6d, 0x75, 0x6d, 0x58, 0xfc, + 0x82, 0x08, 0xed, 0x01, 0x53, 0x8a, 0xb7, 0xfb, 0xb5, 0x6d, 0x61, 0x79, 0x54, 0xfe, 0x91, 0x69, + 0xa6, 0xfd, 0xc1, 0x22, 0x77, 0x6f, 0x72, 0xef, 0xf7, 0xe0, 0x61, 0x73, 0x65, 0x22, 0x20, 0x73, + 0x5b, 0xec, 0xe2, 0x61, 0x72, 0x69, 0x6f, 0x20, 0x28, 0x52, 0xfe, 0x83, 0xf8, 0xfd, 0x89, 0x5b, + 0xf9, 0xef, 0x69, 0x62, 0x6c, 0x65, 0x29, 0x0a, 0x8c, 0xfd, 0x05, 0xa3, 0x69, 0x6d, 0x6b, 0xfc, + 0xe1, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x67, 0xf6, 0x83, 0x17, 0xf6, 0x85, 0xfb, 0xfb, 0x02, + 0xd6, 0xe1, 0x70, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x7b, 0xf5, 0x8f, 0x6c, 0xfc, 0x01, 0x97, 0x73, + 0x9a, 0xf8, 0xdf, 0x4d, 0x61, 0x63, 0x72, 0x6f, 0x95, 0xfe, 0x01, 0x10, 0x29, 0x94, 0x82, 0x80, + 0xf8, 0x86, 0x97, 0xed, 0x01, 0x97, 0x02, 0x5f, 0x22, 0x69, 0x6c, 0xb3, 0xc0, 0x2d, 0x74, 0x69, + 0x6d, 0x2e, 0xfc, 0x81, 0xd2, 0xf9, 0x03, 0xa3, 0x6f, 0x28, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x74, + 0x00, 0x02, 0xc7, 0x83, 0xf5, 0xf4, 0x05, 0x8a, 0xb4, 0x4e, 0x6f, 0x74, 0xc8, 0xfe, 0x8f, 0x2a, + 0xf7, 0x05, 0x04, 0xed, 0x85, 0x07, 0xf8, 0xd2, 0x20, 0x77, 0x68, 0x65, 0x6e, 0xa2, 0xfb, 0x09, + 0x3d, 0x00, 0x5d, 0x8f, 0xb4, 0xf7, 0x05, 0xaa, 0x72, 0x63, 0x60, 0xfb, 0x83, 0xeb, 0xfc, 0x85, + 0x12, 0xf9, 0x9f, 0x6d, 0x12, 0xf9, 0x05, 0x8e, 0xca, 0xfd, 0x8e, 0x71, 0xf9, 0x85, 0x08, 0xfe, + 0x84, 0x26, 0xfe, 0x02, 0x7b, 0x8f, 0x21, 0xfe, 0x09, 0x8f, 0x90, 0xf9, 0x01, 0x43, 0x2c, 0x20, + 0x69, 0x66, 0x72, 0x06, 0x3e, 0xb4, 0x74, 0x6f, 0x6f, 0xe2, 0xfa, 0x3f, 0x28, 0x20, 0x3e, 0x7a, + 0x01, 0xc3, 0x29, 0x0a, 0x2a, 0x2f, 0x3d, 0xf5, 0x0e, 0x18, 0x00, 0xea, 0x03, 0x25, 0x8f, 0xd9, + 0xf5, 0x06, 0xb7, 0x66, 0x61, 0x73, 0xdc, 0xf5, 0x91, 0x53, 0x96, 0xf0, 0xaf, 0x61, 0x73, 0x8d, + 0xfe, 0x05, 0x81, 0x0a, 0xf2, 0x92, 0x74, 0x4a, 0xfe, 0xa2, 0x77, 0x73, 0x42, 0xf6, 0xc2, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0xfa, 0x40, 0x22, 0x61, 0x63, 0x63, 0xf3, 0x92, 0x72, 0x33, 0xfe, 0xd0, + 0x22, 0x20, 0x66, 0x61, 0x63, 0xf6, 0xee, 0x85, 0x5d, 0xf7, 0x13, 0x65, 0x44, 0x92, 0x72, 0xbc, + 0xee, 0x09, 0xd7, 0x83, 0xa7, 0xfe, 0x83, 0x80, 0xfa, 0x01, 0x79, 0x03, 0xdd, 0x87, 0xdc, 0xe8, + 0x05, 0x90, 0xa3, 0x73, 0x6f, 0x21, 0xf0, 0x00, 0x73, 0x03, 0xdd, 0x89, 0xb9, 0xfc, 0x84, 0xf6, + 0xf5, 0x83, 0x0e, 0xf6, 0xa0, 0x74, 0x72, 0xae, 0xe8, 0x50, 0x2d, 0x6f, 0x66, 0x66, 0x2e, 0xee, + 0x82, 0x31, 0xf3, 0xb2, 0x62, 0x65, 0x20, 0xd6, 0xfb, 0xd4, 0x74, 0x75, 0x6e, 0x65, 0x64, 0x47, + 0xe9, 0xc2, 0x65, 0x61, 0x63, 0x68, 0x85, 0xf5, 0x01, 0xbe, 0x23, 0x76, 0x65, 0x79, 0x83, 0x3b, + 0xfd, 0x82, 0x82, 0xfa, 0x91, 0x72, 0x7e, 0xf9, 0x80, 0xc2, 0xfc, 0x42, 0x2b, 0x7e, 0x33, 0x25, + 0x18, 0xa5, 0x70, 0x65, 0xcb, 0xf8, 0x2f, 0x41, 0x6e, 0x3e, 0x00, 0x82, 0x79, 0xf8, 0xb6, 0x22, + 0x31, 0x22, 0x66, 0xf8, 0x84, 0xbb, 0xfe, 0x40, 0x72, 0x65, 0x67, 0x75, 0x06, 0x8f, 0xb3, 0xfe, + 0x05, 0x02, 0xb1, 0x11, 0x56, 0xc1, 0x91, 0x73, 0xc4, 0xf8, 0x93, 0x30, 0x87, 0xf9, 0x92, 0x62, + 0xb6, 0xed, 0xb1, 0x6c, 0x61, 0x63, 0xf6, 0xf7, 0xd0, 0x79, 0x20, 0x41, 0x43, 0x43, 0x13, 0xf1, + 0xb1, 0x52, 0x41, 0x54, 0x08, 0xf1, 0xf2, 0x05, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, + 0x28, 0x73, 0x65, 0x65, 0x48, 0xee, 0xa4, 0x63, 0x29, 0x15, 0xf8, 0x82, 0x7f, 0xf2, 0x95, 0x2e, + 0xfb, 0xfd, 0x8e, 0x21, 0xfe, 0x9f, 0x20, 0x3a, 0xf3, 0x2a, 0x06, 0xef, 0x0a, 0x07, 0xbf, 0x29, + 0x3b, 0x0a, 0xb5, 0xfd, 0x04, 0xe0, 0x5f, 0x65, 0x78, 0x74, 0x53, 0x74, 0x9a, 0xf7, 0x8a, 0xac, + 0xfd, 0x8f, 0xae, 0xed, 0x03, 0xb1, 0x2c, 0x20, 0x6a, 0x5e, 0xf7, 0xa3, 0x75, 0x73, 0x9c, 0xf8, + 0x93, 0x20, 0x5a, 0xed, 0xb6, 0x61, 0x6c, 0x6c, 0x98, 0xf3, 0x87, 0x60, 0xf1, 0xd2, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x74, 0xfe, 0x3b, 0x74, 0x6f, 0x72, 0xb1, 0x11, 0x73, 0x92, 0x83, 0x62, 0xfe, + 0xa3, 0x55, 0x73, 0xed, 0xf9, 0x81, 0xc8, 0xfc, 0x24, 0x6f, 0x66, 0x79, 0x01, 0xca, 0x60, 0x6b, + 0x6e, 0x6f, 0x77, 0x20, 0x68, 0xfc, 0x44, 0x6d, 0x75, 0x63, 0x68, 0xac, 0x85, 0xe0, 0xf6, 0x07, + 0x93, 0x83, 0x33, 0xf4, 0x36, 0x61, 0x6e, 0x64, 0xed, 0x40, 0x20, 0x69, 0x74, 0x20, 0x9d, 0xa3, + 0x38, 0x2d, 0x86, 0xf9, 0x91, 0x62, 0xad, 0xfc, 0xb1, 0x61, 0x72, 0x69, 0xcc, 0xfa, 0x03, 0x49, + 0x12, 0x6d, 0xd6, 0x01, 0x9b, 0x41, 0x79, 0x70, 0x69, 0x63, 0x44, 0x96, 0x29, 0x09, 0xfd, 0xa4, + 0x6e, 0x2c, 0xe7, 0xfa, 0x02, 0xb9, 0xc1, 0x61, 0x73, 0x20, 0x27, 0x66, 0xef, 0x13, 0x2a, 0x4f, + 0x10, 0x27, 0x69, 0x8f, 0xea, 0xfe, 0x03, 0x85, 0x39, 0xfe, 0x0e, 0x37, 0x01, 0xc3, 0x84, 0xb1, + 0xf1, 0x8f, 0x8a, 0xfe, 0x08, 0x28, 0x20, 0x28, 0x9c, 0xaf, 0x2c, 0x20, 0x08, 0xfe, 0x0e, 0x86, + 0xe2, 0xfb, 0x8f, 0x09, 0xfe, 0x2a, 0x13, 0x64, 0xd1, 0x87, 0x0e, 0xfe, 0xa1, 0x52, 0x65, 0x6e, + 0xee, 0x93, 0x65, 0x4b, 0xfc, 0xd0, 0x6f, 0x67, 0x69, 0x63, 0x2c, 0x34, 0xfd, 0x05, 0x13, 0x83, + 0x12, 0xfe, 0x92, 0x73, 0x76, 0xfe, 0x82, 0x2a, 0xf9, 0x01, 0xf3, 0xa3, 0x70, 0x6f, 0x2f, 0xf9, + 0x82, 0x79, 0xf1, 0x8d, 0x6d, 0xf3, 0x8f, 0x79, 0xf1, 0x09, 0x8b, 0x24, 0xf4, 0x87, 0x79, 0xf1, + 0x91, 0x74, 0x8f, 0xfb, 0x99, 0x74, 0x76, 0xf1, 0x8e, 0xd8, 0xf8, 0xa1, 0x65, 0x69, 0xd2, 0xe6, + 0x06, 0x6a, 0x84, 0x4a, 0xf8, 0xd6, 0x65, 0x6e, 0x74, 0x69, 0x72, 0xeb, 0xf2, 0x86, 0x85, 0xf2, + 0x02, 0x81, 0x05, 0x9a, 0xa2, 0x69, 0x66, 0x9f, 0xf1, 0x8b, 0x50, 0xf5, 0x94, 0x0a, 0x41, 0xfa, + 0xc9, 0x66, 0x69, 0x6c, 0x6c, 0xe3, 0xf0, 0x04, 0x9d, 0xa1, 0x6c, 0x65, 0xf6, 0xf1, 0x82, 0x81, + 0xfb, 0x0f, 0x03, 0x15, 0x87, 0x13, 0xf6, 0x97, 0x2a, 0x66, 0xfc, 0xd5, 0x50, 0x74, 0x72, 0x20, + 0x3a, 0xd6, 0xfb, 0x84, 0x8d, 0xe4, 0x83, 0xb6, 0xf0, 0xc1, 0x69, 0x6e, 0x64, 0x69, 0x4e, 0xfd, + 0x83, 0x1a, 0xfd, 0xb5, 0x61, 0x6e, 0x79, 0xf6, 0xf2, 0x00, 0x1b, 0x92, 0x65, 0x0e, 0xf2, 0x0b, + 0xa1, 0x00, 0xcc, 0x08, 0x54, 0x08, 0x92, 0x0e, 0xff, 0xb7, 0x4e, 0x65, 0x77, 0xfe, 0xf8, 0x8c, + 0x0e, 0xf4, 0xa4, 0x6f, 0x6c, 0xe2, 0xf8, 0x9f, 0x2e, 0xf7, 0xf8, 0x00, 0xaf, 0x4e, 0x62, 0x73, + 0xf2, 0x01, 0x8f, 0x7a, 0xf2, 0x06, 0x86, 0x4f, 0xfe, 0x8f, 0x79, 0xf2, 0x1c, 0x88, 0x0d, 0xfb, + 0x8e, 0x70, 0xfd, 0x8f, 0x9e, 0xee, 0x14, 0xaa, 0x2a, 0x20, 0xa2, 0xfe, 0x02, 0xec, 0x0c, 0x72, + 0x89, 0x0b, 0xfd, 0xaf, 0x64, 0x65, 0xc7, 0xf8, 0x04, 0xd0, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x44, + 0xfb, 0x8a, 0x5c, 0xf2, 0x06, 0xea, 0x85, 0x00, 0xf0, 0xb1, 0x72, 0x65, 0x66, 0x42, 0xfb, 0xa7, + 0x75, 0x6e, 0xa3, 0xf2, 0x82, 0x4f, 0xfd, 0x8f, 0x70, 0xf2, 0x0f, 0x87, 0x3f, 0xfe, 0x88, 0x2a, + 0xf3, 0x86, 0x79, 0xf2, 0xa4, 0x69, 0x6e, 0x05, 0xe4, 0xd3, 0x77, 0x6f, 0x72, 0x64, 0x73, 0xb0, + 0xf8, 0x0c, 0x9e, 0x9f, 0x29, 0xe2, 0xf2, 0x73, 0x9e, 0x44, 0x98, 0xf5, 0x8f, 0x5b, 0xf1, 0x09, + 0x42, 0x20, 0x49, 0x74, 0x73, 0x44, 0x07, 0xdc, 0xc3, 0x20, 0x6d, 0x69, 0x6e, 0xa3, 0xf6, 0xb5, + 0x66, 0x20, 0x27, 0x8d, 0xfe, 0x88, 0x3a, 0xed, 0x03, 0x91, 0x91, 0x6e, 0xc6, 0xf5, 0x9c, 0x3a, + 0x11, 0xfc, 0xa1, 0x66, 0x75, 0xa8, 0xf9, 0x84, 0xa6, 0xe7, 0x84, 0xfe, 0xf9, 0x89, 0x30, 0xfa, + 0x91, 0x66, 0x65, 0xef, 0x91, 0x72, 0x6c, 0xe7, 0x00, 0xd9, 0x03, 0x05, 0x8d, 0x67, 0xe7, 0x0a, + 0x33, 0xa2, 0x49, 0x74, 0x02, 0xf5, 0xc7, 0x20, 0x62, 0x69, 0x74, 0x44, 0xf7, 0xbf, 0x61, 0x6e, + 0x20, 0xe9, 0xef, 0x03, 0x0a, 0xc6, 0xb1, 0x48, 0x6f, 0x77, 0xe0, 0xfa, 0x91, 0x2c, 0xeb, 0xf9, + 0xb2, 0x64, 0x6f, 0x65, 0x04, 0xf1, 0x86, 0xd7, 0xf9, 0xb3, 0x61, 0x6e, 0x79, 0xcd, 0xf1, 0x02, + 0x4a, 0x86, 0xcc, 0xf1, 0x92, 0x69, 0x7a, 0xfb, 0xa2, 0x69, 0x6f, 0xe2, 0xf8, 0x84, 0x08, 0xfc, + 0x04, 0x6a, 0x85, 0x42, 0xfe, 0x96, 0x28, 0xcc, 0xf1, 0x83, 0x2e, 0xfa, 0x0b, 0x8b, 0x91, 0x55, + 0x71, 0xfa, 0x8b, 0xd8, 0xf3, 0x50, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x47, 0x90, 0x64, 0x3d, 0xfb, + 0xd2, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x42, 0xe8, 0x20, 0x6f, 0x6e, 0x9f, 0x12, 0x28, 0xa7, 0xa3, + 0x74, 0x6f, 0x1b, 0xfe, 0x82, 0xb3, 0xfd, 0x85, 0xdd, 0xeb, 0x15, 0x61, 0xca, 0x84, 0xc3, 0xfd, + 0x9a, 0x29, 0x50, 0xf9, 0xaf, 0x64, 0x65, 0x87, 0xf7, 0x20, 0x86, 0xc4, 0xfc, 0x8a, 0x5e, 0xf5, + 0x8e, 0xba, 0xfe, 0x94, 0x5f, 0xc7, 0xed, 0x83, 0x8d, 0xfc, 0x8e, 0x31, 0xfa, 0x07, 0xd2, 0xae, + 0x20, 0x61, 0xb1, 0xee, 0x87, 0xe7, 0xf9, 0x8b, 0x62, 0xef, 0x91, 0x27, 0x34, 0xe4, 0x81, 0x48, + 0xe4, 0x01, 0xbd, 0x8a, 0x09, 0xeb, 0x8e, 0x0c, 0xef, 0x8f, 0x96, 0xf9, 0x06, 0x8c, 0x0c, 0xef, + 0x89, 0x91, 0xf9, 0x89, 0xc8, 0xfc, 0x92, 0x74, 0x9b, 0xfd, 0xa5, 0x74, 0x6f, 0xc4, 0xfc, 0x89, + 0xf3, 0xf8, 0xa5, 0x6f, 0x70, 0xb2, 0xf5, 0x52, 0x61, 0x73, 0x20, 0x73, 0x6f, 0xf8, 0x85, 0x3d, + 0xf9, 0x87, 0x65, 0xed, 0x30, 0x27, 0x20, 0x68, 0xe9, 0xe1, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x72, + 0x3f, 0xf5, 0x85, 0x51, 0xf7, 0x91, 0x72, 0x37, 0xe8, 0x00, 0xb9, 0x08, 0xab, 0x02, 0x8f, 0xbf, + 0x69, 0x6d, 0x65, 0x18, 0xee, 0x15, 0xb4, 0x64, 0x65, 0x64, 0xa9, 0xdf, 0x8f, 0x1b, 0xee, 0x2e, + 0x92, 0x4e, 0x86, 0xfc, 0x82, 0x97, 0xfd, 0x04, 0x96, 0x85, 0x7c, 0xf4, 0x1f, 0x3c, 0x2f, 0x02, + 0xef, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0xff, 0xec, 0x03, 0x87, 0x83, 0xfd, 0x01, 0xc2, 0x91, + 0x73, 0x99, 0xf6, 0xac, 0x65, 0x72, 0xb2, 0xfb, 0xe5, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x80, + 0xe3, 0x8e, 0x07, 0xf9, 0x35, 0x65, 0x72, 0x65, 0x21, 0x8f, 0xe4, 0xed, 0x81, 0x8f, 0x45, 0xee, + 0x05, 0x9c, 0x66, 0x42, 0xee, 0x01, 0xa0, 0x02, 0xd5, 0x8d, 0x3c, 0xee, 0xab, 0x6f, 0x66, 0x39, + 0xee, 0x83, 0x6f, 0xfb, 0x88, 0x9b, 0xf9, 0x8e, 0x87, 0xed, 0x8f, 0xab, 0xed, 0x04, 0x86, 0xbd, + 0xf8, 0x8f, 0x8d, 0xfc, 0x09, 0x8f, 0x55, 0xe7, 0x28, 0x89, 0x0c, 0xfe, 0x8f, 0x3f, 0xe7, 0x0d, + 0x8a, 0x7b, 0xed, 0x8f, 0x0d, 0xe6, 0x19, 0x82, 0x42, 0xfe, 0xb9, 0x69, 0x6e, 0x67, 0x97, 0xe7, + 0x8f, 0x65, 0xed, 0x02, 0x8f, 0x5c, 0xed, 0x22, 0xe1, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x9e, + 0xf0, 0xc0, 0x5f, 0x55, 0x36, 0x34, 0xee, 0xed, 0xed, 0x31, 0x20, 0x3c, 0x3c, 0x20, 0x28, 0x58, + 0xe5, 0xb1, 0x2d, 0x33, 0x29, 0xdf, 0xed, 0x2f, 0x34, 0x29, 0xc3, 0x01, 0x86, 0x23, 0xed, 0x1f, + 0x28, 0xaf, 0x01, 0xa3, 0x2a, 0x20, 0x1f, 0xf4, 0x30, 0x28, 0x6c, 0x6f, 0x3f, 0x01, 0xfb, 0xa8, + 0x29, 0x29, 0xad, 0xe3, 0x83, 0x66, 0xfd, 0x92, 0x5f, 0x8f, 0xe4, 0xa1, 0x69, 0x6e, 0x6e, 0xfd, + 0x83, 0x66, 0xfc, 0x00, 0xe8, 0xd2, 0x75, 0x63, 0x74, 0x75, 0x72, 0xef, 0xf2, 0xa1, 0x74, 0x72, + 0xae, 0xee, 0x83, 0x86, 0xf9, 0x84, 0x34, 0xfd, 0x12, 0x2e, 0xcf, 0x91, 0x6d, 0x42, 0xef, 0xb1, + 0x61, 0x6e, 0x74, 0x71, 0xf7, 0xb2, 0x6e, 0x69, 0x74, 0x6a, 0xfc, 0x07, 0xc5, 0x86, 0x26, 0xf5, + 0x93, 0x62, 0xd1, 0xfd, 0xd2, 0x66, 0x69, 0x72, 0x73, 0x74, 0xe4, 0xe0, 0x10, 0x21, 0xc2, 0x85, + 0xbc, 0xf8, 0xaa, 0x6f, 0x6e, 0x73, 0xf2, 0x60, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0xed, 0x38, + 0x74, 0x68, 0x65, 0xb5, 0x93, 0x69, 0x18, 0xe0, 0xb2, 0x61, 0x72, 0x65, 0x88, 0xf3, 0x83, 0xf8, + 0xf2, 0xd4, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x3d, 0xe0, 0x00, 0xae, 0x86, 0x84, 0xfc, 0x06, 0xd4, + 0x84, 0x07, 0xf2, 0xe1, 0x6c, 0x69, 0x62, 0x6c, 0x7a, 0x34, 0x0d, 0xfb, 0xda, 0x61, 0x20, 0x44, + 0x4c, 0x4c, 0x59, 0xe0, 0x51, 0x62, 0x65, 0x6c, 0x6f, 0x77, 0x56, 0x03, 0x94, 0x82, 0xcb, 0xec, + 0xe6, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x49, 0xe0, 0x82, 0xbf, 0xe3, 0xc0, 0x74, 0x79, 0x70, + 0x65, 0x86, 0xfe, 0x04, 0x6d, 0xb6, 0x20, 0x7b, 0x20, 0xb0, 0xfe, 0xa1, 0x20, 0x74, 0x9d, 0xdf, + 0x9f, 0x5b, 0x84, 0xfe, 0x00, 0xca, 0x5d, 0x3b, 0x20, 0x7d, 0x9b, 0xfe, 0xa8, 0x3b, 0x0a, 0x86, + 0xfe, 0xd3, 0x72, 0x65, 0x73, 0x65, 0x74, 0xa5, 0xfd, 0x01, 0xed, 0x8e, 0xc2, 0xf8, 0x83, 0x8e, + 0xf4, 0x91, 0x69, 0x04, 0xef, 0x87, 0xe1, 0xfe, 0x0a, 0xb1, 0x87, 0xe1, 0xfe, 0x02, 0x5e, 0x81, + 0x6a, 0xf2, 0x0d, 0xa6, 0x29, 0x20, 0x28, 0xcf, 0x94, 0x2a, 0x43, 0xfe, 0x4a, 0x50, 0x74, 0x72, + 0x29, 0x74, 0x81, 0x22, 0xe2, 0x23, 0x74, 0x65, 0xcd, 0x82, 0x7e, 0xfb, 0x05, 0x8e, 0x82, 0x67, + 0xd8, 0x02, 0x79, 0x51, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0xf1, 0x0f, 0x7d, 0x05, 0x05, 0xb5, 0x35, + 0x66, 0x72, 0x65, 0xb7, 0xa2, 0x72, 0x65, 0x99, 0xfe, 0x91, 0x73, 0xda, 0xde, 0x84, 0xf1, 0xf6, + 0x83, 0x4c, 0xde, 0x81, 0xf7, 0xf9, 0x84, 0xe2, 0xfd, 0x91, 0x78, 0x63, 0xd9, 0x83, 0x69, 0xfe, + 0xa3, 0x20, 0x28, 0x58, 0xfe, 0x9a, 0x29, 0x60, 0xfe, 0x20, 0x74, 0x68, 0x32, 0x86, 0x6d, 0xfe, + 0xc5, 0x72, 0x61, 0x74, 0x68, 0xf9, 0xf6, 0xa5, 0x74, 0x68, 0xf4, 0xfd, 0x04, 0x7a, 0x02, 0xa3, + 0xc2, 0x54, 0x68, 0x65, 0x79, 0x05, 0xfe, 0x92, 0x6d, 0x8d, 0xfd, 0xb3, 0x75, 0x74, 0x75, 0x57, + 0xfb, 0xa1, 0x6f, 0x66, 0xe7, 0xfb, 0x82, 0xe5, 0xec, 0x02, 0x8e, 0x83, 0x0f, 0xdf, 0x01, 0xf4, + 0x0c, 0x2f, 0x00, 0x1a, 0x83, 0x0e, 0xfe, 0x09, 0xe9, 0x8f, 0xd9, 0xfe, 0x00, 0x89, 0xd4, 0xf0, + 0x06, 0xff, 0x86, 0xfe, 0xfe, 0x8f, 0x82, 0xfe, 0x1b, 0xff, 0x01, 0x6c, 0x6f, 0x61, 0x64, 0x44, + 0x69, 0x63, 0x74, 0xf9, 0xfd, 0x07, 0x01, 0xdf, 0x25, 0x20, 0x61, 0x13, 0x22, 0x64, 0x69, 0xe7, + 0xb2, 0x61, 0x72, 0x79, 0xbe, 0xf7, 0x02, 0x41, 0x88, 0x6b, 0xfc, 0x92, 0x41, 0x21, 0xf6, 0xa6, + 0x65, 0x76, 0x7a, 0xfa, 0x86, 0x34, 0xf2, 0xd1, 0x66, 0x6f, 0x72, 0x67, 0x6f, 0xd9, 0xf2, 0x93, + 0x2c, 0x8b, 0xfc, 0x17, 0x27, 0xb6, 0x13, 0x27, 0xdb, 0xd1, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x48, + 0xf6, 0x89, 0x51, 0xfe, 0xb3, 0x4c, 0x6f, 0x61, 0x79, 0xf9, 0x86, 0xf0, 0xe5, 0xc3, 0x30, 0x20, + 0x69, 0x73, 0x5c, 0xec, 0x22, 0x65, 0x64, 0xdd, 0x94, 0x52, 0x00, 0xf8, 0x09, 0x64, 0x94, 0x73, + 0x74, 0xfa, 0x83, 0xd4, 0xf8, 0x8e, 0x1c, 0xf8, 0xd0, 0x36, 0x34, 0x20, 0x4b, 0x42, 0xa3, 0xdf, + 0x83, 0xe5, 0xf9, 0x8a, 0xf8, 0xfe, 0x8f, 0xc9, 0xfe, 0x07, 0x8a, 0x93, 0xef, 0x08, 0x94, 0x82, + 0x0d, 0xfa, 0x01, 0xf0, 0x88, 0x7e, 0xeb, 0x02, 0x46, 0x8e, 0x3c, 0xef, 0x81, 0x8c, 0xfd, 0xb1, + 0x69, 0x6e, 0x75, 0x52, 0xfd, 0x86, 0x33, 0xfa, 0x84, 0x9b, 0xdb, 0x86, 0x52, 0xfb, 0xe3, 0x27, + 0x73, 0x72, 0x63, 0x27, 0x2c, 0xc5, 0xfb, 0x82, 0xbf, 0xfe, 0x82, 0x6a, 0xf5, 0x86, 0xac, 0xfe, + 0xae, 0x6c, 0x79, 0xb6, 0xf7, 0x49, 0x73, 0x20, 0x61, 0x73, 0x05, 0xa6, 0x74, 0x6f, 0x1d, 0xdf, + 0x8e, 0xe7, 0xde, 0x83, 0xfe, 0xfc, 0x88, 0xc7, 0xfa, 0x99, 0x50, 0x54, 0xfe, 0x06, 0xb0, 0x91, + 0x72, 0x21, 0xec, 0xb4, 0x73, 0x75, 0x6d, 0x3c, 0xe1, 0x94, 0x74, 0x3d, 0xfe, 0x01, 0xb4, 0x00, + 0x5c, 0x83, 0xbf, 0xd4, 0x95, 0x6e, 0x5b, 0xf4, 0x83, 0xb0, 0xfa, 0xdf, 0x27, 0x64, 0x73, 0x74, + 0x27, 0x0c, 0xf3, 0x0f, 0x84, 0xca, 0xda, 0x82, 0xdf, 0xf8, 0x83, 0x3c, 0xf1, 0x8f, 0x43, 0xe9, + 0x0c, 0xbf, 0x2c, 0x20, 0x63, 0xa2, 0xe0, 0x11, 0x82, 0xbb, 0xf7, 0x89, 0xdc, 0xe0, 0x05, 0x99, + 0x33, 0x6e, 0x6f, 0x74, 0xe4, 0xad, 0x69, 0x66, 0x7b, 0xda, 0x85, 0xed, 0xe0, 0xa3, 0x66, 0x69, + 0x04, 0xef, 0x0a, 0x3f, 0x84, 0xc1, 0xfd, 0x8e, 0x0a, 0xe1, 0x02, 0xb3, 0x89, 0x1c, 0xe1, 0xb1, + 0x74, 0x75, 0x72, 0x2d, 0xd5, 0x85, 0x1c, 0xe1, 0x8d, 0x60, 0xeb, 0x8e, 0x06, 0xfe, 0x8f, 0xa3, + 0xfd, 0x15, 0x00, 0x01, 0x86, 0x81, 0xf7, 0x86, 0x42, 0xeb, 0xab, 0x72, 0x63, 0x9f, 0xf7, 0x8f, + 0x3d, 0xed, 0x09, 0x89, 0x9d, 0xf8, 0xb5, 0x61, 0x76, 0x65, 0x21, 0xfc, 0xaf, 0x49, 0x66, 0xb8, + 0xfd, 0x04, 0x88, 0x03, 0xfe, 0x84, 0x55, 0xe3, 0x8b, 0x98, 0xfe, 0x85, 0x66, 0xfc, 0xd2, 0x61, + 0x76, 0x61, 0x69, 0x6c, 0x2e, 0xd9, 0xa8, 0x61, 0x74, 0xa9, 0xfa, 0x95, 0x20, 0x1b, 0xe7, 0x01, + 0x9c, 0x01, 0x90, 0x95, 0x20, 0xac, 0xfe, 0x10, 0x61, 0xf1, 0x81, 0xb1, 0xfe, 0x82, 0x10, 0xea, + 0x22, 0x20, 0x28, 0x23, 0x02, 0xed, 0x92, 0x42, 0x99, 0xfe, 0x81, 0x22, 0xdc, 0x84, 0xad, 0xf4, + 0x82, 0xcc, 0xf8, 0xd6, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0xb2, 0xd8, 0x81, 0x9b, 0xf8, 0x8a, 0x66, + 0xfc, 0xd0, 0x28, 0x29, 0x20, 0x61, 0x66, 0x22, 0xfe, 0xa1, 0x77, 0x61, 0xfb, 0xef, 0x87, 0x8d, + 0xf8, 0x8a, 0x6c, 0xfb, 0xa8, 0x73, 0x20, 0x67, 0xdf, 0x31, 0x20, 0x75, 0x73, 0x51, 0xb3, 0x2c, + 0x20, 0x79, 0x13, 0xd7, 0x87, 0xc2, 0xf5, 0x02, 0xa2, 0x8f, 0x57, 0xfe, 0x09, 0xa9, 0x28, 0x29, + 0xa6, 0xfb, 0x02, 0x2a, 0x9d, 0x64, 0xa0, 0xfb, 0x8f, 0xa1, 0xfb, 0x07, 0x87, 0xf3, 0xfb, 0x95, + 0x2c, 0x26, 0xee, 0x83, 0x33, 0xe2, 0x8a, 0xde, 0xfd, 0x01, 0xac, 0x8f, 0x8f, 0xfb, 0x0d, 0x8d, + 0xcf, 0xfe, 0x86, 0x95, 0xfb, 0x89, 0x49, 0xee, 0x8f, 0xac, 0xf5, 0x2b, 0xbf, 0x44, 0x65, 0x63, + 0xaa, 0xf5, 0x32, 0x00, 0x29, 0x8f, 0xe5, 0xf5, 0x01, 0xe6, 0x44, 0x45, 0x43, 0x4f, 0x44, 0x45, + 0xf3, 0xf5, 0x2f, 0x20, 0x34, 0xdc, 0x07, 0x87, 0xbb, 0xf5, 0x0d, 0xc2, 0x8e, 0xb5, 0xf5, 0x86, + 0x1d, 0xe3, 0x99, 0x20, 0xac, 0xf5, 0x8e, 0xdf, 0xf6, 0x0a, 0xda, 0x8e, 0xd6, 0xf6, 0x0e, 0x9f, + 0x8e, 0xd0, 0xf6, 0x92, 0x44, 0xa7, 0xf2, 0xb3, 0x5f, 0x74, 0x3b, 0x51, 0xf5, 0x0e, 0xe6, 0x8f, + 0x4b, 0xf5, 0x24, 0x8f, 0x57, 0xf5, 0x09, 0x84, 0xd8, 0xe7, 0x03, 0x97, 0x38, 0x65, 0x74, 0x53, + 0x94, 0x93, 0x20, 0x22, 0xe3, 0x00, 0xea, 0xaf, 0x28, 0x29, 0x31, 0xf5, 0x04, 0x8f, 0x27, 0xf7, + 0x12, 0x85, 0x28, 0xf7, 0xe4, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0xef, 0xd8, 0xaf, 0x6f, 0x66, + 0x82, 0xf5, 0x03, 0x83, 0x67, 0xf5, 0x8f, 0x2d, 0xf7, 0x26, 0x8e, 0xd4, 0xfe, 0x87, 0xda, 0xe3, + 0x25, 0x74, 0x68, 0xbc, 0x9b, 0x2e, 0x01, 0xf6, 0x09, 0x10, 0x8f, 0xfb, 0xf5, 0x0e, 0x0e, 0x9f, + 0x8f, 0xf5, 0xf5, 0x05, 0x0a, 0xab, 0x8f, 0xef, 0xf5, 0x06, 0x2f, 0x2f, 0x0a, 0xb2, 0x00, 0x0f, + 0x67, 0x05, 0x8a, 0x5d, 0xe7, 0x0c, 0xff, 0x0f, 0x8c, 0x04, 0x1f, 0x28, 0xa4, 0x01, 0x08, 0x42, + 0x89, 0x55, 0xfa, 0x8e, 0x0a, 0xfe, 0x8f, 0x68, 0xf4, 0x09, 0x03, 0x13, 0x83, 0x05, 0xe9, 0x83, + 0x18, 0xe9, 0x83, 0x81, 0xda, 0x86, 0x5e, 0xfb, 0x84, 0xc3, 0xf6, 0xcf, 0x53, 0x65, 0x74, 0x74, + 0xc3, 0xf6, 0x08, 0xd5, 0x20, 0x28, 0x73, 0x61, 0x6d, 0x0c, 0xd7, 0x83, 0x30, 0xe4, 0x00, 0x7d, + 0x9b, 0x29, 0xac, 0xf6, 0x91, 0x31, 0x43, 0xfb, 0xbf, 0x4f, 0x4b, 0x2c, 0x3a, 0xfb, 0x07, 0x2f, + 0x65, 0x74, 0x0e, 0x10, 0x0d, 0xec, 0x8f, 0xb5, 0xf6, 0x1b, 0x96, 0x2a, 0x6b, 0xfa, 0x88, 0xe6, + 0xec, 0x00, 0x56, 0x86, 0x5d, 0xef, 0x86, 0x3e, 0xd2, 0x04, 0x26, 0x8b, 0xd7, 0xed, 0x01, 0x0a, + 0xd0, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0xc7, 0xd6, 0x85, 0x1f, 0xf7, 0xd5, 0x69, 0x6e, 0x20, 0x22, + 0x73, 0xfc, 0xfa, 0x91, 0x22, 0x91, 0xeb, 0x84, 0xb5, 0xed, 0x96, 0x50, 0xe1, 0xf8, 0x03, 0xa2, + 0x87, 0x9c, 0xf6, 0x91, 0x2a, 0x2c, 0xf7, 0x9f, 0x2a, 0xf6, 0xf8, 0x03, 0xb4, 0x74, 0x68, 0x65, + 0xf6, 0xf8, 0x86, 0x95, 0xec, 0x85, 0x65, 0xfe, 0xba, 0x68, 0x65, 0x79, 0x58, 0xee, 0xc0, 0x20, + 0x28, 0x75, 0x70, 0x4f, 0xfe, 0x86, 0x80, 0xf5, 0xa4, 0x20, 0x20, 0x49, 0xfc, 0x88, 0xb8, 0xfc, + 0x10, 0x72, 0x2d, 0x84, 0x78, 0xf7, 0x97, 0x73, 0xda, 0xdb, 0x8c, 0xa5, 0xf6, 0x84, 0x22, 0xe6, + 0x84, 0xf0, 0xfe, 0xd2, 0x2d, 0x20, 0x45, 0x78, 0x61, 0x48, 0xf1, 0xb4, 0x73, 0x61, 0x6d, 0xc6, + 0xda, 0x5a, 0x61, 0x73, 0x20, 0x65, 0x6e, 0xc4, 0x83, 0xe3, 0xe1, 0x03, 0xdd, 0xb1, 0x75, 0x70, + 0x64, 0xa5, 0xfc, 0x20, 0x72, 0x75, 0x3d, 0x12, 0x28, 0x1d, 0x89, 0xd4, 0xe9, 0x22, 0x61, 0x74, + 0xda, 0x06, 0x31, 0x11, 0x73, 0x55, 0x03, 0x53, 0x83, 0x70, 0xe2, 0x01, 0x51, 0x83, 0x28, 0xe1, + 0x07, 0x5f, 0x16, 0x26, 0x90, 0x07, 0x3d, 0x84, 0xe0, 0xec, 0xb2, 0x68, 0x61, 0x76, 0x06, 0xea, + 0x02, 0x66, 0x89, 0xf9, 0xdb, 0xc3, 0x76, 0x65, 0x72, 0x79, 0x03, 0xed, 0xb1, 0x20, 0x6f, 0x6e, + 0xb7, 0xf8, 0xa4, 0x20, 0x3c, 0xe4, 0xfe, 0x14, 0x2e, 0x27, 0x95, 0x4c, 0xa6, 0xe0, 0x00, 0xb9, + 0x0e, 0x30, 0xab, 0x62, 0x79, 0xcd, 0xe8, 0x41, 0x6d, 0x61, 0x78, 0x42, 0x34, 0xb3, 0x53, 0x69, + 0x7a, 0x50, 0xfb, 0x89, 0xca, 0xe8, 0x1b, 0x20, 0xe1, 0xb2, 0x69, 0x73, 0x20, 0xb3, 0xd4, 0x87, + 0x9b, 0xcb, 0xb1, 0x64, 0x65, 0x70, 0xb5, 0xd6, 0xb3, 0x6e, 0x74, 0x2e, 0x92, 0xe0, 0x8e, 0x1b, + 0xdd, 0xb3, 0x79, 0x6f, 0x75, 0x57, 0xe9, 0x99, 0x64, 0x24, 0xe3, 0x86, 0x15, 0xf7, 0x00, 0x66, + 0x85, 0x9d, 0xfd, 0x9f, 0x2e, 0xd0, 0xfe, 0x04, 0xa7, 0x65, 0x6e, 0xab, 0xec, 0x8d, 0x26, 0xfe, + 0xc0, 0x73, 0x20, 0x64, 0x6f, 0x85, 0xf6, 0x86, 0x00, 0xf7, 0x82, 0xe9, 0xeb, 0xc0, 0x79, 0x6e, + 0x63, 0x68, 0x47, 0xe9, 0xa3, 0x69, 0x7a, 0xf3, 0xea, 0x84, 0x42, 0xe2, 0x8f, 0x97, 0xfe, 0x20, + 0x8f, 0x9c, 0xfe, 0x0c, 0xe1, 0x5f, 0x41, 0x74, 0x20, 0x6c, 0x65, 0x01, 0xf7, 0x03, 0xe7, 0xc4, + 0x20, 0x2b, 0x20, 0x38, 0x26, 0xf7, 0x9a, 0x2b, 0xcb, 0xfe, 0x0f, 0x29, 0x7f, 0x97, 0x6c, 0xe2, + 0xfd, 0x0d, 0x87, 0x03, 0x54, 0xb2, 0x57, 0x68, 0x65, 0xa3, 0xeb, 0x83, 0x36, 0xf0, 0x8c, 0x74, + 0xc8, 0x01, 0x68, 0x86, 0x63, 0xe3, 0x93, 0x2c, 0x45, 0xf5, 0x92, 0x74, 0x32, 0xde, 0xa2, 0x73, + 0x74, 0x70, 0xd1, 0x33, 0x20, 0x6f, 0x66, 0xa9, 0x84, 0xdc, 0xf4, 0x89, 0x2a, 0xf5, 0x04, 0x99, + 0x86, 0xad, 0xe0, 0x86, 0x5f, 0xe3, 0x84, 0x04, 0xfc, 0x91, 0x69, 0x51, 0xeb, 0x83, 0xc7, 0xf5, + 0x8f, 0x26, 0xf8, 0x08, 0xaf, 0x28, 0x29, 0x62, 0xeb, 0x09, 0x85, 0xca, 0xf3, 0x8f, 0xab, 0xfa, + 0x17, 0x8f, 0x90, 0xd2, 0x3b, 0x8f, 0x0d, 0xe7, 0x06, 0x0f, 0x6a, 0x3a, 0x8e, 0xde, 0xe6, 0x89, + 0x72, 0xe3, 0x85, 0x79, 0xd8, 0x8f, 0x18, 0xfa, 0x02, 0xc2, 0x3a, 0x0a, 0x2a, 0x5f, 0xab, 0xfe, + 0x81, 0xe8, 0xf3, 0x8f, 0xe9, 0xf9, 0x10, 0xc9, 0x77, 0x6f, 0x72, 0x6b, 0x46, 0xdd, 0x01, 0xd2, + 0x83, 0xba, 0xe6, 0x95, 0x62, 0xf3, 0xe7, 0xaf, 0x6f, 0x66, 0x60, 0xfe, 0x04, 0x84, 0x58, 0xc7, + 0x82, 0x52, 0xdd, 0x8d, 0xf1, 0xfe, 0x98, 0x78, 0xd1, 0xf3, 0x05, 0x7f, 0x95, 0x79, 0xda, 0xeb, + 0xd0, 0x6e, 0x64, 0x2d, 0x61, 0x6c, 0x8f, 0xfc, 0x12, 0x2e, 0xea, 0x89, 0x24, 0xf3, 0xb3, 0x6e, + 0x6f, 0x72, 0x80, 0xfa, 0x8f, 0x34, 0xf7, 0x0f, 0x9f, 0x2e, 0xe2, 0xfd, 0x09, 0x07, 0x00, 0x8f, + 0x97, 0xd0, 0x3b, 0x8e, 0x65, 0xf8, 0x81, 0x89, 0xde, 0xa7, 0x72, 0x74, 0x66, 0xf8, 0x8f, 0xe2, + 0xfd, 0x0c, 0x06, 0x6a, 0x8f, 0xe5, 0xe4, 0x1d, 0x0f, 0x85, 0x1a, 0x8f, 0x32, 0xd6, 0x1c, 0xc0, + 0x4f, 0x62, 0x73, 0x6f, 0x63, 0xdf, 0x8f, 0xcb, 0xce, 0x22, 0x91, 0x2f, 0xf9, 0xcd, 0x00, 0x24, + 0x82, 0x2a, 0xfc, 0xb1, 0x57, 0x61, 0x72, 0xbd, 0xcc, 0x23, 0x73, 0x20, 0xe7, 0x96, 0x53, 0x25, + 0xe6, 0x45, 0x73, 0x65, 0x20, 0x77, 0xe4, 0xb1, 0x6d, 0x65, 0x73, 0xa9, 0xf4, 0x93, 0x73, 0x33, + 0xe2, 0xc0, 0x70, 0x72, 0x6f, 0x62, 0x9f, 0xf9, 0x81, 0xdd, 0xfb, 0x83, 0xf1, 0xfb, 0x84, 0xde, + 0xc9, 0xb7, 0x6c, 0x6c, 0x79, 0xec, 0xde, 0xa1, 0x74, 0x6f, 0x4e, 0xc5, 0x12, 0x61, 0xf5, 0x13, + 0x68, 0xd3, 0x83, 0x58, 0xf8, 0x65, 0x2d, 0x57, 0x6e, 0x6f, 0x2d, 0x64, 0x80, 0x10, 0x64, 0xf5, + 0xb3, 0x63, 0x6c, 0x61, 0x1d, 0xf0, 0x83, 0x32, 0xe2, 0xc3, 0x67, 0x63, 0x63, 0x0a, 0xc4, 0xdf, + 0xb0, 0x5f, 0x43, 0x52, 0xd8, 0xd8, 0x91, 0x45, 0xd1, 0xc6, 0xc0, 0x5f, 0x4e, 0x4f, 0x5f, 0xe8, + 0xc7, 0xd1, 0x4e, 0x49, 0x4e, 0x47, 0x53, 0x18, 0xf7, 0xe9, 0x56, 0x69, 0x73, 0x75, 0x61, 0x6c, + 0x81, 0xd7, 0x98, 0x2e, 0x02, 0xc8, 0x83, 0x84, 0xd9, 0x88, 0x6b, 0xf2, 0xb0, 0x44, 0x45, 0x50, + 0x23, 0xc6, 0x35, 0x41, 0x54, 0x45, 0xbb, 0x81, 0x6b, 0xda, 0xe2, 0x42, 0x4c, 0x4f, 0x43, 0x4b, + 0x2e, 0x69, 0xd5, 0x30, 0x69, 0x66, 0x6e, 0xd2, 0x0f, 0xd5, 0x0d, 0x34, 0x0a, 0x23, 0x20, 0xac, + 0x0f, 0xd7, 0x1c, 0xb5, 0x47, 0x43, 0x43, 0xfc, 0xca, 0x81, 0x20, 0xc8, 0xe0, 0x47, 0x4e, 0x55, + 0x43, 0x5f, 0x5f, 0x73, 0xf5, 0x83, 0xde, 0xca, 0x03, 0xef, 0x83, 0xca, 0xca, 0x31, 0x5f, 0x5f, + 0x29, 0xc4, 0x4d, 0x69, 0x66, 0x20, 0x28, 0xc7, 0xd0, 0x3e, 0x3d, 0x20, 0x34, 0x30, 0x30, 0xd5, + 0xa5, 0x7c, 0x7c, 0xd4, 0xc7, 0x81, 0xd5, 0xc7, 0x44, 0x6c, 0x61, 0x6e, 0x67, 0xcb, 0x0f, 0x64, + 0x04, 0xa4, 0x44, 0x28, 0x44, 0xfe, 0x10, 0x29, 0x97, 0xa3, 0x61, 0x74, 0xbe, 0xc3, 0xd7, 0x65, + 0x5f, 0x5f, 0x28, 0x28, 0x7d, 0xfe, 0x06, 0xdd, 0x12, 0x29, 0xb7, 0x2f, 0x65, 0x6c, 0x80, 0x05, + 0x3f, 0x33, 0x30, 0x31, 0x96, 0x2d, 0x07, 0x9f, 0x07, 0x3b, 0x22, 0x4d, 0x53, 0x9b, 0x0f, 0xa6, + 0x16, 0x81, 0xd1, 0xfd, 0x81, 0xf4, 0xdf, 0x0f, 0x40, 0x01, 0x05, 0xa2, 0x23, 0x73, 0x65, 0xb4, + 0x84, 0x9b, 0xc6, 0x04, 0xe2, 0xa4, 0x28, 0x22, 0x59, 0xfe, 0xb7, 0x3a, 0x20, 0x59, 0x23, 0xc7, + 0x87, 0xd3, 0xf6, 0x0c, 0x8c, 0x83, 0xcb, 0xc8, 0xb4, 0x68, 0x69, 0x73, 0xe8, 0xd4, 0x3f, 0x65, + 0x72, 0x22, 0x5d, 0x12, 0x02, 0x7d, 0x82, 0x57, 0xc6, 0x84, 0x50, 0xc6, 0xbf, 0x20, 0x2f, 0x2a, + 0xd2, 0xfd, 0x0d, 0x93, 0x20, 0x3f, 0xc7, 0x85, 0x2e, 0xfc, 0x8f, 0x8c, 0xd8, 0x04, 0x84, 0x60, + 0xfc, 0x83, 0xf4, 0xf9, 0x07, 0xea, 0x83, 0x50, 0xc0, 0xc5, 0x6c, 0x61, 0x6e, 0x6e, 0x2c, 0xeb, + 0xb5, 0x61, 0x72, 0x74, 0x4f, 0xc6, 0x88, 0x3f, 0xfc, 0x90, 0x62, 0xbd, 0xde, 0xe0, 0x31, 0x33, + 0x31, 0x20, 0x61, 0x70, 0x43, 0xfc, 0xb2, 0x78, 0x69, 0x6d, 0xb9, 0xed, 0x8f, 0x28, 0xec, 0x02, + 0x8b, 0x02, 0xf2, 0x8f, 0x7f, 0xd7, 0x1e, 0x8f, 0x19, 0xd9, 0x02, 0x84, 0x81, 0xcc, 0x82, 0xb4, + 0xe3, 0x8f, 0x2e, 0xd7, 0x28, 0x03, 0xc1, 0x0f, 0x9c, 0x06, 0x81, 0xa7, 0xfb, 0x82, 0xb9, 0xd8, + 0x0b, 0x41, 0x8f, 0xab, 0xd8, 0x26, 0x0f, 0x35, 0x13, 0x07, 0x8b, 0x0f, 0x99, 0x26, 0x0f, 0x1f, + 0x18, 0x87, 0x63, 0xf7, 0x0d, 0x1f, 0x8f, 0xb0, 0xe6, 0x00, 0x86, 0x84, 0xea, 0x0f, 0x0f, 0x3e, + 0x06, 0x7b, 0x0f, 0x89, 0x0c, 0x8f, 0xff, 0xfe, 0x32, 0x8b, 0xf0, 0xfc, 0xaf, 0x64, 0x65, 0xee, + 0xfc, 0x18, 0xd2, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0xe9, 0xfc, 0x89, 0x41, 0xd8, 0x87, 0xd4, 0xfb, + 0x81, 0x2d, 0xf5, 0x83, 0x93, 0xf1, 0xa2, 0x6e, 0x6f, 0xc1, 0xec, 0xc2, 0x65, 0x72, 0x20, 0x62, + 0xeb, 0xe4, 0xb8, 0x64, 0x2e, 0x0a, 0x15, 0xf7, 0x82, 0x33, 0xe6, 0x87, 0xe0, 0xd0, 0x81, 0x05, + 0xf5, 0x86, 0xdb, 0xd0, 0xb2, 0x61, 0x74, 0x69, 0x7d, 0xc4, 0x94, 0x79, 0xb1, 0xbc, 0xc5, 0x6c, + 0x64, 0x65, 0x72, 0xbd, 0xc2, 0x96, 0x73, 0x1f, 0xf2, 0xb7, 0x5a, 0x34, 0x5f, 0xd0, 0xd9, 0x8c, + 0x9d, 0xd3, 0x8f, 0x9d, 0xf7, 0x02, 0x0f, 0xc8, 0x03, 0x00, 0xf5, 0x81, 0xfd, 0xd4, 0x97, 0x6e, + 0xe3, 0xfe, 0x0e, 0xb6, 0x8e, 0xbd, 0xf6, 0x81, 0x6a, 0xd9, 0x8c, 0xea, 0xfe, 0x82, 0xab, 0xdf, + 0x91, 0x6f, 0xb3, 0xeb, 0x85, 0xdf, 0xf3, 0x95, 0x77, 0x62, 0xf8, 0xa3, 0x64, 0x3b, 0x29, 0xd9, + 0x81, 0xfd, 0xfa, 0x82, 0x56, 0xf8, 0x02, 0x06, 0x85, 0xe5, 0xe1, 0xa1, 0x72, 0x65, 0x2a, 0xf8, + 0x82, 0xd3, 0xfa, 0x02, 0xe3, 0xa6, 0x2e, 0x0a, 0xbd, 0xda, 0xa1, 0x68, 0x69, 0x94, 0xd2, 0x89, + 0x54, 0xc8, 0x85, 0xd9, 0xdc, 0x83, 0xe8, 0xf3, 0x83, 0xbc, 0xf7, 0x08, 0x86, 0x83, 0x85, 0xfe, + 0xa1, 0x69, 0x67, 0x66, 0xfb, 0x01, 0xd5, 0x81, 0x8e, 0xef, 0xa2, 0x74, 0x61, 0x0a, 0xc1, 0xb5, + 0x6f, 0x6e, 0x65, 0x31, 0xfe, 0x00, 0xec, 0x8c, 0xc4, 0xfe, 0x8f, 0x8e, 0xf6, 0x15, 0x88, 0xc1, + 0xfd, 0x07, 0xb5, 0x8f, 0xb1, 0xfe, 0x0f, 0x0f, 0xa3, 0x14, 0xaf, 0x69, 0x73, 0x56, 0xfd, 0x06, + 0x8c, 0x43, 0xfa, 0x85, 0x6a, 0xdd, 0x8a, 0x58, 0xf4, 0x92, 0x3b, 0x30, 0xeb, 0x34, 0x6e, 0x65, + 0x77, 0xe3, 0x8b, 0xdc, 0xc1, 0x94, 0x77, 0x35, 0xf2, 0x86, 0xc5, 0xf6, 0x01, 0xad, 0x8c, 0xa3, + 0xf9, 0x11, 0x22, 0xbf, 0x8e, 0xd3, 0xe2, 0x95, 0x29, 0xb3, 0xe0, 0xb2, 0x22, 0x29, 0x20, 0x7e, + 0xfb, 0x07, 0xdd, 0x85, 0x6a, 0xe7, 0x83, 0x98, 0xfc, 0x84, 0x69, 0xe7, 0x1f, 0x3b, 0xa9, 0x20, + 0x82, 0xee, 0xeb, 0x88, 0x2e, 0xd3, 0x03, 0xdd, 0x87, 0x28, 0xd3, 0x0f, 0xac, 0x04, 0x89, 0xcf, + 0xe0, 0x0e, 0xad, 0x03, 0xac, 0x07, 0xdd, 0x08, 0xad, 0x8b, 0xb8, 0xfa, 0x0f, 0x3f, 0x15, 0x8a, + 0x8b, 0xe7, 0x0b, 0x96, 0x23, 0x20, 0x20, 0xbb, 0x03, 0xdd, 0x57, 0x6c, 0x69, 0x64, 0x65, 0x49, + 0xb2, 0x8a, 0x4a, 0xfa, 0xaf, 0x29, 0x3b, 0x3a, 0xfe, 0x05, 0x8f, 0x89, 0xf2, 0x01, 0x8f, 0x60, + 0xfe, 0x05, 0x8f, 0x33, 0xf3, 0x08, 0x0e, 0x67, 0x8f, 0x05, 0xf3, 0x05, 0x82, 0xae, 0xf9, 0xb0, + 0x50, 0x72, 0x65, 0x61, 0xc0, 0xdf, 0x36, 0x34, 0x6b, 0x20, 0x28, 0xc5, 0xe4, 0x06, 0x8f, 0x05, + 0xf3, 0x0e, 0x85, 0x02, 0xd5, 0x0f, 0x5a, 0x0e, 0x8e, 0x23, 0xf3, 0x0e, 0x5a, 0x0f, 0xd2, 0x02, + 0x0f, 0x5a, 0x1c, 0x8e, 0xfc, 0xf0, 0x8f, 0x11, 0xbd, 0x0a, 0x95, 0x7d, 0x1c, 0xbd, 0x0f, 0x00, + 0xee, 0x00, 0x00, +}; + +static unsigned char buf[18830]; + +int main() { + + unsigned long cksum = adler32(0, NULL, 0); + + decompress_lzsa1(compressed, buf); + cksum = adler32(cksum, buf, 18830); + + return cksum == 0xf748269d ? 0 : 1; +} diff --git a/test/val/lzsa2.c b/test/val/lzsa2.c new file mode 100644 index 000000000..5babbb38c --- /dev/null +++ b/test/val/lzsa2.c @@ -0,0 +1,438 @@ +/* + !!DESCRIPTION!! lzsa2 decompression + !!ORIGIN!! cc65 regression tests + !!LICENCE!! BSD 2-clause + !!AUTHOR!! Colin Leroy-Mira +*/ + +#include <zlib.h> +#include <stdio.h> +#include <lzsa.h> + +/* The sample data is the original lz4.h, compressed with: + * lzsa -r -f 1 lz4.h lz4.lzsa1 + * + * We reused lz4.h from the LZ4 test to have a matching adler32 sum. + */ +static const unsigned char compressed[] = { + 0x19, 0xda, 0x2f, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x4c, 0x5a, 0x34, 0x20, 0x2d, 0x20, 0x46, 0x61, + 0x73, 0x74, 0x5a, 0xf8, 0x04, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x20, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0xd9, 0x1a, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x81, 0x38, 0x43, 0x6f, 0x70, 0x79, 0x2a, 0x19, + 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x31, 0x31, 0x2d, 0xd4, 0x39, 0x35, + 0x2c, 0x20, 0x59, 0x61, 0x6e, 0x6e, 0x13, 0x5a, 0x6c, 0x6c, 0x65, 0x74, 0x2e, 0x0a, 0xd6, 0x38, + 0x00, 0x42, 0x53, 0x44, 0x39, 0xac, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x4c, 0x69, + 0x63, 0x65, 0x6e, 0x18, 0x6f, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x48, 0x2e, + 0xb6, 0x01, 0x60, 0x38, 0x6f, 0x75, 0x72, 0x3a, 0x00, 0x5c, 0x13, 0x72, 0x67, 0x2f, 0x6c, 0xdd, + 0x1d, 0x73, 0x2f, 0x62, 0x73, 0x64, 0x2d, 0x92, 0x5b, 0x2e, 0x70, 0x68, 0x70, 0x29, 0xb2, 0x5b, + 0x80, 0x52, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x5d, 0x5a, 0x6e, 0x64, + 0x20, 0xa8, 0x08, 0x69, 0xa7, 0x44, 0xbd, 0x23, 0x08, 0x62, 0x89, 0x59, 0x61, 0x72, 0x79, 0x20, + 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x2c, 0x20, 0x77, 0x3d, 0x08, 0x20, 0xac, 0x23, 0x48, 0x6f, 0xc9, + 0x42, 0xba, 0xf0, 0x6d, 0x6f, 0x48, 0x66, 0x75, 0x4a, 0x61, 0xbc, 0x50, 0x2c, 0x20, 0xd4, 0xf8, + 0x10, 0x65, 0x20, 0x70, 0x65, 0x20, 0x48, 0x74, 0xa2, 0x20, 0xb2, 0x19, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0xb0, 0x30, 0x74, 0x68, 0x01, 0xd2, 0x20, 0x49, 0x66, 0x32, 0x50, 0x6f, 0x77, 0x9d, 0x69, + 0x67, 0xe2, 0x48, 0x6e, 0x81, 0x42, 0xcb, 0xea, 0x73, 0x43, 0xb6, 0x40, 0x19, 0xe9, 0x3a, 0x04, + 0xf6, 0x4f, 0x2a, 0x61, 0x48, 0x73, 0x89, 0x4e, 0x66, 0x68, 0x48, 0x63, 0x8d, 0x00, 0xd2, 0x71, + 0x6d, 0x75, 0x9a, 0x68, 0x72, 0xe6, 0x48, 0x61, 0x50, 0x43, 0xa6, 0x50, 0x61, 0x62, 0x94, 0x01, + 0x65, 0xb4, 0x43, 0x65, 0x79, 0x00, 0x6e, 0x6f, 0x74, 0xdc, 0x09, 0x2c, 0x48, 0x69, 0xc1, 0x49, + 0x6c, 0x14, 0x41, 0xbc, 0x47, 0x88, 0x4b, 0x20, 0x47, 0x6b, 0x6f, 0x61, 0xef, 0x50, 0x63, 0x6c, + 0xae, 0x48, 0x6d, 0x3e, 0x4f, 0x2e, 0x77, 0x02, 0x77, 0x69, 0x6e, 0xea, 0x3f, 0x46, 0x77, 0x41, + 0x14, 0x51, 0x64, 0x75, 0x63, 0x46, 0x74, 0x63, 0x25, 0xee, 0x63, 0x47, 0x74, 0x25, 0x62, 0x99, + 0x45, 0x1a, 0x38, 0x17, 0x64, 0x6f, 0x63, 0x75, 0x48, 0x6e, 0x0a, 0x66, 0x4d, 0x69, 0x2f, 0x72, + 0x29, 0x6f, 0x3d, 0x20, 0x28, 0x6d, 0x6d, 0x20, 0x7f, 0x10, 0x69, 0x61, 0x6c, 0x73, 0x89, 0x64, + 0x51, 0x00, 0x13, 0x43, 0x75, 0x67, 0x14, 0x84, 0xfb, 0xb2, 0x39, 0x54, 0x48, 0x49, 0x53, 0x20, + 0x53, 0x4f, 0x46, 0x54, 0x57, 0x41, 0x52, 0x45, 0x20, 0xa8, 0x19, 0x50, 0x52, 0x4f, 0x56, 0x49, + 0x44, 0x45, 0x44, 0x20, 0x42, 0x59, 0x16, 0x00, 0x38, 0xa4, 0x43, 0x4f, 0x50, 0x59, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x20, 0x48, 0x4f, 0x4c, 0x39, 0x35, 0x52, 0x53, 0x20, 0x41, 0x4e, 0x44, 0xf0, + 0x4e, 0x54, 0x18, 0x17, 0x42, 0x55, 0x54, 0x4f, 0x42, 0xb9, 0x59, 0x02, 0x22, 0x41, 0x53, 0xc3, + 0x2a, 0x22, 0x21, 0x06, 0x40, 0xc6, 0x50, 0x45, 0x58, 0xb8, 0x30, 0x45, 0x53, 0x00, 0x04, 0x00, + 0x59, 0x12, 0x4d, 0x50, 0x4c, 0x49, 0xb0, 0x41, 0x9f, 0x08, 0x52, 0x10, 0x54, 0x49, 0x46, 0x28, + 0x2c, 0x38, 0x2d, 0x4e, 0x43, 0x4c, 0x55, 0x44, 0x08, 0x47, 0xa1, 0x41, 0xbc, 0xbb, 0x20, 0x4e, + 0x4f, 0x54, 0xfa, 0xc6, 0x40, 0xd5, 0x51, 0x49, 0x54, 0xd6, 0x40, 0xab, 0x4a, 0x2c, 0x85, 0x47, + 0xc6, 0x48, 0x20, 0x57, 0x50, 0x20, 0x4d, 0x7c, 0x11, 0x43, 0x48, 0x80, 0x38, 0x41, 0x42, 0x49, + 0x1b, 0x53, 0x54, 0x59, 0x71, 0x08, 0x46, 0x4a, 0x4e, 0x91, 0x48, 0x46, 0x71, 0x42, 0x2b, 0xf8, + 0x7a, 0x41, 0x20, 0x50, 0x41, 0x52, 0x54, 0x49, 0x43, 0x55, 0x4c, 0x00, 0x5a, 0x46, 0x55, 0x52, + 0x50, 0x4f, 0x53, 0x45, 0x20, 0x20, 0x48, 0x44, 0x5c, 0x28, 0x43, 0x50, 0x49, 0x4d, 0x21, 0x49, + 0x2e, 0x7c, 0x41, 0x88, 0x40, 0x57, 0x50, 0x56, 0x45, 0xb5, 0x50, 0x20, 0x53, 0xaf, 0x57, 0x4c, + 0x4c, 0x11, 0x44, 0x43, 0x6f, 0x50, 0x4f, 0x57, 0xaa, 0x49, 0x52, 0x3c, 0x47, 0x11, 0x60, 0xe7, + 0x49, 0x45, 0x56, 0x40, 0x82, 0x52, 0x4c, 0x45, 0x91, 0x43, 0x12, 0x50, 0x44, 0x49, 0x13, 0x52, + 0x43, 0x54, 0x29, 0x27, 0xb1, 0x69, 0x43, 0xbb, 0x41, 0x5b, 0x72, 0x4c, 0x2c, 0x9a, 0x30, 0x53, + 0x50, 0x0a, 0x29, 0x49, 0x61, 0xe8, 0x68, 0x45, 0xf1, 0x41, 0x6a, 0x55, 0x59, 0x2c, 0xa9, 0x40, + 0x67, 0x51, 0x51, 0x55, 0x7e, 0x01, 0x13, 0x59, 0x20, 0x44, 0x41, 0x4d, 0x41, 0x47, 0x1c, 0x6f, + 0x28, 0xe2, 0xf2, 0x09, 0x62, 0x5b, 0x50, 0x43, 0x55, 0x8c, 0x49, 0x4d, 0x44, 0x62, 0xed, 0x18, + 0x53, 0x55, 0x42, 0x53, 0x54, 0x10, 0x08, 0x55, 0x7b, 0x26, 0x20, 0x47, 0x4f, 0x4f, 0x44, 0x89, + 0x68, 0x53, 0x55, 0x68, 0x56, 0xfe, 0x60, 0x93, 0x48, 0x3b, 0x53, 0x73, 0x4f, 0x53, 0xc7, 0x08, + 0x55, 0x43, 0x73, 0x70, 0x44, 0x41, 0xc4, 0x42, 0x81, 0x62, 0x15, 0x61, 0xc7, 0x32, 0x53, 0x3b, + 0xa1, 0x28, 0x42, 0x6b, 0x49, 0xbd, 0x20, 0xd4, 0x70, 0x54, 0x45, 0x57, 0xf0, 0x55, 0x50, 0x40, + 0x63, 0x69, 0x29, 0x0c, 0x69, 0x57, 0xde, 0x61, 0xff, 0x49, 0x41, 0xc2, 0x6b, 0x44, 0x05, 0x00, + 0x62, 0x1e, 0x84, 0xf4, 0xc4, 0x50, 0x45, 0x4f, 0x36, 0x62, 0x6c, 0x75, 0x4c, 0x49, 0x72, 0x60, + 0x47, 0xe8, 0x57, 0x20, 0x61, 0xca, 0xf4, 0x49, 0x4e, 0x6a, 0x41, 0xe7, 0x28, 0x53, 0xc0, 0xe8, + 0x49, 0x47, 0xd9, 0x44, 0x02, 0x61, 0xb3, 0x62, 0x09, 0x47, 0x10, 0x20, 0x68, 0x20, 0x3b, 0x08, + 0x47, 0x30, 0x47, 0x45, 0x8c, 0x4a, 0x45, 0x3d, 0x4a, 0x4f, 0xb7, 0x70, 0x57, 0x49, 0x44, 0x69, + 0x29, 0x43, 0x00, 0x42, 0xdf, 0x4b, 0x49, 0x83, 0x81, 0xff, 0xb4, 0x41, 0x89, 0x4a, 0x55, 0x04, + 0x62, 0x4b, 0x42, 0x26, 0x63, 0x51, 0x8f, 0x46, 0x31, 0x5e, 0x6b, 0x2c, 0x22, 0x40, 0xcc, 0xe8, + 0x46, 0x51, 0x44, 0x56, 0xb9, 0x4e, 0x44, 0xd0, 0x69, 0x50, 0xee, 0x4c, 0x49, 0x4f, 0x64, 0xc1, + 0x75, 0x43, 0x48, 0x82, 0xa4, 0x9d, 0x9a, 0x4e, 0x59, 0x6f, 0x75, 0x20, 0x63, 0x61, 0x6e, 0x61, + 0x80, 0xed, 0xa5, 0xf4, 0x63, 0x74, 0x28, 0x75, 0xa1, 0xfe, 0x99, 0x81, 0x3d, 0x4a, 0x3a, 0x94, + 0xaa, 0x2d, 0xee, 0x18, 0xa6, 0xdc, 0xf9, 0x5e, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0xb2, 0x3a, 0x20, 0x76, 0xa9, 0x73, 0xee, 0x75, 0xa9, 0x67, 0xe1, 0x99, 0x0d, 0x75, 0x62, 0x2e, + 0xff, 0x5f, 0xa1, 0x2f, 0x43, 0x79, 0x61, 0x6e, 0x34, 0x39, 0x37, 0x33, 0x2f, 0x6c, 0x7a, 0x34, + 0xc3, 0x28, 0x70, 0x1e, 0xa1, 0x64, 0xa2, 0xe3, 0xaa, 0x57, 0x75, 0x6d, 0xc8, 0x48, 0x72, 0xab, + 0x00, 0xb4, 0x5b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0xc1, 0x43, 0xde, 0x3b, 0x0c, 0x2f, + 0x23, 0x21, 0x42, 0xbc, 0xb8, 0xae, 0x63, 0x0a, 0x2a, 0x2f, 0x0a, 0x23, 0x70, 0x72, 0x61, 0x67, + 0x6d, 0x61, 0x20, 0x8e, 0xf9, 0xa5, 0x63, 0x65, 0x0a, 0x0a, 0x23, 0x69, 0x66, 0x20, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x3a, 0x28, 0x5f, 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0xe1, 0x99, 0x29, 0x0a, + 0x65, 0x78, 0xe8, 0xed, 0xb9, 0x6e, 0x20, 0x22, 0x43, 0x22, 0x20, 0x7b, 0x0a, 0x23, 0x65, 0x6e, + 0xed, 0x56, 0x92, 0x0a, 0x0a, 0x55, 0x51, 0x2a, 0x20, 0xb5, 0xb6, 0x2e, 0x68, 0xe4, 0x5f, 0x9f, + 0x73, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0xd4, 0x4e, 0x50, 0x66, 0x75, 0xa3, 0xa3, 0xed, 0x61, + 0x8b, 0x2c, 0xf8, 0x40, 0x2d, 0x08, 0x76, 0x35, 0x01, 0x7b, 0x60, 0x6c, 0x6c, 0x20, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0xde, 0xf8, 0x72, 0x6f, 0x6c, 0x4a, 0x6f, 0xb9, 0x48, 0x67, 0x6e, 0xac, + 0x6d, 0xe1, 0xc9, 0x68, 0x2a, 0x8a, 0x40, 0x70, 0x69, 0x79, 0xb9, 0x40, 0x70, 0x32, 0x65, 0x64, + 0x30, 0x67, 0x65, 0xb1, 0x20, 0x8a, 0x74, 0xd0, 0xa6, 0x41, 0x71, 0x39, 0x2d, 0x6f, 0x70, 0x90, + 0x40, 0x01, 0x4f, 0x65, 0x92, 0x41, 0x49, 0x08, 0x64, 0x09, 0x48, 0x61, 0x44, 0x01, 0x20, 0x26, + 0x41, 0x8b, 0x73, 0x6e, 0x67, 0x9e, 0x49, 0x66, 0xad, 0x12, 0x65, 0x20, 0x87, 0xd0, 0x9f, 0x51, + 0x29, 0x2c, 0xa0, 0x42, 0x70, 0x63, 0x5c, 0x74, 0x6c, 0x65, 0x60, 0x60, 0xb5, 0x92, 0x62, 0x72, + 0xd3, 0x5b, 0x09, 0x68, 0x41, 0xa8, 0x91, 0x69, 0x74, 0xdd, 0xd3, 0x91, 0x77, 0x6e, 0xb0, 0x69, + 0x6d, 0x69, 0x48, 0x2c, 0x62, 0x20, 0x6d, 0x48, 0x61, 0x9b, 0x82, 0x24, 0x42, 0x0a, 0x43, 0xaa, + 0x51, 0x2e, 0x68, 0x73, 0xb1, 0x73, 0x74, 0xdf, 0x78, 0x69, 0x2e, 0xb0, 0x62, 0xec, 0x07, 0xff, + 0x0d, 0x70, 0x0a, 0x2a, 0x01, 0x48, 0x56, 0x42, 0x62, 0xe0, 0x4f, 0x0a, 0xce, 0x0d, 0x62, 0x54, + 0x64, 0x65, 0x42, 0x2e, 0xb1, 0x5f, 0x56, 0xef, 0xbc, 0xa1, 0xa4, 0x99, 0x1f, 0x5f, 0x4d, 0x41, + 0x4a, 0x1c, 0x01, 0xfd, 0x0a, 0x31, 0xb2, 0x2f, 0x2a, 0xdd, 0xa1, 0x50, 0x20, 0x62, 0x01, 0x51, + 0x61, 0x6b, 0x04, 0x64, 0xd9, 0x92, 0x66, 0x61, 0x17, 0x41, 0x2e, 0x69, 0x67, 0x62, 0x4f, 0x20, + 0xb8, 0xf2, 0x00, 0xf4, 0x49, 0x4e, 0xef, 0x37, 0x80, 0xf3, 0xf9, 0xe8, 0x77, 0x68, 0x6e, 0xd4, + 0x4e, 0x2d, 0xaf, 0x4f, 0x29, 0xae, 0x70, 0x61, 0x70, 0x84, 0xb1, 0x69, 0x6c, 0xde, 0x87, 0x61, + 0x0b, 0x47, 0x62, 0xff, 0x45, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0xf1, 0x74, 0x77, 0x71, + 0x73, 0x2c, 0x03, 0x50, 0x67, 0x2d, 0xce, 0x11, 0x78, 0x65, 0xa5, 0x21, 0x9a, 0x4d, 0x64, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6e, 0x47, 0xb2, 0xf1, 0x00, 0x99, 0x4e, 0x55, 0x4d, 0x42, 0xe9, + 0xba, 0x4f, 0x28, 0x00, 0x3a, 0x1e, 0x2a, 0x31, 0x30, 0x30, 0x57, 0x20, 0x2b, 0x2b, 0xa3, 0x04, + 0x47, 0x68, 0xb3, 0x51, 0x29, 0x0a, 0x31, 0x03, 0x6c, 0x76, 0x75, 0x7f, 0xbf, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x20, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x29, 0x3b, 0x33, 0x15, 0x7a, 0x0f, 0x54, + 0x75, 0x6e, 0x8e, 0x92, 0x70, 0x61, 0xeb, 0x61, 0x8a, 0x67, 0x2a, 0xff, 0x10, 0xa4, 0xbb, 0x63, + 0x2c, 0xb8, 0x0e, 0x4d, 0x45, 0x4d, 0xbc, 0xf0, 0x59, 0x5f, 0xa1, 0xe5, 0x3f, 0x32, 0x20, 0x3a, + 0x8b, 0x4d, 0xfc, 0x88, 0xa1, 0xb4, 0x68, 0x61, 0x44, 0xa3, 0xcd, 0xc7, 0x79, 0x75, 0x6c, 0x61, + 0x20, 0x3a, 0x20, 0x4e, 0x2d, 0x3e, 0x32, 0x5e, 0x4e, 0x20, 0x42, 0x79, 0x74, 0x2e, 0x99, 0x2f, + 0x28, 0x65, 0x78, 0x61, 0x6d, 0x67, 0x09, 0x73, 0x32, 0x68, 0x31, 0xfe, 0x00, 0x20, 0xd0, 0x18, + 0x4b, 0x42, 0x3b, 0xaa, 0xea, 0x32, 0xe8, 0x34, 0x29, 0x20, 0xea, 0x36, 0x32, 0x36, 0x34, 0x42, + 0x4c, 0x32, 0xdd, 0xe9, 0x4d, 0xbb, 0x65, 0x74, 0x63, 0x2e, 0x29, 0xff, 0x9a, 0x91, 0x6e, 0x63, + 0xce, 0xea, 0x73, 0x4f, 0x6d, 0x8e, 0x3c, 0xb2, 0x69, 0x6d, 0x89, 0x97, 0x65, 0x73, 0xb4, 0x80, + 0xaa, 0x72, 0xcc, 0x60, 0xab, 0x0a, 0xaa, 0x82, 0xc4, 0x5a, 0x4f, 0x64, 0xcd, 0xa2, 0xff, 0xb3, + 0x45, 0xc9, 0xa3, 0x90, 0x00, 0x0c, 0x60, 0x18, 0x91, 0x64, 0x75, 0x35, 0x29, 0x6f, 0x3c, 0x89, + 0x63, 0x8a, 0xa9, 0x65, 0xfa, 0x0f, 0x52, 0x63, 0x74, 0x24, 0x08, 0x44, 0x59, 0x5c, 0x61, 0x75, + 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0xdf, 0xa1, 0xa9, 0x5a, 0x0b, 0x31, 0x34, 0x2c, 0x1c, 0x41, + 0x52, 0x91, 0x4b, 0x42, 0xe0, 0x50, 0x68, 0x69, 0xd0, 0x91, 0x20, 0x6e, 0xbb, 0x66, 0x89, 0x6c, + 0xcc, 0xa2, 0xf7, 0x77, 0x61, 0x54, 0x49, 0x6f, 0x55, 0x08, 0x74, 0x5c, 0x4f, 0x20, 0x78, 0x38, + 0x36, 0x20, 0x4c, 0x31, 0xad, 0x8f, 0x0a, 0x2d, 0x28, 0x67, 0xb9, 0x41, 0xab, 0x6f, 0x0a, 0x39, + 0xfe, 0x15, 0x72, 0x53, 0x69, 0xb4, 0x96, 0x20, 0x46, 0x4d, 0x67, 0x39, 0xff, 0x11, 0x87, 0xb5, + 0x0f, 0x66, 0xd4, 0x54, 0x5f, 0x64, 0x1f, 0x51, 0x28, 0x63, 0xb9, 0xaa, 0x74, 0x7f, 0xb5, 0x72, + 0x2a, 0xb9, 0xf1, 0x2d, 0x2c, 0xa1, 0xe4, 0xd1, 0x52, 0x74, 0x2c, 0x28, 0x25, 0x40, 0x83, 0x34, + 0x7a, 0x65, 0x81, 0x19, 0x6d, 0x61, 0x78, 0x44, 0x17, 0x02, 0x56, 0x29, 0x3b, 0xa5, 0x41, 0xae, + 0x47, 0xa3, 0x0f, 0x60, 0x93, 0xe8, 0x66, 0x47, 0xa5, 0x0c, 0xa7, 0xe2, 0xe4, 0x47, 0xa1, 0x63, + 0x07, 0x5f, 0x84, 0x11, 0x4f, 0x0a, 0x3e, 0xcd, 0x8c, 0x29, 0x52, 0x56, 0x20, 0x43, 0xce, 0x60, + 0x53, 0x4f, 0x27, 0x4e, 0x10, 0x9b, 0x27, 0x20, 0x62, 0xf0, 0x77, 0x10, 0x66, 0x72, 0xa5, 0xe0, + 0x2e, 0x06, 0x4a, 0x27, 0xc9, 0x64, 0x47, 0x91, 0x61, 0x6c, 0xec, 0x6b, 0x31, 0x64, 0x79, 0x81, + 0xdb, 0xe0, 0xaa, 0x61, 0x2d, 0x4a, 0x27, 0x01, 0x4d, 0x27, 0xce, 0xa3, 0xb5, 0x6c, 0x41, 0x01, + 0x20, 0x47, 0x05, 0x2a, 0x56, 0x27, 0x2e, 0x89, 0x86, 0x02, 0x82, 0xff, 0xd8, 0xb1, 0x67, 0x75, + 0x9c, 0x95, 0x6e, 0x74, 0xd1, 0xed, 0x1a, 0x73, 0x75, 0x63, 0x63, 0xa5, 0x57, 0x69, 0x66, 0xc5, + 0x7f, 0x04, 0x20, 0x3e, 0x3d, 0x71, 0x70, 0x42, 0x6f, 0x2d, 0x77, 0x64, 0x28, 0x98, 0x15, 0x4c, + 0x29, 0xa4, 0x51, 0x49, 0x74, 0x6e, 0x20, 0x30, 0x20, 0x72, 0x1f, 0x41, 0x3e, 0xb1, 0x61, 0x73, + 0x46, 0x69, 0x2c, 0xb5, 0xa1, 0xea, 0x06, 0x89, 0x27, 0xb2, 0x00, 0x4b, 0x62, 0x8e, 0xa1, 0xda, + 0x82, 0xad, 0x86, 0x60, 0xd7, 0x8a, 0x74, 0xaf, 0x45, 0xc8, 0x8b, 0x66, 0xad, 0x7b, 0x86, 0x25, + 0xa2, 0xd1, 0x17, 0x77, 0x6e, 0x6f, 0x93, 0x67, 0xff, 0x0d, 0x45, 0x03, 0x89, 0x20, 0xc0, 0x82, + 0xd4, 0xa2, 0x57, 0x6d, 0x69, 0x06, 0x50, 0x64, 0x67, 0xac, 0xa3, 0xcf, 0xb2, 0xa7, 0x9e, 0x42, + 0x20, 0xb1, 0x6f, 0x70, 0xe0, 0xad, 0x49, 0x69, 0x87, 0x71, 0x64, 0x69, 0xd5, 0xbb, 0x6c, 0x79, + 0x2a, 0xd5, 0xc6, 0x47, 0x8e, 0x41, 0xd2, 0x61, 0x64, 0x62, 0xef, 0x70, 0x7a, 0x65, 0x86, 0x44, + 0x6a, 0x4a, 0x41, 0x4c, 0x82, 0xf2, 0x90, 0x99, 0x65, 0x71, 0x75, 0x65, 0x6e, 0xfc, 0x97, 0x65, + 0x9b, 0x83, 0x7c, 0x00, 0x7f, 0x43, 0xd2, 0xb3, 0x6e, 0x6f, 0x8c, 0x74, 0x69, 0x64, 0xa3, 0x89, + 0x54, 0xa1, 0x2e, 0x47, 0xab, 0xa9, 0x6e, 0xea, 0x7a, 0xa1, 0x6c, 0x72, 0x72, 0x69, 0x2f, 0xa1, + 0xaa, 0x69, 0xa9, 0x73, 0x8c, 0x67, 0x57, 0x5f, 0xa0, 0x5c, 0xe9, 0x6e, 0x62, 0x34, 0x26, 0x0a, + 0x46, 0x14, 0x44, 0xde, 0x87, 0x10, 0x2f, 0x87, 0x2a, 0x2e, 0x89, 0x20, 0x4a, 0x68, 0x4d, 0x62, + 0x61, 0x52, 0x70, 0x70, 0x70, 0xf6, 0x62, 0x02, 0xa6, 0xfe, 0x09, 0x84, 0x06, 0x5e, 0xbf, 0x41, + 0x58, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0xbf, 0xa7, 0xf9, + 0x3c, 0x94, 0x20, 0x3a, 0xcd, 0xb2, 0x6f, 0x72, 0xea, 0x9c, 0x89, 0x74, 0x62, 0x84, 0xfe, 0xd0, + 0x55, 0x6f, 0x66, 0x67, 0x46, 0x15, 0x8b, 0x28, 0xc6, 0xa4, 0xaf, 0x2b, 0x97, 0x62, 0x65, 0x88, + 0x9a, 0x4e, 0x29, 0xa2, 0xa2, 0x0d, 0xf0, 0x75, 0x72, 0x6b, 0x3a, 0xa8, 0xac, 0x6e, 0xef, 0x05, + 0x94, 0x6f, 0x66, 0x32, 0x63, 0xfc, 0x61, 0xcd, 0x63, 0x40, 0x47, 0x9e, 0x7e, 0x60, 0xda, 0x48, + 0x63, 0xde, 0xf0, 0x73, 0x61, 0x81, 0x65, 0x52, 0x3c, 0x3d, 0x5a, 0x68, 0x4f, 0xd5, 0x53, 0x70, + 0x75, 0x58, 0x46, 0xa1, 0x06, 0xff, 0x61, 0xd3, 0x89, 0x30, 0x63, 0xa7, 0xc5, 0xef, 0xbf, 0x3f, + 0x61, 0x69, 0x6c, 0x73, 0x0a, 0x0a, 0x2d, 0xaf, 0xa6, 0x95, 0xa7, 0xf6, 0x4a, 0x00, 0x55, 0x61, + 0x18, 0x43, 0x59, 0x01, 0x30, 0x63, 0x69, 0x53, 0x63, 0xf4, 0x66, 0xff, 0x02, 0x47, 0xcf, 0x2c, + 0xa4, 0x7e, 0x61, 0x22, 0x66, 0xbf, 0x47, 0xb4, 0xee, 0x46, 0xc1, 0x83, 0x79, 0x94, 0x69, 0x6e, + 0x9f, 0xf8, 0x66, 0x1b, 0x67, 0xbb, 0x07, 0x77, 0x2e, 0x0a, 0xbf, 0xf2, 0x09, 0x4f, 0x64, 0x88, + 0x63, 0xba, 0x47, 0x98, 0xa7, 0x67, 0xb5, 0x47, 0x50, 0x7a, 0x67, 0xaf, 0x4f, 0x49, 0x50, 0xbf, + 0x86, 0x28, 0x68, 0x6c, 0x6c, 0x89, 0x67, 0xda, 0x9c, 0x00, 0x5b, 0x1d, 0x75, 0x67, 0x68, 0x2c, + 0x7e, 0xaa, 0x64, 0x6b, 0x70, 0x77, 0x69, 0xd3, 0xa3, 0xf8, 0xaa, 0x83, 0x78, 0x6b, 0x6f, 0x54, + 0x01, 0xa8, 0x48, 0x20, 0x7f, 0x68, 0x72, 0x61, 0x84, 0xfc, 0x5f, 0x27, 0x28, 0x3c, 0x30, 0x29, + 0x2e, 0x96, 0x62, 0xda, 0xa6, 0xbd, 0x62, 0x71, 0x73, 0x74, 0xfd, 0x6a, 0x6d, 0xc5, 0xa9, 0x64, + 0x21, 0x8a, 0x63, 0xf8, 0x3d, 0xe8, 0x6d, 0x82, 0x33, 0x81, 0xdf, 0x1c, 0xa7, 0x66, 0x42, 0x47, + 0x91, 0x46, 0x7e, 0x42, 0x88, 0x66, 0xd2, 0xa9, 0x61, 0xff, 0x9b, 0x49, 0x67, 0x43, 0xb5, 0x76, + 0x65, 0x3d, 0x47, 0x89, 0x2f, 0xa7, 0x6f, 0x99, 0xab, 0x69, 0x7c, 0x45, 0x8f, 0x48, 0x61, 0xc8, + 0x82, 0xbe, 0x94, 0xa7, 0xcd, 0x0c, 0xa9, 0x76, 0x23, 0xa1, 0x8c, 0xfc, 0x40, 0x38, 0x10, 0x78, + 0x70, 0x81, 0xbd, 0x54, 0x82, 0xb4, 0x5a, 0x0b, 0x63, 0x6c, 0x75, 0x0c, 0x42, 0x63, 0x50, 0x69, + 0x63, 0xbe, 0xb4, 0x75, 0x73, 0xee, 0x5f, 0x47, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x1d, + 0xaf, 0x74, 0xfc, 0x0e, 0x65, 0xdd, 0xa7, 0xf8, 0x0e, 0x47, 0xdf, 0x10, 0x37, 0x69, 0x6e, 0x1b, + 0x82, 0x08, 0xa7, 0xdf, 0x9b, 0x16, 0x99, 0x2c, 0x41, 0x64, 0x76, 0x61, 0x6e, 0xc5, 0xa7, 0xdf, + 0x99, 0x1a, 0xa6, 0xde, 0x17, 0x87, 0xca, 0x61, 0x5e, 0x53, 0x49, 0x5a, 0x45, 0x2c, 0x1b, 0x2f, + 0x30, 0x78, 0x37, 0x45, 0x30, 0xa4, 0xbc, 0xef, 0xa0, 0xf8, 0xf8, 0x6d, 0x31, 0x31, 0x33, 0x20, + 0x39, 0x32, 0x39, 0x20, 0x32, 0x85, 0x55, 0x47, 0xb7, 0x60, 0x9b, 0x43, 0x4f, 0x4d, 0x85, 0x97, + 0xba, 0x42, 0x4f, 0x55, 0x4e, 0x44, 0x28, 0x69, 0x73, 0xf9, 0x39, 0x81, 0xae, 0x89, 0x28, 0xda, + 0xec, 0xb1, 0x69, 0x67, 0xf4, 0x2e, 0x29, 0x61, 0xf7, 0x3e, 0x20, 0x47, 0x7e, 0xaf, 0xa9, 0x3f, + 0x15, 0x56, 0x3a, 0x20, 0xd3, 0xe8, 0x2b, 0x05, 0xa1, 0x3a, 0x2f, 0x32, 0x35, 0x35, 0x8d, 0x40, + 0x80, 0xab, 0x29, 0x9b, 0x87, 0xd9, 0x68, 0xa6, 0xda, 0x9e, 0xac, 0x50, 0xba, 0xa3, 0xfc, 0x14, + 0x82, 0xfb, 0xb1, 0x69, 0x6d, 0xa7, 0x2a, 0x42, 0xbc, 0x83, 0x08, 0x42, 0x53, 0x87, 0x63, 0xf4, + 0x41, 0xde, 0x6e, 0x79, 0x54, 0x8a, 0x69, 0xfc, 0xa6, 0x70, 0x22, 0x77, 0x56, 0x82, 0x94, 0xf8, + 0x17, 0x61, 0x73, 0x65, 0x22, 0xa1, 0x2b, 0x81, 0xef, 0x5c, 0x48, 0x6f, 0x6f, 0x63, 0x52, 0x84, + 0xf8, 0x87, 0xd3, 0x5b, 0xa9, 0x69, 0xaf, 0xc5, 0x97, 0x29, 0x0a, 0x8c, 0xee, 0x93, 0x69, 0x6d, + 0x20, 0xa2, 0x7a, 0x38, 0xa1, 0x55, 0x82, 0xab, 0xf1, 0x84, 0xe4, 0xa6, 0xd9, 0x3e, 0x43, 0xd6, + 0x40, 0xa9, 0x89, 0x72, 0x4c, 0x82, 0xbf, 0x7b, 0xa7, 0x6c, 0xad, 0xaf, 0x73, 0x9a, 0x12, 0x7f, + 0x4d, 0x61, 0x63, 0x72, 0x6f, 0x95, 0xad, 0x49, 0x29, 0x94, 0xa4, 0x80, 0xa6, 0x7d, 0x20, 0x42, + 0x97, 0x43, 0x5f, 0x53, 0x69, 0x6c, 0xb3, 0x08, 0x2d, 0xa9, 0x6d, 0xfb, 0x2e, 0x82, 0xdb, 0x44, + 0xa3, 0xb1, 0x28, 0x73, 0x99, 0xb3, 0x4f, 0x6b, 0x74, 0x43, 0xc7, 0xa4, 0xbc, 0xf5, 0x46, 0x8a, + 0x48, 0x4e, 0x14, 0x65, 0xc8, 0x87, 0x2a, 0xe6, 0x05, 0xa6, 0xdb, 0x07, 0x81, 0x8c, 0xb3, 0x65, + 0x6e, 0xc3, 0x6b, 0x47, 0x3d, 0x61, 0xf1, 0x87, 0xce, 0xb4, 0xb7, 0x72, 0x63, 0xe5, 0x0f, 0x63, + 0x99, 0x86, 0xdc, 0x12, 0xef, 0x6d, 0x87, 0xfa, 0x48, 0x87, 0xd8, 0x71, 0x66, 0x08, 0x65, 0x26, + 0x43, 0x7b, 0x67, 0x21, 0xfd, 0x03, 0x87, 0x90, 0xac, 0xaa, 0x2c, 0xf2, 0x64, 0x0b, 0x46, 0x3e, + 0xbd, 0x0e, 0x74, 0x6f, 0x6f, 0xe2, 0x48, 0x28, 0x32, 0x47, 0x7a, 0xa8, 0x89, 0x29, 0xf3, 0x82, + 0xba, 0x3d, 0x47, 0x18, 0x21, 0x5b, 0x45, 0x25, 0x87, 0xd9, 0xeb, 0x61, 0xc2, 0x87, 0xdc, 0x19, + 0xaa, 0x53, 0x96, 0x00, 0x7e, 0x67, 0x8d, 0xa2, 0xac, 0x0a, 0x6b, 0x74, 0x4a, 0xb3, 0x77, 0x73, + 0x42, 0x68, 0x65, 0x52, 0xab, 0x63, 0xe9, 0x74, 0x68, 0x22, 0x2a, 0x09, 0x63, 0x6b, 0x72, 0x33, + 0x69, 0x22, 0x6e, 0xa9, 0x63, 0x8c, 0xf6, 0x86, 0x5d, 0x4c, 0x65, 0x44, 0xab, 0x72, 0x83, 0xbc, + 0x47, 0xd7, 0x64, 0xa7, 0xa3, 0xea, 0x80, 0x65, 0x3b, 0x02, 0xa7, 0x51, 0xdc, 0x46, 0x90, 0xb4, + 0x73, 0x6f, 0x95, 0x21, 0x41, 0x51, 0x44, 0xba, 0xa7, 0xad, 0x3b, 0x85, 0xf6, 0xa4, 0xc5, 0x0e, + 0xb1, 0x74, 0x72, 0xae, 0x70, 0x2d, 0x6f, 0x01, 0x29, 0x2e, 0x78, 0xa2, 0x40, 0x82, 0xc9, 0xbb, + 0xa3, 0x89, 0x91, 0x74, 0x75, 0xe5, 0xf5, 0x85, 0x47, 0x89, 0x65, 0xab, 0x33, 0x83, 0x85, 0x42, + 0xbe, 0x74, 0x76, 0x65, 0x20, 0x84, 0x5d, 0x5b, 0x83, 0x8e, 0x8a, 0x72, 0xdc, 0x7e, 0x81, 0xe2, + 0x79, 0x1a, 0x2b, 0x7e, 0x33, 0x25, 0x84, 0xa4, 0xf5, 0xa5, 0xc9, 0x5c, 0x4f, 0x6e, 0x3e, 0x83, + 0xc0, 0x39, 0xbf, 0x22, 0x31, 0x22, 0xd0, 0x66, 0x65, 0xbb, 0x40, 0x5f, 0x51, 0x67, 0x75, 0x06, + 0x67, 0xb3, 0xec, 0x63, 0xe3, 0x6a, 0x56, 0xff, 0x8a, 0x73, 0x79, 0x8c, 0x30, 0xd7, 0x18, 0x8b, + 0x62, 0xb6, 0xb2, 0x6c, 0x61, 0xe9, 0xa0, 0x50, 0x62, 0x79, 0x91, 0xb1, 0x43, 0x43, 0x7b, 0xb2, + 0x52, 0x41, 0x75, 0x76, 0xb9, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0xf8, 0xbb, 0xb3, + 0x65, 0x65, 0x48, 0xb5, 0x63, 0x29, 0xaa, 0x96, 0xa3, 0x7f, 0x8e, 0x2e, 0xf8, 0xfb, 0x67, 0x21, + 0x8f, 0x20, 0xaf, 0x3a, 0x25, 0x06, 0x74, 0x67, 0x45, 0xa1, 0x9f, 0xa0, 0x87, 0xb5, 0xd7, 0x89, + 0x5f, 0x94, 0x91, 0x53, 0x74, 0xaf, 0xdd, 0x87, 0xac, 0x47, 0x87, 0xae, 0xc5, 0x40, 0xaa, 0xaa, + 0x6a, 0x44, 0x20, 0xed, 0xa4, 0x9c, 0x8c, 0x20, 0x7a, 0x5a, 0x81, 0x9d, 0x87, 0xa2, 0x98, 0x86, + 0x9f, 0x2d, 0x71, 0x73, 0x70, 0xed, 0x63, 0x74, 0x81, 0xa7, 0x47, 0xb1, 0x5d, 0x4a, 0x73, 0x92, + 0x64, 0x62, 0x94, 0x55, 0x73, 0xed, 0x82, 0xad, 0x74, 0x55, 0x6f, 0x66, 0x79, 0x42, 0xca, 0xb1, + 0x6b, 0x6e, 0x97, 0x29, 0x68, 0xeb, 0x70, 0x6d, 0x75, 0xfb, 0x45, 0xac, 0x86, 0x9b, 0xa7, 0xc1, + 0xe8, 0xea, 0x2c, 0x82, 0x46, 0x00, 0x06, 0x82, 0x7d, 0xbc, 0x49, 0x20, 0x9d, 0x94, 0x38, 0x2d, + 0x86, 0x8a, 0x62, 0xab, 0x79, 0x81, 0xc6, 0xa2, 0x9f, 0x47, 0x44, 0x49, 0x4b, 0x6d, 0xd6, 0x42, + 0x9b, 0x70, 0x79, 0x70, 0x77, 0x42, 0x44, 0x8f, 0x29, 0x09, 0x0e, 0xb5, 0x6e, 0x2c, 0xe7, 0x43, + 0xb9, 0xa9, 0x61, 0xa8, 0x89, 0x82, 0x66, 0x4c, 0x2a, 0x4f, 0x49, 0x27, 0x69, 0x67, 0xea, 0xc7, + 0x66, 0x39, 0x47, 0x37, 0x85, 0x82, 0x29, 0x06, 0x67, 0x8a, 0xe2, 0x57, 0x20, 0x28, 0x9c, 0x77, + 0x2c, 0x20, 0x08, 0xfe, 0x09, 0x86, 0xe2, 0x67, 0x09, 0xf1, 0x24, 0x4c, 0x64, 0xd1, 0x67, 0x0e, + 0xb2, 0x52, 0x65, 0x87, 0x6e, 0xac, 0x65, 0x6c, 0x70, 0x6f, 0x67, 0xe8, 0x89, 0x2c, 0xf7, 0x34, + 0x46, 0x13, 0x64, 0x12, 0x6b, 0x73, 0x76, 0xa3, 0x10, 0x02, 0x9d, 0x94, 0x70, 0x6f, 0x2f, 0x83, + 0x9a, 0x79, 0x87, 0x6d, 0x79, 0x87, 0x79, 0xfa, 0x03, 0x87, 0xc2, 0x59, 0x87, 0x79, 0x1e, 0x8a, + 0x74, 0x8f, 0x8f, 0x74, 0x90, 0x76, 0xa7, 0xab, 0xd3, 0xb3, 0x65, 0x69, 0x4d, 0xd2, 0x46, 0x3a, + 0xa5, 0x4a, 0xa1, 0x48, 0xad, 0x08, 0x69, 0x46, 0x7e, 0xa7, 0xa0, 0x85, 0x43, 0x81, 0x46, 0x9a, + 0x93, 0x69, 0x66, 0x9b, 0x9f, 0x87, 0x50, 0x5a, 0x8d, 0x0a, 0xd1, 0x89, 0x66, 0xb9, 0x52, 0xa7, + 0xe3, 0x39, 0x45, 0x9d, 0x92, 0x6c, 0x65, 0xf6, 0xa3, 0x3f, 0xc8, 0x47, 0x03, 0x0f, 0x87, 0xb1, + 0x30, 0x8f, 0x2a, 0x81, 0xa0, 0x50, 0x50, 0x74, 0x14, 0x8e, 0x3a, 0xe3, 0xd6, 0xa5, 0x8d, 0xa4, + 0x66, 0xa3, 0xa9, 0x69, 0x2b, 0x62, 0xed, 0x84, 0xf0, 0x1a, 0xbe, 0x61, 0x6e, 0x79, 0xaa, 0xf6, + 0x41, 0x1b, 0xab, 0x65, 0x0e, 0x67, 0xa4, 0x62, 0x57, 0x74, 0x6f, 0x54, 0x43, 0x92, 0x27, 0xfe, + 0xbf, 0x08, 0x4e, 0x65, 0x77, 0x19, 0x1a, 0xa7, 0xc3, 0x69, 0x95, 0x6f, 0x6c, 0xf4, 0xaf, 0x2e, + 0xd9, 0xf7, 0xb7, 0x4e, 0x62, 0xab, 0x73, 0xa7, 0xae, 0x7a, 0x67, 0x4f, 0x0a, 0xa7, 0x79, 0xfe, + 0x16, 0x86, 0x0d, 0x87, 0xfb, 0x70, 0xa7, 0x8f, 0x9e, 0x0e, 0x05, 0x36, 0x66, 0xa2, 0x23, 0x47, + 0x72, 0x6e, 0x87, 0x14, 0x3d, 0xb7, 0x64, 0x65, 0xc7, 0xd2, 0xa9, 0x6f, 0x47, 0x89, 0x69, 0xea, + 0x44, 0xa7, 0x5c, 0x55, 0x26, 0x84, 0x28, 0x9e, 0x62, 0x76, 0x8a, 0x66, 0xb6, 0xb7, 0x75, 0x6e, + 0xa1, 0xa3, 0xa3, 0x8a, 0xc8, 0xa7, 0x70, 0xf1, 0x09, 0x67, 0x3f, 0x87, 0xa3, 0x2a, 0xa6, 0xa3, + 0x79, 0xb5, 0x69, 0x6e, 0x05, 0x81, 0xba, 0xbf, 0x94, 0x64, 0x73, 0x30, 0x47, 0x9e, 0x6a, 0xaf, + 0x29, 0xe2, 0xfa, 0x6d, 0xaf, 0x44, 0x04, 0x89, 0x87, 0x5b, 0xfd, 0x02, 0xa2, 0x3e, 0x6b, 0x73, + 0xe2, 0x47, 0xdc, 0x1c, 0xa0, 0xa3, 0xf4, 0x69, 0x6e, 0x81, 0x77, 0xd0, 0x66, 0x8d, 0x87, 0x3a, + 0x2b, 0x84, 0xc6, 0xea, 0x6e, 0xaf, 0x3a, 0xa5, 0x75, 0x01, 0xbd, 0x82, 0xa8, 0x85, 0x4d, 0xa6, + 0x85, 0xfe, 0xa7, 0xe3, 0x30, 0x8a, 0x66, 0x84, 0x65, 0x8a, 0x72, 0x6c, 0x41, 0xd9, 0x44, 0x05, + 0x87, 0x47, 0x67, 0x47, 0x33, 0x4b, 0x93, 0x49, 0x74, 0x02, 0xa1, 0x1c, 0xe8, 0x8f, 0x74, 0x44, + 0x1c, 0x81, 0x90, 0x87, 0x8c, 0xe9, 0x47, 0xc6, 0x40, 0xba, 0x48, 0x6f, 0x77, 0xed, 0xe0, 0x8a, + 0x2c, 0xeb, 0x9c, 0x09, 0x64, 0x6f, 0x65, 0x04, 0x86, 0xdf, 0xd7, 0xa1, 0x47, 0x84, 0x99, 0xcd, + 0x44, 0x4a, 0x86, 0xcc, 0x00, 0xd7, 0x20, 0xe9, 0x6e, 0xa3, 0xdf, 0xe2, 0xa5, 0x08, 0x45, 0x6a, + 0x66, 0x42, 0x8f, 0x28, 0x90, 0xcc, 0xa4, 0xa5, 0x20, 0x47, 0x8b, 0xaa, 0x55, 0xe3, 0x71, 0x67, + 0xef, 0x83, 0x1e, 0xb7, 0x51, 0x72, 0x75, 0x47, 0x89, 0x64, 0x0b, 0xe8, 0x76, 0x00, 0x65, 0xa3, + 0x42, 0x00, 0xc4, 0x41, 0x9f, 0x4b, 0x28, 0xa7, 0x74, 0x74, 0x6f, 0x1b, 0xa3, 0x5e, 0x86, 0x66, + 0xdd, 0x4e, 0x61, 0xca, 0xa5, 0xf2, 0x8e, 0x29, 0xcc, 0x89, 0x45, 0x06, 0x87, 0x87, 0xf6, 0x1b, + 0x66, 0x37, 0x87, 0x37, 0x2a, 0x67, 0xba, 0x8d, 0x5f, 0x7b, 0xc7, 0x86, 0x54, 0x67, 0x20, 0x61, + 0x47, 0xd2, 0xb7, 0x20, 0x61, 0x88, 0xb1, 0x87, 0x61, 0x60, 0xa7, 0x65, 0xc9, 0xa8, 0x27, 0xe0, + 0x81, 0xea, 0x74, 0x83, 0x80, 0x87, 0x64, 0x09, 0x87, 0x89, 0x0c, 0x87, 0xde, 0x96, 0xa7, 0x6a, + 0x73, 0x86, 0xd7, 0x91, 0xa7, 0x10, 0x3c, 0x8b, 0x74, 0xcb, 0x96, 0x74, 0x6f, 0x8d, 0xa6, 0xa7, + 0xf3, 0x33, 0xa3, 0xf7, 0x64, 0x11, 0x69, 0x73, 0xdb, 0x23, 0xcd, 0x86, 0x3d, 0x84, 0x70, 0x65, + 0x44, 0x54, 0x09, 0x68, 0x91, 0x62, 0x65, 0x7b, 0x2a, 0x8a, 0x72, 0x3f, 0x86, 0xc5, 0x51, 0xaa, + 0x72, 0x37, 0x83, 0x06, 0x4c, 0x8f, 0x65, 0x79, 0x3a, 0xa2, 0x86, 0xa7, 0x8f, 0x18, 0x0f, 0xa1, + 0x60, 0xe1, 0x85, 0xa9, 0xa7, 0x8f, 0x1b, 0x28, 0xac, 0x4e, 0xfb, 0x86, 0xe9, 0x74, 0x45, 0x96, + 0xa6, 0x7c, 0x4f, 0x3c, 0x2f, 0xb7, 0xc9, 0x73, 0xdd, 0xc4, 0xb7, 0x6c, 0x64, 0xff, 0xcf, 0x87, + 0x83, 0x1c, 0x42, 0xc2, 0xaa, 0x73, 0x99, 0x83, 0x6f, 0x64, 0x07, 0x33, 0x9e, 0x41, 0x6c, 0x77, + 0x61, 0x79, 0x73, 0x2d, 0x80, 0x87, 0x07, 0x8d, 0x81, 0x08, 0x46, 0x21, 0x87, 0x7f, 0xe4, 0x7b, + 0xa7, 0x8e, 0x45, 0xaf, 0x66, 0x86, 0x42, 0x42, 0xa0, 0x45, 0xd5, 0xa6, 0x88, 0x3c, 0x46, 0xd6, + 0xa7, 0x39, 0x5e, 0x84, 0x6f, 0x87, 0xd1, 0x9b, 0x87, 0x79, 0x87, 0x87, 0x7d, 0xab, 0xa7, 0xd4, + 0xbd, 0xa7, 0xfe, 0x8d, 0x87, 0x4f, 0x55, 0x22, 0x67, 0x0c, 0x34, 0x87, 0x3f, 0xf4, 0x07, 0xa7, + 0x16, 0x44, 0xa7, 0x0d, 0xf4, 0x13, 0x63, 0x42, 0x61, 0x76, 0x87, 0x97, 0x33, 0x87, 0xfe, 0xb7, + 0x87, 0x5c, 0xf0, 0x1c, 0x81, 0x4c, 0xba, 0x09, 0x45, 0x41, 0x4d, 0x9e, 0x18, 0x8c, 0x5f, 0x55, + 0x36, 0x34, 0x20, 0x28, 0x28, 0x31, 0x20, 0x3c, 0x3c, 0xa7, 0x37, 0x11, 0x9a, 0x07, 0x2d, 0x33, + 0x29, 0xcf, 0x57, 0x34, 0x29, 0xc3, 0xea, 0x63, 0x01, 0x4f, 0x28, 0xaf, 0x94, 0x2a, 0x20, 0xa0, + 0x56, 0x59, 0x28, 0x6c, 0x6f, 0x3f, 0x02, 0xd2, 0x97, 0x29, 0x29, 0xad, 0x26, 0x84, 0x4a, 0xab, + 0x5f, 0x3f, 0x8f, 0x92, 0x69, 0x6e, 0x6e, 0xa4, 0x84, 0x47, 0x21, 0x91, 0x75, 0x63, 0x5a, 0x02, + 0xa3, 0xef, 0x20, 0xa8, 0xa2, 0xae, 0x84, 0xd6, 0x86, 0x85, 0x18, 0x4b, 0x2e, 0xcf, 0xaa, 0x6d, + 0x5f, 0x54, 0x69, 0x61, 0x26, 0x69, 0x3a, 0x8b, 0xb3, 0x69, 0x74, 0x6a, 0x47, 0xc5, 0x24, 0x86, + 0xab, 0x8c, 0x62, 0xc7, 0x6c, 0x91, 0x66, 0x69, 0x84, 0xa3, 0x1d, 0xe4, 0x49, 0x21, 0x81, 0xa6, + 0xbc, 0xb7, 0x6f, 0x6e, 0xa4, 0x73, 0xb1, 0x64, 0x69, 0x46, 0xad, 0x08, 0x74, 0x82, 0x52, 0x7f, + 0x47, 0xb5, 0xac, 0x69, 0x1a, 0x18, 0x08, 0x61, 0xa3, 0xaa, 0x73, 0xa4, 0xf8, 0xa1, 0x41, 0xd0, + 0xb5, 0x6e, 0x6b, 0x3d, 0x42, 0xae, 0xa6, 0x60, 0x68, 0x47, 0xd4, 0xa4, 0xa1, 0x07, 0xa2, 0x4b, + 0xa1, 0x07, 0xed, 0x00, 0xa2, 0x40, 0x4f, 0xbf, 0x44, 0x4c, 0x4c, 0x14, 0x59, 0xb1, 0x62, 0x65, + 0x67, 0xdf, 0x42, 0x56, 0x44, 0x0e, 0xa3, 0xcb, 0xa9, 0x65, 0x01, 0x7c, 0xb7, 0x64, 0x73, 0x49, + 0x02, 0x83, 0xbf, 0xa1, 0xad, 0x83, 0x69, 0x65, 0x49, 0x65, 0xe7, 0x73, 0x20, 0x7b, 0xb5, 0x04, + 0x8a, 0x74, 0x09, 0x9d, 0x6f, 0x5b, 0x33, 0x7f, 0x14, 0x5d, 0x3b, 0x20, 0x7d, 0x9b, 0x77, 0x3b, + 0x0a, 0x86, 0x26, 0x00, 0x81, 0x3f, 0xd0, 0x84, 0xa5, 0x01, 0x6d, 0xa7, 0xc2, 0x9b, 0xa4, 0x8e, + 0x8a, 0x69, 0x51, 0x78, 0x67, 0xe1, 0x47, 0xb1, 0x41, 0x67, 0x5b, 0x43, 0x5e, 0x82, 0x17, 0x6c, + 0x47, 0xa6, 0x57, 0x20, 0x28, 0x80, 0x3b, 0x6d, 0x2a, 0x43, 0x81, 0x7b, 0x4f, 0x29, 0x74, 0x42, + 0xa2, 0x22, 0x54, 0x74, 0x65, 0xcd, 0x84, 0x80, 0xdb, 0x66, 0x6f, 0xa2, 0x6f, 0x63, 0x24, 0x89, + 0x69, 0x58, 0xd1, 0x0a, 0x7a, 0x47, 0x7d, 0xed, 0x46, 0xb5, 0xe8, 0x66, 0x46, 0xb7, 0x00, 0x63, + 0x99, 0xaa, 0x73, 0x00, 0xda, 0xa5, 0xde, 0xa4, 0x0d, 0x4c, 0x82, 0xf7, 0x85, 0xf3, 0xe2, 0xca, + 0x78, 0xd8, 0xd7, 0x64, 0x69, 0x74, 0x20, 0x28, 0x58, 0x6f, 0x29, 0x60, 0x42, 0xd6, 0x20, 0xb1, + 0x66, 0x6d, 0x82, 0xa4, 0xae, 0x68, 0xc7, 0xf9, 0x20, 0x86, 0xf9, 0xf4, 0x45, 0x7a, 0x62, 0x57, + 0xa2, 0xeb, 0x6b, 0x79, 0x05, 0x41, 0x91, 0xa2, 0x3e, 0x81, 0x94, 0x74, 0x75, 0x57, 0x92, 0x6f, + 0x66, 0x56, 0x03, 0x83, 0x06, 0x43, 0x8e, 0x84, 0x0a, 0x0f, 0x22, 0x67, 0xac, 0x64, 0x41, 0x1a, + 0x64, 0x0e, 0x07, 0x39, 0x67, 0xd9, 0xa7, 0x93, 0xd4, 0x07, 0xf1, 0x66, 0xfe, 0x67, 0x82, 0xf3, + 0x15, 0x9a, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x69, 0x1f, 0x0b, 0x87, 0xf9, 0xe3, 0x42, 0xdf, 0x56, + 0x20, 0x61, 0x13, 0x12, 0x64, 0x69, 0xc2, 0xd6, 0xd5, 0x83, 0x1f, 0x0e, 0x46, 0x41, 0xa6, 0x6b, + 0xab, 0x41, 0xc5, 0x21, 0xb7, 0x65, 0x76, 0x25, 0x0a, 0xa5, 0x34, 0x83, 0x03, 0xe0, 0x92, 0x67, + 0x6f, 0x4c, 0xac, 0x2c, 0xc1, 0x7d, 0x4f, 0x27, 0xb6, 0x4b, 0x27, 0xdb, 0xc1, 0xd7, 0x1c, 0xea, + 0x6d, 0x00, 0xe3, 0x67, 0x51, 0x48, 0x4c, 0x61, 0x84, 0x43, 0x5d, 0xa6, 0xb0, 0x82, 0x37, 0x50, + 0xac, 0x73, 0x5c, 0xa1, 0x41, 0x17, 0xa3, 0x16, 0xa5, 0xa3, 0x6f, 0x47, 0x64, 0x8d, 0x73, 0x15, + 0x54, 0xa4, 0xae, 0xa7, 0x38, 0xec, 0x81, 0xe0, 0x14, 0x91, 0x4b, 0x42, 0xa3, 0x84, 0x64, 0xaa, + 0x67, 0xf8, 0x67, 0xc9, 0xf8, 0x01, 0x87, 0x93, 0x42, 0x67, 0xf8, 0x83, 0xd8, 0xe3, 0x22, 0x84, + 0x68, 0x7e, 0x66, 0xa3, 0x87, 0x3c, 0xac, 0x41, 0xc0, 0x81, 0x83, 0x8b, 0x75, 0xf1, 0x52, 0x86, + 0x53, 0x86, 0xa2, 0x1c, 0xa6, 0xfd, 0xa9, 0x27, 0x67, 0x48, 0x94, 0x27, 0x2c, 0xcc, 0x63, 0xbf, + 0xa4, 0xa3, 0xeb, 0x66, 0xac, 0xb7, 0x6c, 0x79, 0xb5, 0x83, 0x61, 0xf3, 0x6f, 0x73, 0x69, 0x96, + 0x74, 0x6f, 0x00, 0x1d, 0xa7, 0xe7, 0x9e, 0xa3, 0xc7, 0xef, 0x49, 0x24, 0x6f, 0x50, 0x54, 0x46, + 0xb0, 0xaa, 0x72, 0x60, 0xdc, 0x9d, 0x73, 0x75, 0x6d, 0x19, 0x3c, 0x6d, 0x74, 0x3d, 0x42, 0xb4, + 0x41, 0x5c, 0xc4, 0xd4, 0xbf, 0xae, 0x6e, 0x63, 0xa4, 0xe8, 0xb0, 0x91, 0x27, 0x64, 0xef, 0x87, + 0xaf, 0x0c, 0x09, 0xc5, 0xda, 0xca, 0x83, 0x02, 0xbf, 0xa4, 0xc7, 0x87, 0x5f, 0x43, 0x06, 0x61, + 0x8c, 0xa7, 0x1f, 0xa2, 0x0b, 0x83, 0xc1, 0xbb, 0xa7, 0xdc, 0x31, 0x45, 0x99, 0x82, 0xb3, 0x24, + 0x2a, 0x97, 0x69, 0x66, 0x14, 0x71, 0xa6, 0xed, 0x94, 0x66, 0x69, 0x84, 0x04, 0x47, 0x3f, 0x84, + 0xf1, 0xc1, 0x87, 0x0a, 0x91, 0x44, 0x97, 0x86, 0x1c, 0xa5, 0x21, 0x5e, 0x61, 0x80, 0x84, 0x1c, + 0x87, 0xf3, 0xb1, 0x67, 0x06, 0xef, 0x87, 0xa3, 0xf0, 0x0f, 0x41, 0x01, 0xa7, 0x7b, 0x00, 0xa5, + 0x7c, 0x22, 0x60, 0xa7, 0x7f, 0x56, 0x87, 0x46, 0xff, 0x00, 0xa7, 0x21, 0x51, 0xfe, 0x73, 0x61, + 0x76, 0x65, 0x97, 0x49, 0x66, 0xfd, 0xb8, 0x67, 0x03, 0x21, 0xa5, 0x7d, 0x67, 0x98, 0x5f, 0xa6, + 0x66, 0x91, 0x61, 0x76, 0x1e, 0xe6, 0xc3, 0xd9, 0x2e, 0xb7, 0x61, 0x74, 0xa9, 0x24, 0xae, 0x20, + 0x8f, 0x42, 0x9c, 0x42, 0x90, 0x6e, 0x20, 0xac, 0x09, 0x61, 0x86, 0x62, 0xb1, 0xa3, 0x10, 0x53, + 0x20, 0x28, 0x23, 0x03, 0x6f, 0x6b, 0x42, 0x99, 0xa2, 0x7f, 0xa5, 0xbd, 0xad, 0xa3, 0xa0, 0x68, + 0x64, 0xfd, 0xe8, 0x27, 0xc6, 0xd8, 0xb2, 0x82, 0x6f, 0x93, 0xa7, 0x66, 0x30, 0xa2, 0x17, 0x71, + 0x61, 0x66, 0x22, 0x92, 0x77, 0x61, 0x8d, 0xfb, 0xa7, 0x8d, 0x1e, 0x87, 0x6c, 0x40, 0x97, 0x73, + 0x20, 0x67, 0x03, 0x83, 0xe1, 0x42, 0x51, 0x4a, 0x2c, 0xa2, 0x62, 0x0f, 0x87, 0x82, 0x5d, 0x46, + 0xa2, 0x67, 0x57, 0xee, 0x97, 0x28, 0x29, 0xa6, 0x3e, 0x43, 0x2a, 0x8f, 0x64, 0xa0, 0x7e, 0x87, + 0xa1, 0xfe, 0x01, 0x87, 0xf3, 0x11, 0xae, 0x2c, 0x9f, 0xa4, 0x2e, 0x33, 0x86, 0x8f, 0x67, 0x66, + 0x0e, 0x87, 0x8f, 0xf7, 0x07, 0x67, 0xcf, 0x87, 0xe8, 0x95, 0x62, 0x16, 0x87, 0xbf, 0xac, 0x25, + 0x81, 0xab, 0x16, 0x87, 0xaa, 0xfb, 0x2c, 0x41, 0x29, 0x87, 0xa8, 0xa1, 0x38, 0x44, 0x45, 0x43, + 0x4f, 0xeb, 0x87, 0xa2, 0x0f, 0x57, 0x20, 0x34, 0xdc, 0x03, 0x86, 0xb3, 0xbb, 0x27, 0x7b, 0x87, + 0xb5, 0x92, 0x86, 0x09, 0x8f, 0x20, 0xb2, 0xac, 0xa7, 0xc9, 0xdf, 0x46, 0xda, 0xa7, 0xc8, 0xd6, + 0x47, 0x61, 0x7c, 0xa7, 0xd0, 0xe8, 0x8b, 0x44, 0xe7, 0xa1, 0xcb, 0xca, 0x84, 0x51, 0x27, 0x38, + 0x87, 0xbf, 0x4b, 0x1e, 0x87, 0xbf, 0x57, 0x03, 0x85, 0x4c, 0xd8, 0x63, 0xe5, 0xa5, 0xbe, 0x46, + 0x7a, 0x8c, 0x20, 0x25, 0x22, 0x21, 0x97, 0x28, 0x29, 0xbd, 0x31, 0x87, 0xcf, 0x27, 0x0c, 0x86, + 0xb2, 0x88, 0x61, 0x12, 0x81, 0x00, 0xc5, 0xd8, 0x4a, 0x97, 0x6f, 0x66, 0xbc, 0x82, 0x84, 0xbc, + 0x67, 0x87, 0x2d, 0xf2, 0x2a, 0x66, 0xba, 0x86, 0xda, 0x41, 0x05, 0x46, 0xbc, 0xaf, 0x2e, 0xc9, + 0x01, 0x46, 0x10, 0x87, 0xbf, 0xfb, 0x11, 0x46, 0x9f, 0x87, 0xbe, 0xf5, 0x47, 0xab, 0x5b, 0x87, + 0xef, 0xe9, 0x77, 0x2f, 0x0a, 0x0b, 0x47, 0x67, 0xe4, 0x87, 0x5d, 0x4f, 0x07, 0x6d, 0x47, 0x8c, + 0x4f, 0x28, 0xa4, 0xd6, 0x26, 0xa7, 0xe0, 0x55, 0x67, 0x0a, 0xbb, 0xa7, 0x68, 0xf5, 0x03, 0x44, + 0x13, 0x84, 0x05, 0x84, 0x56, 0x18, 0xa4, 0x81, 0xa7, 0xc2, 0x62, 0x63, 0xa1, 0xcc, 0x53, 0xd9, + 0xec, 0xa7, 0xce, 0xc3, 0xb1, 0x20, 0x28, 0x33, 0x37, 0xc6, 0xd7, 0x0c, 0xa4, 0x30, 0x41, 0x7d, + 0xaf, 0x29, 0xc5, 0xac, 0xaa, 0x31, 0xd0, 0xc4, 0x9f, 0x4f, 0x4b, 0x2c, 0xea, 0x3a, 0x47, 0x4b, + 0xae, 0x47, 0x0e, 0x27, 0x67, 0xa7, 0xcf, 0xb5, 0x15, 0xaf, 0x2a, 0xe2, 0x6b, 0xa6, 0x7b, 0xe6, + 0xa3, 0x69, 0xa6, 0x60, 0x5f, 0x67, 0xe3, 0x45, 0x26, 0x87, 0x75, 0xd7, 0x42, 0x0a, 0xa9, 0x6d, + 0x6f, 0x56, 0x89, 0x69, 0x01, 0xa6, 0xc2, 0xcf, 0xa9, 0x69, 0x2f, 0xae, 0x73, 0x96, 0xa8, 0x8a, + 0x22, 0x91, 0xa5, 0x3c, 0xa0, 0xaf, 0x50, 0x99, 0x07, 0x86, 0xc7, 0x46, 0xcd, 0x8a, 0x2a, 0xcd, + 0x2c, 0xaf, 0x2a, 0xf6, 0xc0, 0xfe, 0x74, 0x68, 0x65, 0xa6, 0x7a, 0x95, 0x66, 0x65, 0x81, 0xf1, + 0xa7, 0x84, 0x58, 0xa1, 0x3b, 0xaa, 0x6a, 0x70, 0x3d, 0x86, 0x80, 0x00, 0xfa, 0x85, 0x70, 0x87, + 0xa2, 0xe5, 0x69, 0x72, 0x4e, 0x85, 0xc1, 0x78, 0xcf, 0x73, 0xdb, 0xda, 0x87, 0x56, 0xb1, 0xa5, + 0x42, 0x22, 0x65, 0xf0, 0x9b, 0x2d, 0x20, 0x45, 0x78, 0x61, 0x94, 0x48, 0x62, 0x2e, 0x63, 0x13, + 0x62, 0x30, 0x57, 0x65, 0x6e, 0xc4, 0x84, 0x1f, 0xe3, 0x44, 0xdd, 0x40, 0x79, 0xaa, 0x64, 0xa5, + 0x51, 0x72, 0x75, 0x3d, 0x6b, 0x28, 0xea, 0x87, 0x53, 0xd4, 0x00, 0x22, 0x44, 0xb7, 0x46, 0x31, + 0x4a, 0x73, 0x55, 0x44, 0x53, 0xa4, 0x70, 0x42, 0x51, 0x83, 0x12, 0x28, 0x67, 0x7a, 0x4f, 0x26, + 0x90, 0x01, 0x47, 0x3d, 0xa5, 0x7c, 0xe0, 0x8a, 0x68, 0xeb, 0x20, 0xcb, 0xa4, 0x69, 0xc7, 0xdb, + 0xf9, 0x33, 0xa1, 0xb9, 0x8c, 0x79, 0x76, 0x03, 0xa1, 0x68, 0xa2, 0xd1, 0xb7, 0x75, 0x20, 0x3c, + 0xe4, 0x4d, 0x2e, 0x27, 0xae, 0x4c, 0xa6, 0x57, 0x61, 0x6e, 0x30, 0x95, 0xb7, 0x62, 0x79, 0xcd, + 0x3b, 0x83, 0xa9, 0x6a, 0x42, 0x51, 0x81, 0xba, 0xa7, 0xa4, 0x7d, 0xa7, 0x53, 0xca, 0x0f, 0x20, + 0x04, 0x84, 0xce, 0xd6, 0xa1, 0xed, 0xc3, 0xcb, 0x9b, 0xa5, 0x6a, 0x9e, 0x28, 0x70, 0x09, 0x64, + 0x81, 0xaa, 0x2e, 0x92, 0xc7, 0xdd, 0x1b, 0x9c, 0x82, 0x5c, 0x84, 0x52, 0x57, 0x8f, 0x64, 0x24, + 0x3c, 0x86, 0x15, 0xa2, 0xef, 0x42, 0x86, 0x9d, 0x6f, 0x2e, 0xd0, 0xc4, 0x63, 0x6f, 0x86, 0xad, + 0x67, 0x26, 0x7c, 0x89, 0x73, 0x01, 0x82, 0xbc, 0x4f, 0x86, 0x00, 0x83, 0x65, 0xe9, 0x50, 0x79, + 0x6e, 0xc4, 0x81, 0x47, 0xb4, 0x69, 0x7a, 0x22, 0x44, 0xa5, 0x42, 0x67, 0x97, 0xff, 0x1a, 0x67, + 0x9c, 0x06, 0x99, 0x00, 0x5f, 0x41, 0x74, 0x84, 0x82, 0xa3, 0x5e, 0x04, 0xa1, 0x84, 0x15, 0xad, + 0x38, 0x69, 0x6f, 0x2b, 0xac, 0x4f, 0x47, 0x29, 0x79, 0x8f, 0x6c, 0xf1, 0xe2, 0x67, 0xb0, 0x60, + 0xa5, 0x63, 0xe8, 0x57, 0x83, 0x69, 0x78, 0xa4, 0x36, 0xc7, 0xc8, 0x74, 0x62, 0x43, 0x68, 0xa6, + 0x66, 0x8b, 0x2c, 0xb0, 0x45, 0xa3, 0x55, 0xe9, 0x6c, 0xc3, 0xd1, 0x70, 0x81, 0xeb, 0xc4, 0x44, + 0xa9, 0xa5, 0xdc, 0x87, 0xb3, 0x2a, 0x65, 0x49, 0xa7, 0x11, 0xad, 0x86, 0x22, 0x5f, 0x85, 0x6e, + 0x8a, 0x69, 0x6b, 0x51, 0x84, 0xc7, 0xa7, 0xdf, 0x26, 0x02, 0x97, 0x28, 0x29, 0x6f, 0x62, 0x03, + 0x86, 0xae, 0xca, 0xa7, 0xab, 0xff, 0x11, 0xc7, 0xd2, 0x90, 0x36, 0x87, 0x4e, 0x0d, 0x47, 0x6a, + 0xf4, 0x3d, 0xa6, 0xde, 0x87, 0x23, 0x72, 0xc6, 0xd8, 0x79, 0xa7, 0xeb, 0x18, 0x89, 0x3a, 0xda, + 0xea, 0x63, 0xab, 0x82, 0xe8, 0x87, 0xdf, 0xe9, 0x09, 0x82, 0x23, 0xc9, 0xcf, 0x6b, 0xdd, 0x46, + 0x64, 0x4c, 0x62, 0xf4, 0x8e, 0x62, 0x4d, 0xf3, 0x77, 0x6f, 0x66, 0x60, 0xc5, 0xc6, 0x37, 0xc3, + 0xdd, 0x52, 0x67, 0xf1, 0x7a, 0x8f, 0x78, 0xd1, 0x26, 0x46, 0x7f, 0x8e, 0x79, 0xda, 0xf8, 0x0e, + 0x6e, 0x64, 0x2d, 0x81, 0x2b, 0x2b, 0x2e, 0x5a, 0x87, 0x24, 0x2e, 0xc2, 0xd3, 0x5e, 0xa4, 0x80, + 0x87, 0xcf, 0x34, 0x09, 0x8f, 0x2e, 0xff, 0xe2, 0x03, 0x47, 0x00, 0x1f, 0xc7, 0xd0, 0x97, 0x34, + 0xa7, 0xda, 0x65, 0xb0, 0x53, 0x74, 0xd8, 0x66, 0xef, 0x74, 0x87, 0xfe, 0xe2, 0x47, 0x6a, 0xff, + 0x18, 0x66, 0x07, 0x47, 0x85, 0x14, 0xc7, 0xce, 0xcd, 0xf1, 0x16, 0xf8, 0x4f, 0x62, 0x73, 0x6f, + 0xcf, 0x74, 0xce, 0xcb, 0xf6, 0x1c, 0xca, 0x2f, 0xcd, 0xf9, 0x41, 0x24, 0x83, 0x75, 0x48, 0x57, + 0x6b, 0xc2, 0xcc, 0xbd, 0x14, 0x73, 0x20, 0x34, 0xab, 0x53, 0x25, 0x85, 0x62, 0xdf, 0x2e, 0x77, + 0x81, 0x2b, 0xba, 0xa2, 0xa9, 0xab, 0x73, 0x2b, 0x33, 0xa2, 0xda, 0x89, 0x62, 0xde, 0x9f, 0x82, + 0xdd, 0x84, 0xe2, 0xf1, 0xc4, 0xc9, 0xde, 0x83, 0x1d, 0xa6, 0x02, 0xec, 0x83, 0x7b, 0x20, 0x3a, + 0x0b, 0x61, 0x4c, 0x68, 0xd3, 0xa4, 0x03, 0xba, 0x5e, 0x2d, 0x57, 0x6e, 0x6f, 0x2d, 0x64, 0x80, + 0x09, 0x64, 0xa9, 0xc1, 0xc4, 0x4e, 0xa4, 0x1d, 0xa4, 0x21, 0x32, 0xbc, 0x67, 0x63, 0x63, 0x0a, + 0x04, 0x6c, 0xda, 0x5f, 0x43, 0x52, 0x54, 0x5f, 0x53, 0x45, 0xc6, 0xd1, 0x9a, 0x97, 0x5f, 0x4e, + 0x4f, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x53, 0x00, 0xa8, 0x56, 0xc3, 0x10, 0xe8, + 0x75, 0xc7, 0xd7, 0x81, 0xcf, 0x2e, 0xc8, 0x02, 0x2a, 0xc4, 0xd7, 0x22, 0xa7, 0x6b, 0x26, 0x5e, + 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0xbb, 0x21, 0x74, 0x59, 0x46, 0x42, 0x4c, + 0x4f, 0x43, 0x4b, 0x2e, 0x07, 0xc2, 0xc8, 0x7e, 0xe9, 0x6e, 0x47, 0xd5, 0xff, 0x07, 0x40, 0xd9, + 0x4d, 0x20, 0xac, 0x47, 0xd7, 0x16, 0xde, 0x00, 0x47, 0x43, 0x43, 0xc9, 0xc6, 0xc2, 0xc8, 0x20, + 0x38, 0x47, 0x4e, 0x55, 0x87, 0xa9, 0x5f, 0xd4, 0xc4, 0xca, 0xc5, 0x04, 0x71, 0xc4, 0xc9, 0xf5, + 0x00, 0x49, 0x29, 0x9b, 0x82, 0xb6, 0x65, 0x4f, 0x28, 0xc7, 0x82, 0x7d, 0xb0, 0xd1, 0x34, 0x30, + 0xd5, 0x30, 0xd6, 0x7c, 0x7c, 0xc7, 0xd4, 0x41, 0xb5, 0x61, 0xc6, 0x55, 0x6e, 0x67, 0xcb, 0x47, + 0x64, 0x75, 0x44, 0x28, 0x44, 0x49, 0x29, 0x97, 0xd4, 0x61, 0x74, 0xc1, 0xd2, 0x08, 0x65, 0xa1, + 0x77, 0x28, 0x28, 0x7d, 0x47, 0xdd, 0x0e, 0x4b, 0x29, 0x82, 0x57, 0x65, 0x6c, 0x80, 0x5f, 0x0f, + 0x33, 0x30, 0x31, 0x96, 0x27, 0x47, 0x9f, 0x11, 0x47, 0x3b, 0x73, 0x4d, 0x53, 0xe2, 0x47, 0x3c, + 0xff, 0x10, 0x82, 0xd1, 0x82, 0x0a, 0xf4, 0x47, 0x40, 0x46, 0x41, 0x74, 0x73, 0x65, 0xf0, 0xc5, + 0xc6, 0x9b, 0x25, 0x1f, 0x75, 0x28, 0x22, 0x59, 0x8a, 0x3a, 0xda, 0xa6, 0xdc, 0x48, 0xa7, 0xd3, + 0x16, 0x67, 0xc8, 0xa2, 0x61, 0x27, 0xa3, 0x86, 0xc5, 0xd4, 0xe8, 0x7f, 0x0f, 0x65, 0x72, 0x22, + 0x99, 0x0c, 0x63, 0xbe, 0xc4, 0xc6, 0x57, 0x0b, 0x23, 0xcf, 0xc1, 0xd2, 0xf3, 0x87, 0x7e, 0xff, + 0x07, 0xcc, 0x20, 0xc7, 0x3f, 0xa6, 0x2e, 0xc7, 0xd8, 0x8c, 0xdf, 0xa5, 0x60, 0x85, 0xa5, 0xdd, + 0x26, 0x84, 0x62, 0x2c, 0xfd, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x82, 0xef, 0x2b, 0xc6, 0xc6, 0x4f, + 0xa7, 0x3f, 0x20, 0xa9, 0x62, 0xbd, 0xb8, 0x0f, 0x31, 0x33, 0x31, 0x43, 0xe9, 0x70, 0xa1, 0xc7, + 0x05, 0x83, 0xb9, 0xa7, 0x7b, 0x28, 0xa7, 0xa5, 0x02, 0xc7, 0xd7, 0x7f, 0xfb, 0x18, 0xc7, 0xd9, + 0x19, 0xc5, 0xcc, 0x81, 0x83, 0x1f, 0xc0, 0xc7, 0xd7, 0x2e, 0x22, 0xa5, 0x1e, 0xb0, 0x47, 0x9c, + 0x82, 0xef, 0xa7, 0xc4, 0xd8, 0xb9, 0x07, 0x4f, 0xc7, 0xd8, 0xab, 0x20, 0x47, 0x35, 0xf1, 0x0d, + 0x47, 0x8b, 0x47, 0x99, 0xff, 0x20, 0x47, 0x1f, 0x12, 0xa7, 0x61, 0x97, 0x67, 0x60, 0x74, 0xa7, + 0xb0, 0x96, 0xa7, 0x84, 0x0f, 0x47, 0x0f, 0x39, 0x46, 0x7b, 0x47, 0x89, 0xfe, 0x33, 0x67, 0x1e, + 0xa7, 0xf5, 0xf0, 0xb7, 0x64, 0x65, 0xff, 0xee, 0x12, 0xb1, 0x20, 0x6e, 0xc5, 0xf5, 0xa3, 0x15, + 0xc7, 0xd8, 0x41, 0x3e, 0x87, 0x14, 0x1b, 0x82, 0x2d, 0x84, 0x92, 0x93, 0xb2, 0x6e, 0x6f, 0x47, + 0xa2, 0xb2, 0x99, 0x8a, 0x62, 0x4b, 0x85, 0x0c, 0x93, 0x86, 0x15, 0xa3, 0x21, 0xbe, 0xc7, 0xd0, + 0xe0, 0x83, 0xbd, 0x05, 0xc6, 0xd0, 0xdb, 0x81, 0x54, 0xc3, 0xc4, 0x7d, 0xc4, 0xd7, 0xe9, 0xc2, + 0xd8, 0xb4, 0x20, 0x1a, 0xc6, 0xc2, 0xbd, 0xad, 0x73, 0x1f, 0x63, 0xec, 0xc7, 0xd9, 0xd0, 0x16, + 0xc7, 0xd3, 0x9d, 0x87, 0xcb, 0x9d, 0x47, 0xc8, 0xca, 0x01, 0xc2, 0xd4, 0xfd, 0x6f, 0x6e, 0xe3, + 0x16, 0x47, 0xb6, 0xa7, 0xcb, 0xbd, 0x41, 0x38, 0x67, 0xea, 0x60, 0x83, 0xab, 0xaa, 0x6f, 0x2a, + 0x92, 0x86, 0xdf, 0xae, 0x77, 0xd9, 0x62, 0xd4, 0x64, 0x3b, 0xd9, 0x29, 0x82, 0xd0, 0xa3, 0xd1, + 0x56, 0x43, 0x06, 0x86, 0xe5, 0xb2, 0x72, 0x65, 0xd5, 0x2a, 0x83, 0x44, 0x03, 0x10, 0x62, 0xdc, + 0x85, 0x4e, 0xd2, 0x68, 0x69, 0xd2, 0x94, 0xc7, 0xc8, 0x54, 0x31, 0xc6, 0xdc, 0xd9, 0x84, 0xdf, + 0x84, 0xc2, 0xbc, 0x47, 0x86, 0x64, 0x85, 0x69, 0x69, 0xda, 0xab, 0x74, 0x83, 0x22, 0xa2, 0xea, + 0x92, 0x74, 0x61, 0xd9, 0x36, 0xa2, 0xdb, 0x66, 0x31, 0x21, 0x66, 0x67, 0xc4, 0xa7, 0xcf, 0x8e, + 0x0f, 0x87, 0xe2, 0xdf, 0x47, 0xb5, 0xbe, 0x67, 0xb1, 0x47, 0xa3, 0xfe, 0x0e, 0x97, 0x69, 0x73, + 0x74, 0xfe, 0x00, 0xa7, 0x43, 0x71, 0x85, 0xf3, 0xa7, 0x84, 0x41, 0xaa, 0x3b, 0x21, 0x8c, 0xc2, + 0xc2, 0x29, 0x05, 0xc7, 0xc1, 0xdc, 0x5a, 0xae, 0x77, 0x35, 0xa6, 0xad, 0x4e, 0x42, 0xad, 0xa7, + 0x3c, 0x62, 0x49, 0x22, 0xbf, 0xa7, 0xd3, 0x91, 0xae, 0x29, 0xb3, 0x28, 0x22, 0xbe, 0x83, 0x7e, + 0x47, 0xdd, 0x14, 0x86, 0x6a, 0xa4, 0xf4, 0x98, 0x85, 0x69, 0x4f, 0x3b, 0xa9, 0xf2, 0x1a, 0xa3, + 0x77, 0xc7, 0xd2, 0x65, 0x32, 0x43, 0x22, 0xc7, 0xd3, 0x28, 0x47, 0xac, 0xe1, 0xa6, 0xcf, 0x47, + 0xad, 0xa2, 0x46, 0xac, 0x46, 0xdd, 0x47, 0xad, 0xa7, 0xe5, 0x51, 0x47, 0x3f, 0xf3, 0x14, 0x86, + 0xf1, 0x47, 0x96, 0x4f, 0x01, 0x44, 0xbb, 0x44, 0x3f, 0xa9, 0x6c, 0xf1, 0x36, 0x6f, 0x49, 0xf1, + 0x87, 0xd4, 0xe3, 0x77, 0x29, 0x3b, 0x3a, 0xe7, 0xa7, 0x72, 0xae, 0x67, 0x60, 0x87, 0xaf, 0x33, + 0x06, 0x67, 0xaa, 0x7b, 0x47, 0xd2, 0x83, 0xd2, 0x39, 0x81, 0x46, 0x79, 0x33, 0x66, 0x69, 0x78, + 0x36, 0x34, 0x6b, 0x3e, 0xa7, 0xc5, 0xea, 0x87, 0x05, 0x93, 0xa7, 0xbe, 0xbd, 0x67, 0x65, 0x87, + 0xae, 0x23, 0x47, 0x5a, 0xeb, 0x47, 0xd2, 0x47, 0x5a, 0xf9, 0x10, 0xa7, 0xfc, 0xef, 0xc7, 0xbd, + 0x11, 0x04, 0xce, 0x7d, 0xbd, 0x1c, 0xe7, 0xf0, 0xe8, +}; + +static unsigned char buf[18830]; + +int main() { + + unsigned long cksum = adler32(0, NULL, 0); + + decompress_lzsa2(compressed, buf); + cksum = adler32(cksum, buf, 18830); + + return cksum == 0xf748269d ? 0 : 1; +} diff --git a/test/val/zx02.c b/test/val/zx02.c new file mode 100644 index 000000000..0c123f968 --- /dev/null +++ b/test/val/zx02.c @@ -0,0 +1,416 @@ +/* + !!DESCRIPTION!! zx02 decompression + !!ORIGIN!! cc65 regression tests + !!LICENCE!! BSD 2-clause + !!AUTHOR!! Colin Leroy-Mira +*/ + +#include <zlib.h> +#include <stdio.h> +#include <zx02.h> + +/* The sample data is the original lz4.h, compressed with: + * zx02 lz4.h lz4.zx02 + * + * We reused lz4.h from the LZ4 test to have a matching adler32 sum. + */ +static const unsigned char compressed[] = { + 0xa2, 0x2f, 0x2a, 0x0a, 0x20, 0x2e, 0x42, 0x4c, 0x5a, 0x34, 0x20, 0x2d, 0x20, 0x46, 0x61, 0x73, + 0x74, 0x15, 0xf9, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x4e, 0x4d, 0x4d, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x4e, 0x69, 0x6c, 0x65, 0x4a, 0x1d, 0x41, 0x43, 0x6f, 0x70, 0x79, 0x36, 0x67, 0x2b, + 0x68, 0x43, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x09, 0xd0, 0x35, 0x2c, 0x20, + 0x59, 0x61, 0x6e, 0x6e, 0x3b, 0x4d, 0x6c, 0x4c, 0x74, 0x2e, 0x0a, 0x4d, 0x53, 0x42, 0x53, 0x44, + 0x3a, 0x3e, 0x15, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x0e, + 0x68, 0x39, 0x70, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x14, 0x00, 0x2e, 0x92, 0x25, 0x35, 0x6f, + 0x75, 0x72, 0x32, 0x29, 0x14, 0x72, 0x67, 0x2f, 0x6c, 0x33, 0x45, 0x96, 0x73, 0x2f, 0x62, 0x73, + 0x64, 0x2d, 0x19, 0x2d, 0x2e, 0x70, 0x68, 0x70, 0x29, 0x22, 0x9b, 0x99, 0x52, 0x65, 0x64, 0x69, + 0x52, 0x21, 0xf2, 0x62, 0x75, 0x94, 0x45, 0xd8, 0x14, 0x64, 0xaf, 0x53, 0x69, 0x14, 0x85, 0x48, + 0x23, 0xe0, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x0a, 0x66, 0x06, 0x72, 0x6d, 0x73, 0x2c, 0x77, + 0x05, 0x85, 0x20, 0x14, 0x24, 0x0f, 0x46, 0x52, 0x74, 0x8b, 0x21, 0x6d, 0x6f, 0x66, 0x15, 0xb4, + 0x61, 0x87, 0x56, 0x40, 0x56, 0x6c, 0x51, 0x06, 0x56, 0x3e, 0x74, 0x4c, 0xba, 0x12, 0x72, 0x6f, + 0x76, 0x11, 0x64, 0x11, 0x51, 0x5a, 0x3e, 0x09, 0x58, 0x36, 0x8e, 0x9a, 0x48, 0x6f, 0x8a, 0x6e, + 0x67, 0x15, 0x63, 0x5c, 0x70, 0x42, 0x69, 0x73, 0x92, 0x93, 0x60, 0xcc, 0x3a, 0xd3, 0x01, 0x19, + 0x2a, 0x3d, 0xe4, 0x4a, 0x99, 0x6f, 0x66, 0x2f, 0xd5, 0x74, 0xa6, 0x64, 0x5a, 0x56, 0xa4, 0x45, + 0x72, 0x64, 0x61, 0x98, 0x51, 0xb3, 0x88, 0x62, 0x47, 0xd6, 0x35, 0x76, 0x97, 0x41, 0x35, 0x6e, + 0x44, 0x72, 0x5c, 0x2c, 0x3d, 0x48, 0x90, 0x20, 0x6c, 0x51, 0x5e, 0x87, 0x69, 0xef, 0x67, 0x12, + 0x29, 0x84, 0x64, 0x50, 0x16, 0x63, 0xa2, 0x26, 0x12, 0x72, 0x2e, 0x6b, 0x11, 0x5c, 0x50, 0x2b, + 0xf6, 0x76, 0x11, 0x61, 0xd6, 0x2a, 0x75, 0x62, 0xda, 0x17, 0xd1, 0x81, 0x8b, 0x1d, 0x67, 0x17, + 0xe9, 0x58, 0x93, 0xcb, 0xd3, 0x28, 0x46, 0x6f, 0x63, 0x75, 0x22, 0x6e, 0x69, 0xea, 0x65, 0xc6, + 0x2f, 0x51, 0x04, 0x92, 0x33, 0x14, 0x0a, 0x6d, 0x26, 0x0a, 0x6d, 0x69, 0xd0, 0x77, 0x96, 0xed, + 0x68, 0x5d, 0xd1, 0x39, 0x58, 0x81, 0x87, 0xf6, 0xcc, 0x9b, 0xf9, 0x54, 0x48, 0x49, 0x53, 0x20, + 0x53, 0x4f, 0x46, 0x54, 0x57, 0x41, 0x52, 0x45, 0x20, 0x0a, 0x17, 0x82, 0x50, 0x52, 0x4f, 0x56, + 0x49, 0x44, 0x45, 0x44, 0x44, 0x42, 0x59, 0x39, 0x24, 0xa0, 0x43, 0x4f, 0x50, 0x59, 0xa9, 0x49, + 0x47, 0x48, 0x54, 0x20, 0x48, 0x4f, 0x4c, 0x13, 0x2e, 0x52, 0x42, 0x42, 0x41, 0x4e, 0x44, 0x2b, + 0x22, 0x4e, 0x54, 0x05, 0x42, 0x55, 0x4f, 0x20, 0x4d, 0x8d, 0x22, 0x41, 0x53, 0x05, 0x79, 0x22, + 0x37, 0x44, 0x07, 0x72, 0xd1, 0x45, 0x58, 0x50, 0x9c, 0x53, 0x52, 0x26, 0x3c, 0x2c, 0xc9, 0x4d, + 0x50, 0x4c, 0x49, 0x45, 0x04, 0xc1, 0x52, 0x34, 0x49, 0x54, 0x14, 0x53, 0x2c, 0x20, 0x26, 0x4e, + 0x43, 0x91, 0x55, 0x44, 0x0a, 0x47, 0x50, 0x14, 0x86, 0xb2, 0x4e, 0x1f, 0x54, 0x24, 0x73, 0x54, + 0x91, 0x49, 0x54, 0x53, 0x15, 0xa8, 0x2c, 0xf5, 0x2e, 0x73, 0x40, 0x9e, 0x46, 0x62, 0x4d, 0x06, + 0x43, 0x43, 0x48, 0x1d, 0x45, 0x41, 0x42, 0x49, 0x3a, 0x54, 0xd4, 0x44, 0xe5, 0x46, 0x10, 0x45, + 0x4e, 0xdd, 0x0e, 0x45, 0xde, 0x91, 0x24, 0x94, 0x8a, 0x64, 0x5e, 0xd4, 0x43, 0x55, 0x4c, 0x0c, + 0x14, 0x0d, 0x55, 0x50, 0x4f, 0x53, 0x65, 0x9a, 0xbf, 0x25, 0xe4, 0x53, 0x43, 0x26, 0x46, 0xae, + 0xa8, 0x2e, 0x11, 0x07, 0xef, 0x89, 0x50, 0x56, 0x45, 0x74, 0x94, 0x00, 0xa0, 0x99, 0x4c, 0x4c, + 0xdd, 0xb5, 0x8f, 0x25, 0x4f, 0x57, 0xaa, 0x59, 0x80, 0xa6, 0xdd, 0xa6, 0x54, 0x62, 0x4a, 0xf0, + 0xfa, 0x95, 0x4c, 0x45, 0xdd, 0x94, 0xdb, 0xad, 0x49, 0xb6, 0x43, 0x54, 0x94, 0xad, 0x13, 0xb0, + 0x43, 0x05, 0x44, 0x68, 0x14, 0xac, 0x2c, 0x91, 0xd4, 0x53, 0x50, 0x45, 0x1e, 0x17, 0x41, 0xdc, + 0x58, 0x86, 0xa9, 0x25, 0x14, 0x59, 0x2c, 0xad, 0x98, 0x30, 0x91, 0x51, 0x55, 0x4f, 0x12, 0x39, + 0x8a, 0x9c, 0x41, 0x4d, 0x41, 0x47, 0x3a, 0x8a, 0x20, 0x28, 0xad, 0xa4, 0x49, 0x65, 0x43, 0xac, + 0x94, 0x1c, 0x73, 0x25, 0x46, 0xbc, 0x55, 0xb6, 0x28, 0x04, 0xdc, 0x54, 0x3c, 0xc1, 0x20, 0x47, + 0x4f, 0x44, 0xc9, 0xed, 0x27, 0xb0, 0x52, 0x56, 0x45, 0x02, 0x9c, 0x3b, 0x70, 0x9c, 0xfa, 0x71, + 0x85, 0x55, 0x24, 0x94, 0x19, 0xcf, 0x05, 0x54, 0xfd, 0x57, 0x8b, 0x15, 0x71, 0x42, 0x17, 0x15, + 0x42, 0x3a, 0xe0, 0xd5, 0x85, 0x0a, 0x72, 0x8a, 0xdc, 0x26, 0x55, 0x50, 0x1a, 0x38, 0x29, 0x77, + 0xe6, 0x04, 0x18, 0x43, 0x53, 0x15, 0x41, 0x3e, 0xf6, 0xc9, 0xd7, 0x65, 0x2c, 0xe7, 0x1d, 0x91, + 0x5f, 0x45, 0x72, 0x59, 0xb5, 0x66, 0x36, 0x99, 0x1b, 0xa0, 0x70, 0x57, 0x95, 0x2e, 0x62, 0x1c, + 0x8f, 0x6b, 0xc7, 0x41, 0x44, 0x1d, 0x53, 0x0e, 0x24, 0x49, 0x4d, 0xe5, 0xe5, 0x71, 0x99, 0x96, + 0xb1, 0x38, 0xdf, 0x61, 0x20, 0x02, 0x47, 0x75, 0x3c, 0x06, 0x1e, 0x95, 0x90, 0x38, 0x04, 0x41, + 0x91, 0x57, 0x08, 0xf0, 0x29, 0x55, 0x52, 0x0c, 0x41, 0x56, 0x06, 0xf9, 0xc4, 0x23, 0xed, 0x65, + 0xdc, 0xf5, 0x46, 0x47, 0x55, 0xb3, 0x91, 0x79, 0x1a, 0x9d, 0xb5, 0xca, 0xa5, 0xbb, 0x08, 0x66, + 0x46, 0x76, 0x44, 0x16, 0x17, 0x7f, 0x5f, 0x6c, 0x1f, 0x58, 0x9a, 0x13, 0xdc, 0x7d, 0xdb, 0x76, + 0xa0, 0xfb, 0x7c, 0x29, 0xc6, 0x59, 0xb0, 0xc4, 0x20, 0x7d, 0xae, 0xa9, 0x35, 0x6b, 0x23, 0xb4, + 0x63, 0x74, 0x9b, 0xc0, 0x40, 0x68, 0x24, 0x72, 0x1a, 0x51, 0x3a, 0x45, 0x2d, 0xe9, 0xcf, 0x6e, + 0x66, 0x17, 0xa4, 0xf1, 0x9f, 0x6f, 0x73, 0x44, 0xcc, 0x3c, 0x79, 0x38, 0x7a, 0x20, 0x47, 0x13, + 0x73, 0xa0, 0x15, 0x7c, 0x67, 0xef, 0x37, 0x75, 0x62, 0x2e, 0xb0, 0x01, 0xd2, 0x2f, 0x43, 0x79, + 0x98, 0xa4, 0x34, 0x39, 0x37, 0x33, 0x2f, 0x6c, 0x7a, 0x34, 0x79, 0xb1, 0x70, 0x7a, 0x3a, 0x1a, + 0x1d, 0xd6, 0x7f, 0xa4, 0x9a, 0x6f, 0xf1, 0x72, 0x4f, 0xa8, 0x10, 0x49, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x7d, 0x52, 0x43, 0x0a, 0x49, 0x23, 0x21, 0x0f, 0x4e, 0x87, 0xd9, 0x63, 0x0a, + 0x2a, 0x2f, 0x0a, 0x23, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x20, 0x46, 0x85, 0x02, 0x0a, 0x1a, + 0xbc, 0xfe, 0xa0, 0x20, 0x64, 0x65, 0x66, 0xc2, 0x6e, 0x65, 0x64, 0x81, 0x28, 0x5f, 0x5f, 0x63, + 0x6c, 0xb9, 0x22, 0x5e, 0x07, 0x89, 0xca, 0x65, 0x78, 0xac, 0x25, 0x6b, 0x30, 0x70, 0x22, 0x43, + 0x22, 0x5a, 0x7b, 0x4c, 0xde, 0x6c, 0x85, 0x53, 0x5c, 0xf9, 0x55, 0x04, 0x2a, 0x95, 0x26, 0x2e, + 0x68, 0xb7, 0x53, 0x06, 0x73, 0x01, 0x1c, 0x6f, 0x6b, 0xf9, 0x63, 0xa2, 0x5b, 0x66, 0x75, 0xb8, + 0x88, 0x35, 0x6e, 0x2c, 0x26, 0x37, 0x14, 0xa4, 0x76, 0x30, 0x29, 0x6e, 0x4d, 0x3a, 0x56, 0x75, + 0x66, 0x66, 0x72, 0xac, 0x43, 0x56, 0x7c, 0x1c, 0x51, 0xf6, 0x8d, 0x67, 0x86, 0x22, 0x6d, 0xf5, + 0x6d, 0x46, 0xb7, 0x49, 0x1c, 0x1e, 0x79, 0x8d, 0x66, 0x1e, 0x51, 0x20, 0x3b, 0x67, 0x5d, 0xf0, + 0x30, 0x78, 0xed, 0xb3, 0x60, 0x1d, 0x6f, 0x2d, 0x45, 0x24, 0x1b, 0xde, 0x5d, 0x1c, 0xdb, 0x04, + 0x4b, 0x64, 0x3c, 0x04, 0x61, 0x28, 0x19, 0x56, 0x36, 0xe8, 0xe1, 0xf9, 0xd5, 0x49, 0xd8, 0x15, + 0xa5, 0x4a, 0x25, 0x7b, 0x28, 0xc1, 0x95, 0x29, 0x2c, 0xbf, 0x96, 0x1f, 0x95, 0x47, 0x86, 0xa3, + 0x3f, 0x71, 0x94, 0x62, 0x69, 0x54, 0x00, 0xd1, 0x8c, 0x31, 0x1d, 0xaf, 0xf8, 0x9b, 0x50, 0xd5, + 0x84, 0x3c, 0x78, 0xf9, 0x36, 0x67, 0x2a, 0x7c, 0x7f, 0x16, 0x5f, 0xde, 0xc8, 0x96, 0xb7, 0x52, + 0xeb, 0xab, 0x61, 0xf5, 0x6f, 0xca, 0x49, 0x1e, 0x2e, 0x64, 0x2e, 0xc7, 0x9f, 0x52, 0x27, 0x01, + 0xe9, 0x68, 0x56, 0x80, 0x67, 0x56, 0x7a, 0x54, 0x3f, 0x14, 0x01, 0xaf, 0x69, 0x57, 0x68, 0x35, + 0xd9, 0xa3, 0x1f, 0x5f, 0x07, 0x9d, 0x53, 0xc1, 0xb7, 0x5f, 0xb1, 0xdc, 0x4a, 0xe1, 0xc7, 0x05, + 0x01, 0x31, 0x09, 0x5b, 0xf8, 0x46, 0x11, 0x20, 0x61, 0x86, 0x1c, 0x6b, 0x87, 0xf7, 0x31, 0x4d, + 0x66, 0xb7, 0xf8, 0x19, 0x43, 0xa2, 0x75, 0x1e, 0x28, 0x44, 0x3f, 0x8f, 0x23, 0x49, 0x4e, 0x82, + 0x37, 0xf6, 0xc2, 0x0c, 0x77, 0x18, 0x6e, 0x42, 0x5c, 0x2d, 0xa1, 0x4f, 0x29, 0xa3, 0x27, 0x61, + 0x70, 0x1d, 0xf6, 0x69, 0x60, 0xd4, 0x98, 0xac, 0xab, 0xfd, 0xac, 0xb8, 0x07, 0x4c, 0x41, 0xd9, + 0x64, 0x3b, 0xb2, 0x36, 0x74, 0x77, 0xda, 0x16, 0x09, 0xf9, 0x67, 0x2d, 0x04, 0x62, 0x78, 0x15, + 0x45, 0x2b, 0x7a, 0xb1, 0x2a, 0x6c, 0xa7, 0xa0, 0xe5, 0x23, 0x3f, 0x9b, 0x29, 0x4e, 0x55, 0x4d, + 0x42, 0x66, 0x14, 0x22, 0x2a, 0xff, 0x4d, 0x60, 0x31, 0x30, 0x30, 0x49, 0x07, 0x20, 0x2b, 0x8b, + 0xa9, 0x93, 0x31, 0x62, 0x2f, 0xf7, 0x90, 0xac, 0xc4, 0x74, 0xb1, 0x76, 0xa3, 0x15, 0x1f, 0x4e, + 0x16, 0x32, 0x62, 0x12, 0x07, 0xe6, 0x76, 0x89, 0x94, 0x29, 0x3b, 0xa3, 0x99, 0xe8, 0x79, 0x54, + 0xc8, 0xd7, 0xe3, 0x6d, 0x26, 0x29, 0x71, 0x47, 0xa2, 0xab, 0xfd, 0xf6, 0x89, 0x64, 0x3b, 0x06, + 0x4d, 0x4d, 0xf2, 0x86, 0x26, 0x59, 0x5f, 0xb1, 0x85, 0xa9, 0x94, 0x46, 0x2b, 0x4d, 0xc9, 0xef, + 0xb0, 0xdf, 0x69, 0x61, 0x76, 0xab, 0x27, 0x45, 0xc4, 0x68, 0x61, 0x32, 0xac, 0x20, 0x4e, 0x2d, + 0x3e, 0x32, 0x5e, 0x4e, 0x20, 0x42, 0x46, 0xce, 0x73, 0x6a, 0x58, 0x5e, 0x34, 0xe2, 0x50, 0x30, + 0x12, 0x31, 0x65, 0x31, 0xd0, 0x34, 0x34, 0x0a, 0x4b, 0x42, 0x3b, 0x14, 0x28, 0x32, 0x21, 0x34, + 0x20, 0x02, 0x17, 0x36, 0x84, 0x36, 0x19, 0x44, 0x16, 0x32, 0x45, 0xc3, 0x4d, 0x63, 0x4c, 0x7c, + 0x63, 0x2e, 0x29, 0xcb, 0x9a, 0x9b, 0x3e, 0x02, 0x63, 0x73, 0x84, 0x6d, 0xe3, 0xf6, 0xad, 0x62, + 0xa9, 0xab, 0x5a, 0xb2, 0x9a, 0x9b, 0x1f, 0x72, 0x59, 0x7d, 0x39, 0x06, 0x52, 0xb8, 0x4b, 0x56, + 0x06, 0x65, 0x9f, 0x57, 0x99, 0x6d, 0x7d, 0xdf, 0x5a, 0x3c, 0x58, 0xb8, 0x4a, 0x76, 0x11, 0x74, + 0x33, 0xe5, 0x06, 0x10, 0xa1, 0xaa, 0x66, 0xa8, 0x2f, 0x50, 0x7d, 0x44, 0x6d, 0x8c, 0x80, 0x9c, + 0x74, 0xd5, 0x76, 0x61, 0x6c, 0x40, 0x66, 0x36, 0xc8, 0x31, 0x34, 0x2c, 0x58, 0xc7, 0x5b, 0x66, + 0x4e, 0xb8, 0xba, 0x25, 0x77, 0x5e, 0xe5, 0x02, 0x08, 0xb1, 0x2a, 0x79, 0x6a, 0x2c, 0x59, 0x11, + 0x3c, 0x61, 0x8a, 0x55, 0x80, 0xe6, 0x6c, 0xdc, 0x78, 0x38, 0x36, 0x62, 0x4c, 0x31, 0xa5, 0x6d, + 0x0a, 0x5d, 0xa7, 0x7d, 0x8d, 0x1a, 0xa8, 0x0a, 0x3e, 0x8d, 0x86, 0x53, 0x1a, 0x79, 0x81, 0xf1, + 0x46, 0xb9, 0x65, 0xda, 0x3a, 0x8d, 0x9b, 0x29, 0x95, 0xb9, 0x17, 0xc1, 0x5f, 0x8c, 0xc1, 0x55, + 0x28, 0x20, 0x8c, 0x34, 0x9b, 0x52, 0x1e, 0x32, 0x2a, 0x98, 0xd5, 0x59, 0x2c, 0x1b, 0x54, 0x42, + 0x30, 0x16, 0x71, 0x59, 0x2f, 0x24, 0xf8, 0x7a, 0x65, 0x1f, 0xde, 0x89, 0x22, 0x78, 0x44, 0x15, + 0x39, 0x21, 0xe4, 0x0e, 0xb5, 0xa5, 0x5e, 0x29, 0xb9, 0xc2, 0xd8, 0x66, 0x4a, 0xb5, 0xf6, 0xf3, + 0x37, 0x97, 0xbd, 0x96, 0x31, 0x95, 0xcd, 0xe5, 0x15, 0x8e, 0x83, 0x87, 0x29, 0x97, 0x1b, 0xad, + 0xbd, 0x5d, 0x63, 0xa1, 0x18, 0x27, 0x8b, 0x63, 0x02, 0x27, 0x1e, 0x62, 0x79, 0x93, 0xa3, 0x3d, + 0x72, 0x6f, 0x6d, 0x65, 0x3d, 0x34, 0x5a, 0x6d, 0x36, 0x71, 0x9b, 0xca, 0x09, 0xc5, 0x64, 0x79, + 0x1e, 0x0f, 0xc6, 0x3f, 0xd5, 0x84, 0xe8, 0x46, 0x91, 0x47, 0x27, 0x77, 0x63, 0xa9, 0x27, 0x45, + 0x99, 0x2a, 0x8b, 0xf5, 0x45, 0x7c, 0x2e, 0xed, 0xa6, 0x86, 0x1f, 0xd2, 0x4f, 0x7c, 0x67, 0x75, + 0xc7, 0x5e, 0xa4, 0xcd, 0x25, 0x78, 0x68, 0x06, 0x57, 0x63, 0x15, 0xa5, 0xb0, 0x75, 0xb3, 0x18, + 0x20, 0x3e, 0x3d, 0x99, 0xf1, 0x42, 0x9e, 0x20, 0x86, 0xa4, 0x28, 0x74, 0x6b, 0xb6, 0x38, 0x29, + 0x98, 0x49, 0x74, 0x23, 0x41, 0x2a, 0x20, 0x59, 0x3a, 0xb2, 0xda, 0x67, 0x78, 0x14, 0x46, 0x44, + 0x1f, 0xd9, 0xe0, 0x84, 0x5d, 0x32, 0x2c, 0x4b, 0x79, 0xc0, 0x46, 0x72, 0xc3, 0x1e, 0xec, 0x74, + 0xd5, 0xa1, 0x6f, 0x97, 0xdc, 0xb5, 0x5f, 0xf9, 0xb5, 0xde, 0x5b, 0xef, 0xdc, 0x50, 0xd9, 0xb7, + 0x29, 0x01, 0x99, 0xf9, 0xde, 0xe2, 0x7b, 0xb0, 0x5e, 0xbb, 0xe6, 0x9a, 0x68, 0xf3, 0x86, 0x64, + 0x67, 0x95, 0x4a, 0x9f, 0xf6, 0xc3, 0x96, 0x36, 0xf6, 0x0e, 0xf1, 0xa5, 0x5f, 0x58, 0xf0, 0xdd, + 0xcc, 0x54, 0xf0, 0x01, 0x7f, 0x2a, 0x25, 0x73, 0xe3, 0xb4, 0x5b, 0x68, 0x37, 0x75, 0x21, 0x9d, + 0x98, 0xf2, 0x8c, 0x2b, 0x65, 0x41, 0x67, 0xb4, 0x29, 0xd9, 0x65, 0x71, 0x75, 0x68, 0xb1, 0x1b, + 0x77, 0xd5, 0xf5, 0xc3, 0x49, 0x20, 0x5b, 0x9f, 0x4c, 0x26, 0xe7, 0xe4, 0xc0, 0x65, 0xc9, 0x54, + 0x68, 0x4b, 0x26, 0xa9, 0x06, 0x6e, 0xf1, 0x13, 0xf0, 0xf6, 0x72, 0x69, 0xa1, 0x7e, 0x86, 0x2d, + 0x5a, 0x1e, 0x7e, 0x6d, 0x51, 0x56, 0xa4, 0x80, 0x42, 0x95, 0x97, 0x3f, 0xd9, 0xd7, 0xd7, 0x43, + 0x45, 0xaf, 0x01, 0x9c, 0xdb, 0xb4, 0x1a, 0x06, 0x3a, 0x4d, 0x98, 0x3a, 0xb4, 0x85, 0x75, 0x70, + 0x7c, 0xd6, 0x07, 0xa7, 0xed, 0x6a, 0x33, 0x65, 0x83, 0x41, 0x58, 0x5f, 0x49, 0x4e, 0x50, 0xd7, + 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x81, 0x7c, 0x0d, 0xf5, 0x80, 0xab, 0x35, 0x65, 0x7a, + 0xbd, 0xc7, 0x65, 0x58, 0x7c, 0xb3, 0x5f, 0x6d, 0x6e, 0x66, 0xed, 0x71, 0x4d, 0x28, 0xac, 0x73, + 0x9e, 0xf3, 0x97, 0x06, 0x62, 0xca, 0xef, 0xc5, 0x29, 0xbb, 0xdf, 0xa5, 0xe5, 0x85, 0x3e, 0x6e, + 0xb0, 0xd6, 0xaf, 0x7a, 0xaa, 0x35, 0xf5, 0x9c, 0xe6, 0x9b, 0x75, 0x07, 0xc6, 0x65, 0x89, 0x7f, + 0x7d, 0xc3, 0xc4, 0x4a, 0x63, 0x42, 0x89, 0x73, 0x61, 0xb8, 0x35, 0x26, 0x3c, 0x3d, 0x47, 0x4b, + 0x4f, 0x6e, 0x14, 0x98, 0x10, 0x4f, 0x91, 0xbd, 0x3d, 0x01, 0x91, 0x5f, 0x30, 0xe1, 0x39, 0xa6, + 0xc1, 0x9b, 0x47, 0xce, 0x72, 0x73, 0xda, 0xdc, 0x8b, 0xa5, 0x9f, 0x76, 0xd5, 0xa7, 0x6b, 0x97, + 0x28, 0x59, 0x53, 0x4d, 0x55, 0x28, 0x60, 0x14, 0x75, 0x0e, 0x17, 0xdd, 0x01, 0x53, 0x31, 0x61, + 0x9b, 0xa3, 0x03, 0x69, 0x0a, 0xca, 0x81, 0x4f, 0x97, 0xd7, 0x7d, 0x65, 0xab, 0x9f, 0xcc, 0xb3, + 0x0f, 0x69, 0xc9, 0xdd, 0x89, 0xf9, 0x77, 0xba, 0x81, 0xf5, 0xaa, 0x39, 0xef, 0xc9, 0x8b, 0x2e, + 0xcf, 0x77, 0x95, 0xd9, 0x5f, 0xf7, 0x2e, 0xa1, 0x18, 0x49, 0x5f, 0xbd, 0xe7, 0xaf, 0x17, 0x6c, + 0x90, 0xe1, 0x07, 0xa6, 0x6a, 0xcd, 0xee, 0x67, 0x68, 0x2c, 0x88, 0x03, 0x7f, 0x64, 0x90, 0xff, + 0x77, 0x67, 0x6e, 0xc9, 0xab, 0xf2, 0x8b, 0x5a, 0x38, 0x55, 0x57, 0x14, 0x78, 0x81, 0x5c, 0x72, + 0x44, 0x76, 0x49, 0x66, 0xda, 0x28, 0x3c, 0x30, 0xd7, 0x22, 0xd3, 0xd9, 0xaf, 0x79, 0x89, 0x91, + 0x7d, 0xc1, 0x05, 0x6d, 0x51, 0xd1, 0x5a, 0x74, 0x79, 0xb0, 0x85, 0x09, 0x6d, 0xaa, 0x5f, 0x27, + 0x86, 0xc7, 0xa6, 0x33, 0x93, 0xdd, 0x99, 0x03, 0xd5, 0xef, 0xdc, 0x5b, 0x18, 0x61, 0xe6, 0x61, + 0x67, 0x79, 0xf6, 0xd0, 0xa6, 0x85, 0x5a, 0xed, 0x6a, 0x7d, 0x21, 0x1f, 0x17, 0xc4, 0x99, 0xe1, + 0xd5, 0x74, 0x6e, 0x5b, 0x98, 0xb0, 0xca, 0x65, 0x5b, 0x84, 0xa3, 0x14, 0x08, 0x6c, 0x6f, 0x77, + 0x65, 0x78, 0x5f, 0x0c, 0xc7, 0x45, 0xa1, 0xb9, 0x7d, 0x6c, 0xac, 0x59, 0xe3, 0x39, 0x69, 0x82, + 0x69, 0x82, 0x80, 0xbf, 0x37, 0x23, 0xdb, 0x66, 0x16, 0x24, 0x65, 0x42, 0x7c, 0xc5, 0x6a, 0x74, + 0x3a, 0xe3, 0x77, 0x45, 0x6a, 0x7d, 0xe3, 0x2d, 0x41, 0x4b, 0xc2, 0x3f, 0x6f, 0x97, 0xef, 0xf3, + 0xc9, 0xec, 0x9a, 0x41, 0x64, 0x99, 0xfa, 0x50, 0x9f, 0xa0, 0xda, 0xcd, 0xb6, 0xa9, 0xd1, 0xda, + 0xde, 0x6b, 0x7e, 0xc1, 0xea, 0x5a, 0xf7, 0xe3, 0x28, 0x30, 0x78, 0x37, 0x45, 0x49, 0x01, 0xbb, + 0x36, 0xe5, 0xbc, 0x0e, 0xac, 0x31, 0x31, 0x33, 0x20, 0x39, 0x32, 0x39, 0x20, 0x32, 0x9e, 0x65, + 0x37, 0x91, 0xe3, 0x6a, 0x43, 0x4f, 0x4d, 0xb2, 0xd1, 0x01, 0x42, 0x55, 0xfe, 0x1d, 0x34, 0x28, + 0xe4, 0xb5, 0xeb, 0x26, 0x76, 0x28, 0x28, 0x6a, 0x3a, 0x06, 0x5c, 0x67, 0xb1, 0x65, 0x72, 0x27, + 0x2e, 0x3e, 0x20, 0x62, 0x03, 0xe0, 0x3f, 0x41, 0xe6, 0x3a, 0x70, 0x59, 0x2b, 0x96, 0x15, 0x29, + 0x2f, 0x32, 0x35, 0x35, 0x51, 0x1f, 0xfe, 0x29, 0xfd, 0xc9, 0x9f, 0x9f, 0x2f, 0x6a, 0x71, 0xed, + 0x50, 0xef, 0x66, 0x8b, 0xd7, 0xa1, 0xd7, 0x19, 0xb7, 0x06, 0xe8, 0xab, 0x56, 0x87, 0xbe, 0x34, + 0xef, 0x71, 0x6b, 0x69, 0x91, 0x1a, 0x42, 0x79, 0x71, 0x57, 0x69, 0xb4, 0xb3, 0x9a, 0x22, 0x77, + 0x6a, 0x52, 0xd7, 0x21, 0xb8, 0x49, 0x17, 0x22, 0x6c, 0x7c, 0xc2, 0x48, 0x26, 0x72, 0x68, 0x0c, + 0x5b, 0xdb, 0x5f, 0x0f, 0x52, 0x4b, 0x83, 0xde, 0xf1, 0x75, 0x9b, 0x20, 0x3e, 0xe7, 0x5a, 0xf2, + 0x8c, 0x29, 0x5a, 0x75, 0x94, 0xc5, 0xd7, 0x38, 0x6e, 0xb0, 0x99, 0xd1, 0xad, 0x09, 0xd5, 0x53, + 0x1f, 0xac, 0x72, 0xe1, 0x67, 0x5a, 0x94, 0xc4, 0x8b, 0x27, 0x99, 0x6d, 0x7d, 0xa7, 0x86, 0x4d, + 0xd9, 0xfa, 0xb0, 0xcb, 0xd5, 0x85, 0x29, 0xd7, 0x7f, 0x5a, 0xff, 0xec, 0xd1, 0xb5, 0xd1, 0x65, + 0x41, 0x48, 0xf6, 0x99, 0x57, 0x2d, 0x08, 0xec, 0x9e, 0xc0, 0xd4, 0x5b, 0xb9, 0xc5, 0x28, 0xce, + 0xe1, 0x95, 0x8b, 0x17, 0x95, 0x71, 0xbf, 0x35, 0x15, 0xeb, 0xc6, 0x4e, 0x76, 0xd6, 0x6f, 0x6b, + 0x8f, 0xab, 0x96, 0x25, 0x6a, 0x9d, 0xf1, 0xf7, 0x0a, 0x59, 0xe8, 0x8e, 0x93, 0x63, 0x85, 0xd8, + 0x45, 0x6a, 0xcf, 0x97, 0x9a, 0xdb, 0x2c, 0x9b, 0x3f, 0x72, 0xcd, 0x7e, 0x70, 0xdb, 0x6d, 0xae, + 0x9b, 0x5f, 0x6b, 0x8a, 0x1d, 0x9a, 0x76, 0xef, 0x9d, 0xb3, 0x96, 0x09, 0x9b, 0xbd, 0x9e, 0xcb, + 0xdf, 0x87, 0x2c, 0xb5, 0xe1, 0x5d, 0x62, 0x79, 0xbd, 0x3b, 0x00, 0x74, 0x6f, 0xf1, 0x28, 0x98, + 0x9a, 0x0b, 0xb9, 0x9f, 0x8a, 0x1e, 0x27, 0x86, 0x4b, 0x2e, 0xcf, 0x44, 0x2b, 0x99, 0xdb, 0xb3, + 0x4d, 0xf7, 0x5e, 0x7b, 0x28, 0x83, 0x7f, 0x53, 0xd5, 0xd3, 0x20, 0xcf, 0xe5, 0x9f, 0xa5, 0xeb, + 0x69, 0x9a, 0x6b, 0x19, 0x77, 0x27, 0x62, 0x3c, 0x07, 0x65, 0x6c, 0x63, 0xa5, 0x17, 0x9a, 0xb6, + 0x10, 0xaa, 0x63, 0x19, 0x68, 0x72, 0x99, 0x99, 0xba, 0x59, 0x5e, 0x2c, 0x94, 0xae, 0x75, 0x45, + 0xa2, 0x95, 0x77, 0x38, 0xf2, 0x2d, 0x4f, 0x51, 0x73, 0xb1, 0x6f, 0x36, 0xff, 0x57, 0x0d, 0x45, + 0x6f, 0xf7, 0x47, 0x5c, 0xdf, 0x15, 0x73, 0x2e, 0x8b, 0x61, 0x19, 0x37, 0x45, 0xcf, 0x8d, 0x6e, + 0xdd, 0x13, 0xba, 0x55, 0xe3, 0x36, 0xb0, 0xbc, 0x00, 0x1a, 0x2d, 0x17, 0xfc, 0x2e, 0x22, 0x5e, + 0xd5, 0x16, 0x9d, 0x58, 0xb2, 0x53, 0x69, 0x3a, 0xa8, 0xed, 0x6f, 0xe6, 0x71, 0x1e, 0x65, 0xb1, + 0xf3, 0xbb, 0x25, 0xf5, 0x83, 0x6f, 0x63, 0x80, 0x0d, 0x79, 0x89, 0x9b, 0xd1, 0xfb, 0x72, 0xf9, + 0x03, 0x7c, 0x7b, 0x29, 0x2b, 0x7e, 0x33, 0x25, 0x87, 0xcf, 0xbc, 0x15, 0xdb, 0xa6, 0x47, 0x18, + 0x6e, 0x83, 0xb9, 0xfd, 0x6d, 0x36, 0x22, 0x31, 0x22, 0xa8, 0x33, 0xa7, 0x66, 0x89, 0xc1, 0x24, + 0x67, 0x87, 0xf3, 0x3e, 0x99, 0x48, 0x9d, 0x57, 0x56, 0x7d, 0x82, 0x42, 0x3c, 0x1e, 0x30, 0xc9, + 0xf1, 0x95, 0x5d, 0x4c, 0xf5, 0x08, 0xc6, 0x6e, 0xe0, 0x12, 0xdb, 0xdc, 0x7f, 0x43, 0x43, 0x83, + 0xd9, 0x7f, 0x52, 0x41, 0x54, 0x90, 0xef, 0x44, 0x2d, 0x46, 0x41, 0x55, 0x4c, 0x54, 0xf1, 0x89, + 0x9a, 0x1c, 0xe8, 0x6f, 0x89, 0x63, 0x29, 0xaa, 0x77, 0xd5, 0xe9, 0x01, 0x1b, 0x2e, 0x76, 0x09, + 0x9f, 0xbd, 0x5e, 0x22, 0xe7, 0x8b, 0xe9, 0x76, 0x21, 0x69, 0xf1, 0xb1, 0x93, 0xb3, 0x95, 0xb1, + 0x5f, 0xa9, 0x8a, 0x11, 0x64, 0x74, 0x46, 0x65, 0xb6, 0xa7, 0x9a, 0xec, 0xa3, 0xe9, 0xa0, 0xbc, + 0x6a, 0x61, 0x2b, 0x7f, 0x06, 0x25, 0xc7, 0x2e, 0xaf, 0x8d, 0x4b, 0xb1, 0xbd, 0xae, 0x39, 0x55, + 0xad, 0x55, 0xda, 0x71, 0x04, 0x25, 0xa2, 0x17, 0x6c, 0xb1, 0x5b, 0x9d, 0x51, 0x22, 0x51, 0xbf, + 0x30, 0x83, 0x55, 0x7b, 0x37, 0x25, 0xd6, 0x6f, 0x99, 0x26, 0x0d, 0x94, 0x6b, 0x6f, 0x6b, 0x01, + 0x72, 0x77, 0x68, 0x1a, 0x07, 0x99, 0x32, 0xec, 0x66, 0xa7, 0xbd, 0x3f, 0xd2, 0xd9, 0xde, 0xa3, + 0x99, 0x6a, 0x95, 0xdb, 0x25, 0xd9, 0xee, 0x42, 0x42, 0xc5, 0x7b, 0x38, 0x2d, 0x25, 0xf3, 0x58, + 0xf5, 0xa5, 0xa8, 0x6d, 0x6f, 0x58, 0x67, 0x6d, 0x94, 0x86, 0x53, 0x94, 0xc9, 0x9a, 0x79, 0x70, + 0x64, 0x10, 0x77, 0x78, 0x29, 0xed, 0xa6, 0x6d, 0xc0, 0xa7, 0x95, 0x8d, 0xb4, 0x21, 0x6a, 0x27, + 0xe4, 0x33, 0x63, 0x2a, 0x61, 0x18, 0x27, 0x2d, 0x73, 0x2b, 0xa6, 0x9d, 0x8d, 0x9f, 0x91, 0x6a, + 0xe7, 0xad, 0x57, 0x35, 0x6b, 0xeb, 0x64, 0x2e, 0xc7, 0xe0, 0x2c, 0x69, 0xef, 0xfd, 0xac, 0x3b, + 0xa6, 0x9e, 0xed, 0xf1, 0x64, 0x36, 0x5d, 0x8b, 0xe3, 0x1a, 0x52, 0xe5, 0x2b, 0xa7, 0x14, 0xc9, + 0x19, 0xc7, 0x3a, 0x67, 0x5d, 0x2e, 0x90, 0x7e, 0x9d, 0xd9, 0xd7, 0x6d, 0x5a, 0x19, 0x5f, 0x13, + 0x89, 0xab, 0x5b, 0x19, 0xdf, 0xd0, 0x8d, 0xa1, 0xfe, 0x27, 0x0d, 0xb9, 0x25, 0xf7, 0xf9, 0x0d, + 0xb9, 0xea, 0x6d, 0xb7, 0xfe, 0x2c, 0x0d, 0x6b, 0x74, 0x47, 0xe1, 0x74, 0xf9, 0x13, 0xa7, 0xf7, + 0x4f, 0xc6, 0x65, 0xb1, 0x13, 0x62, 0x72, 0x2b, 0x9a, 0xa6, 0x6b, 0x69, 0x68, 0x59, 0x38, 0x1c, + 0x03, 0xde, 0xf2, 0xf5, 0xd5, 0xfd, 0x70, 0xcb, 0x69, 0x95, 0x76, 0x42, 0xbe, 0x6d, 0x5f, 0x26, + 0xc3, 0xd6, 0xaa, 0xbe, 0xa1, 0x8b, 0xff, 0x79, 0x39, 0x41, 0xc5, 0x6c, 0xfb, 0x5a, 0x13, 0xc9, + 0xfd, 0x8b, 0xf9, 0xb6, 0x5f, 0x67, 0xa6, 0x13, 0x0b, 0x2a, 0x86, 0x50, 0xe7, 0xc0, 0x6b, 0xc6, + 0x77, 0x53, 0xbf, 0x67, 0xe5, 0xfc, 0x93, 0xd9, 0x40, 0x75, 0x16, 0x25, 0xe3, 0xcb, 0x78, 0x86, + 0x7b, 0x79, 0xdd, 0x13, 0x85, 0xc9, 0x28, 0xd5, 0x6d, 0xbd, 0xb4, 0x67, 0x63, 0x57, 0x95, 0xdb, + 0x3f, 0x01, 0x37, 0x4e, 0x65, 0x77, 0xf2, 0x03, 0xde, 0xa7, 0xe3, 0x89, 0x6f, 0x6c, 0xfd, 0x3b, + 0x97, 0x7e, 0xf7, 0x11, 0xd1, 0x6e, 0x62, 0xfa, 0x2e, 0x19, 0x7e, 0x8f, 0x0b, 0xda, 0x29, 0x61, + 0xfa, 0x3e, 0x0d, 0xdf, 0x77, 0x57, 0x8e, 0x1f, 0x9b, 0x8b, 0xed, 0xa5, 0x14, 0xda, 0xbb, 0x49, + 0x27, 0x9e, 0x1b, 0x78, 0xe9, 0xf5, 0x6e, 0xfc, 0x71, 0xed, 0xf8, 0x61, 0x17, 0x67, 0x72, 0x7e, + 0x12, 0x9b, 0x47, 0x5d, 0x2b, 0xaa, 0x9d, 0xff, 0x1b, 0x6e, 0x66, 0x97, 0x7b, 0x9e, 0x04, 0xf3, + 0xb9, 0x9e, 0x5f, 0x61, 0xa2, 0x1f, 0xa9, 0xa2, 0x81, 0xde, 0xe3, 0xab, 0xdf, 0xa7, 0x0d, 0x55, + 0xc4, 0x50, 0xbb, 0x77, 0xd2, 0xfa, 0x0d, 0x3a, 0x64, 0x57, 0x45, 0xc3, 0x87, 0x29, 0xbc, 0x3b, + 0xab, 0xa1, 0x44, 0xbb, 0x2a, 0xcf, 0x7f, 0x9a, 0x49, 0xda, 0xa4, 0x83, 0x62, 0x73, 0x77, 0x4b, + 0x47, 0x56, 0x12, 0x7a, 0xbc, 0xb9, 0xd8, 0x7e, 0x77, 0x27, 0xb9, 0x6b, 0xe3, 0x8b, 0x9b, 0xb3, + 0x73, 0x0d, 0x6e, 0xda, 0x8c, 0x9e, 0xdd, 0x5e, 0x10, 0xd7, 0xaf, 0xab, 0x67, 0xb3, 0xb6, 0x03, + 0x7a, 0x3d, 0x9f, 0x87, 0xdb, 0xa5, 0x5b, 0x11, 0x3a, 0x72, 0x4d, 0x8d, 0xf5, 0xeb, 0x9f, 0x31, + 0x66, 0x99, 0x99, 0x38, 0xbe, 0x24, 0xfb, 0xee, 0x1a, 0x69, 0xe2, 0x77, 0xdf, 0x86, 0x89, 0xab, + 0x3a, 0x2d, 0x5a, 0x73, 0x1a, 0x48, 0x9b, 0x40, 0xd7, 0x3f, 0x51, 0xb0, 0x72, 0xac, 0x6f, 0x65, + 0x48, 0x5f, 0xec, 0x51, 0xa6, 0xa1, 0x71, 0xfb, 0x76, 0x65, 0x5f, 0x6b, 0xb7, 0x67, 0x50, 0x08, + 0x22, 0x6e, 0xa7, 0xb5, 0xc3, 0xa9, 0xef, 0x99, 0x2b, 0x9a, 0x71, 0x7b, 0x28, 0xfb, 0x29, 0x67, + 0xe8, 0xa3, 0xd6, 0xe9, 0xc7, 0x55, 0xa5, 0x1d, 0xeb, 0x6d, 0x4f, 0x5c, 0x04, 0x70, 0xb1, 0x45, + 0x8d, 0xb4, 0x1b, 0xf6, 0x72, 0x82, 0xd0, 0x6d, 0x95, 0x0c, 0xc0, 0x49, 0x96, 0xb1, 0xa6, 0xca, + 0x8d, 0xc9, 0xb2, 0x99, 0x6e, 0xb7, 0x45, 0x17, 0x61, 0x6b, 0x6d, 0x79, 0x96, 0xcc, 0xa3, 0x07, + 0xd6, 0x56, 0xad, 0xf1, 0xae, 0x69, 0x91, 0xdb, 0xe6, 0x43, 0xdd, 0x8b, 0xf1, 0x5f, 0xae, 0xd9, + 0x71, 0xf7, 0xe5, 0x69, 0xbf, 0xe4, 0x5b, 0xb6, 0x6a, 0x44, 0xf2, 0x9d, 0xa7, 0xb2, 0x31, 0xd2, + 0x33, 0xdb, 0x26, 0x6d, 0xf0, 0xfc, 0x74, 0xd5, 0x34, 0x85, 0x6e, 0xe2, 0xed, 0xe7, 0xbc, 0x2f, + 0xe7, 0xb3, 0xd3, 0xf6, 0xae, 0x79, 0xe7, 0xec, 0xdd, 0xf7, 0xcf, 0x6f, 0x1b, 0x74, 0x25, 0xc9, + 0xa4, 0xf7, 0x77, 0x7f, 0x3d, 0x19, 0xb5, 0xe9, 0x37, 0xc7, 0x71, 0x64, 0x49, 0x27, 0x0f, 0xe7, + 0x85, 0x6b, 0xe2, 0x35, 0xd1, 0xe6, 0x68, 0x7c, 0x2c, 0x53, 0x33, 0x65, 0x6e, 0x20, 0x76, 0x86, + 0xb9, 0x5d, 0x97, 0x18, 0xaa, 0x51, 0x91, 0x8d, 0x3d, 0xa9, 0x1e, 0x85, 0xf5, 0xf3, 0xae, 0x8b, + 0xcf, 0xe7, 0xe9, 0x71, 0x55, 0x80, 0x3d, 0xae, 0x9f, 0xc9, 0xf1, 0x4e, 0xf3, 0xf3, 0x0d, 0x74, + 0x67, 0xd3, 0xa9, 0x07, 0x96, 0x70, 0x2e, 0xa1, 0x70, 0x16, 0x68, 0x21, 0x75, 0x6c, 0xaf, 0xce, + 0x01, 0x9b, 0x39, 0xf9, 0x5a, 0x7a, 0x50, 0xf5, 0xcd, 0x6b, 0x98, 0x78, 0x9b, 0xe7, 0x41, 0x6c, + 0x77, 0x61, 0x79, 0x73, 0xeb, 0x77, 0xff, 0xe2, 0xf1, 0xa6, 0xf1, 0xdb, 0x9d, 0xbd, 0xae, 0xcb, + 0x37, 0xae, 0x6b, 0xa3, 0x75, 0xe1, 0x66, 0xae, 0x9e, 0x7b, 0x55, 0xbf, 0x55, 0x9b, 0xd4, 0x3f, + 0x53, 0xf6, 0xba, 0x6d, 0x8d, 0xb8, 0x21, 0xde, 0xcb, 0xc9, 0x6b, 0xb2, 0xf1, 0xb6, 0xbb, 0x3e, + 0xa9, 0x6a, 0x77, 0x7d, 0xdb, 0xe5, 0x9e, 0xb9, 0x55, 0xeb, 0x68, 0xe7, 0xf7, 0xae, 0x7e, 0x81, + 0x6b, 0xe6, 0x09, 0x9e, 0xe8, 0xe5, 0xee, 0x68, 0x7b, 0x9a, 0x1e, 0x13, 0xac, 0xd1, 0xf6, 0xbe, + 0x2f, 0x35, 0x7f, 0xa6, 0x4f, 0xbc, 0x83, 0x53, 0x54, 0x7f, 0x45, 0x41, 0x4d, 0xd7, 0xc3, 0xbe, + 0x2c, 0x20, 0x36, 0x34, 0x20, 0x28, 0x28, 0x78, 0x90, 0x5e, 0x3c, 0x0c, 0xf9, 0x4f, 0xf3, 0x6b, + 0x2d, 0x33, 0x29, 0xb4, 0x41, 0x93, 0x34, 0x29, 0x79, 0xe6, 0x95, 0xf9, 0x6a, 0x2e, 0xa1, 0x67, + 0x7e, 0xa8, 0xc1, 0xc7, 0x28, 0x98, 0xe4, 0x81, 0x55, 0x09, 0x90, 0xfa, 0xce, 0xa5, 0x78, 0x33, + 0xc9, 0x5f, 0x74, 0x57, 0x1f, 0xaa, 0x96, 0x23, 0xa3, 0x33, 0x46, 0x2f, 0xa6, 0xe4, 0xc7, 0xe5, + 0xbc, 0x21, 0x96, 0x16, 0x86, 0x8f, 0xc5, 0x4d, 0x63, 0x0e, 0x20, 0x12, 0x2e, 0x61, 0x74, 0x1a, + 0x60, 0x1c, 0x74, 0xdd, 0x11, 0x3a, 0x79, 0xb6, 0xca, 0xa2, 0x2b, 0x4e, 0x75, 0x6f, 0x9c, 0xb3, + 0x6c, 0x62, 0x5d, 0xd8, 0x6c, 0x7e, 0x72, 0x89, 0x17, 0x11, 0x12, 0x21, 0x7b, 0xfd, 0x87, 0xd7, + 0x46, 0xe9, 0x19, 0xa7, 0x95, 0xe2, 0x52, 0x7a, 0x6d, 0x24, 0xcd, 0x4e, 0x95, 0x1a, 0x69, 0xaa, + 0x36, 0xcf, 0x95, 0xd6, 0x29, 0x7b, 0x50, 0xcd, 0x0f, 0x97, 0x9c, 0xea, 0xfb, 0x59, 0xeb, 0x2f, + 0x57, 0xa3, 0xdd, 0xf7, 0x2d, 0x57, 0x54, 0xd8, 0x3d, 0x4c, 0x7f, 0x62, 0x85, 0x97, 0x20, 0xe9, + 0x6f, 0x36, 0x44, 0x4c, 0x4c, 0xaa, 0x9a, 0x4d, 0x64, 0x36, 0xf2, 0x65, 0x77, 0x53, 0x5f, 0xd7, + 0x30, 0x6d, 0x6d, 0x48, 0xf6, 0x6f, 0x64, 0x6a, 0xa8, 0x6d, 0xb6, 0xeb, 0x5e, 0x1d, 0xf1, 0xf9, + 0x99, 0x3a, 0x8e, 0x8d, 0x25, 0x81, 0xe0, 0x7b, 0xca, 0x9f, 0x78, 0x03, 0x11, 0x62, 0x9e, 0x5b, + 0xca, 0xf7, 0xc8, 0x5d, 0x3b, 0x1d, 0x7d, 0xc9, 0xa7, 0x9c, 0x00, 0xf3, 0xe6, 0xc5, 0x8f, 0xce, + 0xb3, 0xb5, 0x47, 0x25, 0xf2, 0x7b, 0xe7, 0x73, 0xf0, 0xa9, 0x77, 0xbe, 0x2d, 0x3d, 0x69, 0x9d, + 0xcb, 0x3d, 0x62, 0x43, 0x7e, 0x95, 0x2b, 0xb3, 0xf6, 0xd3, 0x24, 0x61, 0xd4, 0xca, 0x13, 0xc4, + 0x50, 0x0a, 0x66, 0x29, 0x17, 0x85, 0x63, 0x2a, 0x16, 0xbb, 0x65, 0x6e, 0x52, 0x03, 0xe3, 0x9a, + 0xd6, 0x39, 0x5a, 0x0d, 0x96, 0x47, 0xd5, 0x8e, 0x1d, 0x8f, 0x05, 0x97, 0x95, 0x09, 0x66, 0x75, + 0x91, 0x08, 0xc9, 0xcd, 0xc0, 0x91, 0x74, 0x6b, 0xd9, 0x1d, 0xd6, 0x97, 0xf0, 0x36, 0x6e, 0xdb, + 0x60, 0x3b, 0x78, 0x9e, 0x68, 0x36, 0x2d, 0xd9, 0x56, 0xa3, 0x4f, 0x1a, 0x29, 0x3d, 0x3f, 0x56, + 0x53, 0x0a, 0x8a, 0x25, 0x79, 0x10, 0x6b, 0x0e, 0xdd, 0x0d, 0x6d, 0x08, 0x17, 0xd9, 0x0b, 0x95, + 0xb9, 0xfd, 0x25, 0x1a, 0x79, 0x24, 0xf5, 0xdd, 0x6f, 0x59, 0xad, 0x36, 0xb8, 0x51, 0xd6, 0xca, + 0xb5, 0x31, 0x55, 0xe8, 0xaf, 0xe3, 0x6a, 0xb8, 0xe1, 0xd5, 0x17, 0x9e, 0xa1, 0x61, 0xcb, 0xa3, + 0xe3, 0x4f, 0x2d, 0x72, 0x4d, 0xb7, 0xfc, 0x57, 0xf4, 0x01, 0xb7, 0x77, 0x03, 0x3e, 0xfb, 0x9d, + 0xd2, 0xb2, 0xc8, 0x66, 0x44, 0x69, 0x7e, 0xda, 0x0d, 0x95, 0x41, 0x99, 0x62, 0xd9, 0xdf, 0x49, + 0x42, 0x31, 0x86, 0xc6, 0x79, 0xac, 0x83, 0xd2, 0xc7, 0xdc, 0xbb, 0x81, 0x41, 0x82, 0xfe, 0x70, + 0x1e, 0x76, 0x8b, 0x0b, 0x7e, 0x9d, 0x97, 0xa8, 0xbb, 0x21, 0x67, 0x6f, 0xf2, 0xe8, 0x38, 0x6e, + 0x2c, 0x4b, 0x27, 0x93, 0x13, 0x27, 0x49, 0x6e, 0xb8, 0xc6, 0x29, 0x6d, 0x68, 0x04, 0x5d, 0xe5, + 0xbe, 0x7e, 0xfa, 0x37, 0x0d, 0xbb, 0x28, 0x1f, 0x6f, 0x30, 0xa3, 0x2b, 0x7c, 0x71, 0x79, 0x22, + 0x21, 0x45, 0x52, 0xaa, 0x74, 0xff, 0xa3, 0xb4, 0x59, 0x9d, 0xe5, 0x7f, 0x66, 0x57, 0xa9, 0xc7, + 0xf6, 0xe0, 0x35, 0xdd, 0x4b, 0x42, 0x29, 0xd1, 0x75, 0x85, 0xda, 0x0f, 0x76, 0x6d, 0xa6, 0xab, + 0x69, 0xd9, 0x39, 0xd7, 0xe8, 0xe5, 0xd5, 0x1f, 0xba, 0x39, 0xbf, 0x6a, 0xb2, 0xe2, 0x87, 0xe6, + 0xd4, 0xe7, 0x56, 0x79, 0x75, 0x5b, 0x7a, 0x29, 0x99, 0xf9, 0xbd, 0x9f, 0xbc, 0x05, 0xa0, 0x27, + 0x7b, 0x06, 0xf6, 0x27, 0xb6, 0x75, 0x75, 0x81, 0xbe, 0x37, 0x2b, 0x76, 0xa7, 0x6a, 0x7c, 0xca, + 0x93, 0x95, 0x84, 0xb6, 0x8f, 0xf5, 0x69, 0x28, 0xaa, 0xe7, 0xc5, 0x6a, 0xbc, 0x31, 0xad, 0xbc, + 0x71, 0x82, 0x49, 0xf1, 0x50, 0xa6, 0x57, 0x97, 0x9f, 0x55, 0x28, 0x06, 0x6a, 0xae, 0x5b, 0xbe, + 0xc4, 0xa3, 0xa3, 0x69, 0x85, 0x95, 0x97, 0x96, 0x47, 0xa4, 0x2b, 0x1e, 0x75, 0xa7, 0x49, 0x6f, + 0x36, 0x9f, 0x9b, 0x9c, 0xb5, 0x6b, 0xee, 0x7f, 0xe7, 0x6b, 0xbd, 0x6b, 0xdf, 0xd7, 0x41, 0xec, + 0xf7, 0xdb, 0xf9, 0x79, 0xed, 0xc7, 0xe7, 0xff, 0x2b, 0xbb, 0x9a, 0xb2, 0x89, 0x7f, 0xf3, 0x47, + 0xd6, 0xcd, 0x7a, 0x53, 0xc9, 0x37, 0x67, 0x50, 0xb9, 0xd7, 0xf7, 0xff, 0x76, 0x25, 0x6a, 0x82, + 0xe3, 0xf7, 0x66, 0x81, 0x9b, 0x37, 0x7d, 0xfe, 0x2b, 0xeb, 0x4d, 0x99, 0xf7, 0x39, 0x6b, 0xd9, + 0x2d, 0xc7, 0x5f, 0xfe, 0x36, 0xc7, 0xdd, 0x9d, 0xa6, 0xf3, 0xe6, 0xcb, 0xb9, 0xe6, 0x1a, 0xfd, + 0xb2, 0xfd, 0x9a, 0xb6, 0xfb, 0x56, 0x27, 0xad, 0xc1, 0xb6, 0xbe, 0x6e, 0x85, 0x7f, 0x3c, 0xc5, + 0x87, 0x61, 0x76, 0x97, 0xad, 0x36, 0x23, 0xce, 0x8f, 0xda, 0x39, 0xf9, 0xfb, 0x99, 0x55, 0xdb, + 0xcf, 0x6a, 0x75, 0x33, 0x94, 0x1a, 0x0a, 0x6c, 0xfe, 0x25, 0xa3, 0x5e, 0xbc, 0xad, 0xb5, 0x92, + 0xeb, 0x9d, 0xc9, 0x51, 0xc7, 0xdf, 0x77, 0x3c, 0xa7, 0x57, 0xa8, 0x1c, 0x5b, 0x9d, 0xe9, 0xdf, + 0x61, 0xf7, 0x8d, 0xa3, 0x47, 0x25, 0x42, 0x26, 0xcd, 0xa5, 0x01, 0xbf, 0x77, 0xa5, 0xf4, 0x67, + 0x70, 0x64, 0x04, 0x27, 0x56, 0xfc, 0xe9, 0x7f, 0x5a, 0xc9, 0x9a, 0x33, 0x7b, 0xc5, 0x31, 0x74, + 0xa1, 0xbb, 0xbf, 0x6a, 0x28, 0xb5, 0x09, 0xfc, 0xe5, 0xb6, 0xe6, 0x27, 0x99, 0x28, 0xaa, 0xe3, + 0x31, 0x9f, 0x19, 0x8d, 0x5d, 0x15, 0x2c, 0xbb, 0xa5, 0xe1, 0xbb, 0x39, 0x7b, 0x5a, 0xbb, 0x6e, + 0x51, 0x5a, 0xd6, 0xcf, 0xb3, 0x65, 0xab, 0x6b, 0xa6, 0x7d, 0xbf, 0xad, 0xbd, 0xad, 0x5e, 0x51, + 0x66, 0x7f, 0xba, 0x75, 0xb3, 0xee, 0xb0, 0x42, 0x72, 0xed, 0x5a, 0xa7, 0xdf, 0xe1, 0x9d, 0x61, + 0xf6, 0xb2, 0xd5, 0xa6, 0x96, 0xd3, 0xed, 0xa7, 0xfa, 0x6f, 0x86, 0x4d, 0xec, 0xab, 0xab, 0xd8, + 0xad, 0x6e, 0xcb, 0x35, 0x8a, 0x5a, 0x44, 0x45, 0x43, 0x4f, 0x06, 0xe7, 0x21, 0x45, 0xec, 0x34, + 0x47, 0xe9, 0xbb, 0x75, 0x89, 0x33, 0xf6, 0xed, 0x95, 0xf7, 0xee, 0x71, 0xc5, 0x20, 0xbb, 0x39, + 0xa7, 0xaf, 0x2b, 0x41, 0x5d, 0x4b, 0xaf, 0x6a, 0x53, 0x5d, 0xc1, 0xaf, 0x3e, 0x5f, 0x75, 0x31, + 0x6b, 0xa0, 0xc7, 0x6b, 0xd9, 0x97, 0x7d, 0x33, 0xbe, 0x6e, 0x69, 0xdb, 0xe6, 0x51, 0xf7, 0xa6, + 0xe7, 0x56, 0xd1, 0xbd, 0x83, 0x4e, 0xd7, 0x6c, 0x89, 0x7d, 0xd5, 0x47, 0x2b, 0x9b, 0x2c, 0xe3, + 0x9d, 0xb6, 0xb8, 0xb1, 0xaf, 0x6b, 0x9d, 0xaf, 0xa1, 0xdb, 0xb1, 0x95, 0xaf, 0xf6, 0x21, 0x5b, + 0x4a, 0xb3, 0xfb, 0xa6, 0xf8, 0x31, 0xda, 0xe7, 0xa5, 0xad, 0xdf, 0x57, 0x7c, 0x5f, 0xa5, 0xba, + 0x71, 0x87, 0x2e, 0xba, 0x79, 0xfd, 0x39, 0x5f, 0xbb, 0x3a, 0x09, 0x97, 0x61, 0x6e, 0xdb, 0x15, + 0xd7, 0x47, 0x6e, 0xcf, 0x21, 0xde, 0x4a, 0x72, 0x9b, 0xd8, 0x31, 0xfd, 0xaf, 0x3d, 0xed, 0x79, + 0x01, 0x3b, 0xe7, 0x13, 0x28, 0xb7, 0xb5, 0x27, 0xde, 0x9a, 0x55, 0x69, 0xeb, 0xf7, 0xa9, 0x2f, + 0xb9, 0x8d, 0xd9, 0xbf, 0x8d, 0xf5, 0xbf, 0x8d, 0xcf, 0xbb, 0xcd, 0xfd, 0xb8, 0x43, 0xa6, 0xbd, + 0x79, 0x8a, 0x3b, 0x53, 0x65, 0x74, 0x74, 0x98, 0x3a, 0x5b, 0x73, 0xd6, 0xae, 0x77, 0xe7, 0xea, + 0x36, 0x9f, 0x06, 0x05, 0x29, 0xbd, 0xa7, 0xb1, 0x31, 0xb9, 0x79, 0x36, 0x4f, 0x4b, 0x2c, 0xe6, + 0x8b, 0xa5, 0x50, 0x8e, 0xe3, 0xb5, 0x27, 0xda, 0xf3, 0x95, 0xe8, 0x7a, 0x2a, 0x29, 0x29, 0xaf, + 0xce, 0x33, 0x61, 0x53, 0xab, 0x8b, 0x45, 0x77, 0x39, 0x66, 0xb3, 0x6b, 0xb6, 0x51, 0xd9, 0xeb, + 0x6e, 0xf8, 0x31, 0x5e, 0x3e, 0x1a, 0xfd, 0xe6, 0xc1, 0x79, 0x11, 0x18, 0x22, 0x1f, 0xd0, 0x12, + 0x67, 0x56, 0x3c, 0x8c, 0xbb, 0x61, 0x95, 0x50, 0xfc, 0x3d, 0xa6, 0xaf, 0x75, 0xb3, 0x65, 0xc5, + 0x2a, 0x86, 0x1f, 0x62, 0x2a, 0xcb, 0x13, 0xdd, 0xf1, 0x6d, 0x9f, 0x9a, 0xfc, 0xd5, 0xa6, 0x9d, + 0x35, 0xf1, 0x77, 0xae, 0x9a, 0x4f, 0x72, 0x3c, 0x69, 0x75, 0x70, 0x61, 0x6e, 0xdd, 0xff, 0x6a, + 0x00, 0x67, 0x6d, 0xcb, 0x8f, 0x58, 0xc4, 0x27, 0x6b, 0x99, 0x0f, 0xf9, 0xca, 0x8a, 0xc9, 0x6b, + 0xde, 0xb5, 0x7b, 0xa6, 0xbb, 0x76, 0x1f, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x61, 0xfe, 0x26, 0x6f, + 0x96, 0xa3, 0x8d, 0xd9, 0x45, 0x9e, 0x46, 0x6e, 0x77, 0xa7, 0xfb, 0x34, 0x39, 0x45, 0xd9, 0x0c, + 0xaa, 0x1f, 0xe7, 0x02, 0x27, 0x75, 0x66, 0x26, 0x26, 0xc5, 0xfb, 0x3d, 0x57, 0x4d, 0x34, 0x4b, + 0x9c, 0x9d, 0x65, 0x73, 0x55, 0x8d, 0x59, 0xfe, 0x99, 0x1f, 0x95, 0x5d, 0x9e, 0x68, 0x9a, 0x0b, + 0xe1, 0x26, 0x29, 0xdf, 0x8f, 0x85, 0x7f, 0x21, 0xed, 0x68, 0xdb, 0x5e, 0xe8, 0xf3, 0xd9, 0x33, + 0x6b, 0xac, 0x0d, 0xf5, 0x2c, 0xda, 0x68, 0xf8, 0xf9, 0xc5, 0x20, 0xca, 0xfd, 0x91, 0x7f, 0x76, + 0x7a, 0x37, 0x19, 0x2e, 0xb1, 0x87, 0x4c, 0xff, 0x75, 0xb3, 0x7c, 0x8a, 0x9f, 0x9b, 0xfc, 0x64, + 0x3e, 0x79, 0x49, 0x90, 0x78, 0x42, 0x96, 0x97, 0xc6, 0x7b, 0xe6, 0x5f, 0x6f, 0xf7, 0x6b, 0x55, + 0x01, 0x3d, 0xa6, 0xac, 0x53, 0xdb, 0x1e, 0x27, 0xeb, 0x2d, 0xc9, 0x9e, 0x92, 0xdd, 0x86, 0x02, + 0x1a, 0x1d, 0xed, 0xd7, 0x1a, 0x27, 0xbe, 0x2b, 0xc9, 0x6a, 0xd7, 0x8b, 0x94, 0x41, 0x49, 0x7e, + 0xe3, 0xb7, 0xda, 0xe2, 0xd5, 0x98, 0x33, 0x6d, 0xc5, 0xc7, 0x2e, 0x3b, 0x5f, 0x67, 0x81, 0x6e, + 0x5a, 0xa5, 0x7c, 0xb3, 0x50, 0x73, 0x20, 0xa6, 0x6e, 0x6b, 0x8b, 0xff, 0x69, 0xc8, 0x04, 0xa4, + 0x79, 0x76, 0x65, 0x72, 0x34, 0xf8, 0xbb, 0xd9, 0x19, 0x57, 0x00, 0x75, 0x6a, 0xd1, 0xdd, 0xc7, + 0xec, 0x90, 0x5f, 0x41, 0xea, 0x6c, 0x6b, 0x94, 0xfd, 0x31, 0xda, 0xe8, 0xd5, 0x1c, 0x38, 0x73, + 0xd7, 0x12, 0x69, 0x69, 0x8b, 0xad, 0xaa, 0x1b, 0x6c, 0x2d, 0x3b, 0x7d, 0xf1, 0xff, 0x8c, 0x4b, + 0x36, 0x57, 0xa5, 0xa4, 0x45, 0x6b, 0x5f, 0x65, 0xaa, 0x79, 0x17, 0x97, 0x2f, 0xee, 0x75, 0x39, + 0xac, 0x45, 0xb8, 0xcb, 0x4f, 0x5c, 0xaa, 0x15, 0x71, 0x13, 0xdb, 0x10, 0x13, 0xa7, 0xad, 0x6f, + 0xd9, 0x47, 0xbe, 0x3d, 0xab, 0x67, 0xcd, 0xff, 0x2d, 0xa5, 0xfb, 0x9d, 0x41, 0xa9, 0xf7, 0x96, + 0xcc, 0xc5, 0xc5, 0xa7, 0x5a, 0x76, 0xa6, 0xb3, 0xb6, 0xe6, 0xa2, 0xee, 0x6e, 0x3b, 0x6e, 0x76, + 0xef, 0xf3, 0xa9, 0xa9, 0xbe, 0xf2, 0xdf, 0xfa, 0x7a, 0xe3, 0xe5, 0xf6, 0x3b, 0x2b, 0xa7, 0xaf, + 0x7d, 0x43, 0xe9, 0xef, 0x6e, 0xa9, 0x0d, 0xde, 0x8b, 0xcf, 0xc7, 0x3a, 0xb1, 0x2b, 0xc9, 0xa9, + 0xbf, 0x5e, 0x81, 0xca, 0x2d, 0xb1, 0x77, 0x1a, 0xbe, 0x6b, 0xbe, 0x3d, 0x73, 0xa3, 0x67, 0x74, + 0x17, 0x7a, 0x62, 0xb7, 0x19, 0x69, 0xd2, 0xa3, 0x3f, 0xb7, 0xeb, 0x99, 0x4f, 0xab, 0xe2, 0x5b, + 0x77, 0x1d, 0xc7, 0x78, 0xe3, 0x33, 0x99, 0x01, 0xc6, 0x79, 0xeb, 0x73, 0x4b, 0x25, 0x6e, 0x64, + 0x2d, 0x3c, 0xf4, 0x66, 0x2b, 0x9e, 0xe3, 0xb7, 0x96, 0x08, 0x6f, 0x1a, 0x36, 0xff, 0xb9, 0x97, + 0xfd, 0x6d, 0x76, 0x3b, 0xb9, 0x8b, 0xff, 0x6f, 0xfc, 0xd1, 0xbb, 0xda, 0xa2, 0x35, 0xe7, 0x56, + 0x1e, 0x12, 0x87, 0x56, 0x1d, 0xde, 0x3b, 0xd8, 0x2b, 0xff, 0x69, 0xf1, 0xd3, 0xf5, 0xbd, 0xbb, + 0xa3, 0x9b, 0xec, 0xa8, 0x4f, 0x62, 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65, 0xeb, 0xd7, 0xca, 0xbc, + 0x3f, 0x61, 0xb7, 0xa8, 0xab, 0x86, 0x57, 0x18, 0x14, 0x6e, 0xb5, 0x6d, 0x98, 0x31, 0x31, 0x53, + 0xee, 0x9d, 0xb5, 0x90, 0x94, 0x36, 0x77, 0xa8, 0x5b, 0x6d, 0x1a, 0xf5, 0xad, 0x6a, 0x10, 0xe5, + 0xf9, 0xbf, 0x5a, 0x4b, 0xc1, 0xb1, 0x6d, 0xad, 0x45, 0x6b, 0x37, 0x1d, 0xbe, 0xd9, 0x43, 0xbe, + 0xd6, 0x79, 0xb7, 0xed, 0x6f, 0x59, 0x25, 0xb6, 0x55, 0x68, 0x15, 0x98, 0x36, 0x59, 0xa8, 0x4f, + 0xc9, 0x2d, 0x57, 0xb2, 0x50, 0x5d, 0x2d, 0x64, 0xff, 0xb7, 0x9a, 0x1b, 0xd3, 0x97, 0x30, 0x78, + 0x8c, 0xa3, 0x24, 0x66, 0x98, 0x95, 0x63, 0x63, 0x59, 0x0f, 0x13, 0x7e, 0x5f, 0x43, 0x52, 0x54, + 0x5f, 0x53, 0x45, 0xbd, 0x5d, 0x2f, 0x1a, 0x5f, 0x4e, 0x4f, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, + 0x4e, 0x47, 0xe4, 0xcf, 0x45, 0x56, 0xb6, 0x75, 0xe0, 0xba, 0xb3, 0xfd, 0xc7, 0x2e, 0xea, 0x8e, + 0xfb, 0x6b, 0xec, 0xf7, 0xde, 0xbe, 0x38, 0x3b, 0x09, 0x44, 0x50, 0x52, 0x21, 0x8e, 0x41, 0x54, + 0x74, 0x89, 0x23, 0x3d, 0x46, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x2e, 0x87, 0xf1, 0xea, 0x90, 0x03, + 0x6e, 0xd7, 0x55, 0xe4, 0x4c, 0x59, 0x20, 0xa7, 0x3e, 0x51, 0xcd, 0x47, 0x43, 0x43, 0xee, 0xf7, + 0x07, 0x7e, 0xa9, 0xbf, 0x35, 0x47, 0x4e, 0x55, 0x1e, 0xf9, 0x24, 0xde, 0xd6, 0xef, 0x34, 0x43, + 0x21, 0xde, 0xef, 0x34, 0x6b, 0x16, 0x56, 0x29, 0x77, 0x57, 0x1a, 0x4e, 0x71, 0x9a, 0xed, 0x9f, + 0x3d, 0x34, 0x30, 0x35, 0x29, 0x20, 0x7c, 0x7c, 0x61, 0xb5, 0x64, 0x1c, 0x95, 0x73, 0x69, 0x3c, + 0x66, 0x69, 0x3b, 0x37, 0x26, 0x44, 0x28, 0x99, 0x77, 0x5d, 0x72, 0x4e, 0xc8, 0xfe, 0xb3, 0x83, + 0x12, 0x65, 0x14, 0x68, 0x28, 0x28, 0x05, 0xb4, 0x45, 0xa5, 0x00, 0x5e, 0x91, 0xb4, 0x9e, 0xff, + 0xf8, 0x05, 0x33, 0x31, 0xd3, 0xfe, 0x4b, 0xc1, 0x62, 0x89, 0xc9, 0x4d, 0x53, 0x24, 0xc9, 0xb3, + 0xbf, 0x6d, 0x5d, 0x6a, 0xad, 0x17, 0x62, 0x7f, 0xe5, 0xbb, 0xde, 0x4d, 0x72, 0x97, 0xfa, 0xf6, + 0xc9, 0x58, 0x3b, 0x9a, 0x28, 0x22, 0x61, 0x4d, 0x3a, 0xb5, 0x4b, 0xaa, 0x76, 0x6f, 0xbc, 0x59, + 0xb5, 0xe7, 0xe6, 0xd7, 0xb5, 0xb8, 0x47, 0x9b, 0xbf, 0x67, 0x2f, 0x86, 0xbe, 0x22, 0x2e, 0x45, + 0x95, 0x47, 0xfb, 0xa2, 0x51, 0x52, 0x10, 0x0d, 0x1f, 0x20, 0x6d, 0xa8, 0x5b, 0xf9, 0xe5, 0x01, + 0xf5, 0xf5, 0xa9, 0xa3, 0xda, 0xfb, 0x3a, 0xbb, 0x6a, 0x67, 0x3f, 0xb6, 0x17, 0x5d, 0x2b, 0xbb, + 0x8c, 0xa7, 0xb3, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0xda, 0xd7, 0xb3, 0xee, 0x9d, 0x61, 0xa8, 0x81, + 0xb7, 0xa4, 0xc9, 0xa6, 0x72, 0x31, 0x33, 0x31, 0xa0, 0x78, 0x70, 0xdb, 0xa1, 0xf5, 0xae, 0xc9, + 0x8d, 0xba, 0x8b, 0xaf, 0xdf, 0xa6, 0xf9, 0xdb, 0xae, 0x3f, 0x01, 0xda, 0xfe, 0x2f, 0xcd, 0x7a, + 0xfd, 0xfd, 0x9f, 0xac, 0x97, 0x9b, 0xae, 0x7a, 0xa3, 0xd3, 0x7d, 0x4f, 0xc7, 0xda, 0xd6, 0xb1, + 0xbf, 0xcd, 0x8d, 0x69, 0x01, 0xaf, 0xf6, 0xa9, 0xfd, 0x8b, 0x95, 0xa4, 0xe9, 0xb5, 0xcd, 0xbf, + 0x63, 0xc1, 0xad, 0xae, 0x2d, 0x39, 0x9f, 0xc1, 0x7a, 0xf2, 0x9f, 0xb6, 0xbf, 0x29, 0xcf, 0x8e, + 0xe1, 0xa9, 0x9d, 0x09, 0x7b, 0xed, 0x72, 0x01, 0xaf, 0x7d, 0x1f, 0xb5, 0x6a, 0xf3, 0x23, 0xac, + 0x80, 0x20, 0x6e, 0x6d, 0x7c, 0x2d, 0x9b, 0xaa, 0x3d, 0x7d, 0xac, 0x57, 0xb6, 0xf9, 0xa5, 0x7e, + 0xcd, 0xd9, 0xf9, 0x0a, 0xaf, 0xd7, 0x7d, 0xe0, 0xa8, 0x72, 0xa5, 0x20, 0xea, 0x96, 0x89, 0xb8, + 0xd5, 0xf5, 0x34, 0x6f, 0x6e, 0xfc, 0x3f, 0xb5, 0x2a, 0x6f, 0x24, 0xfc, 0x49, 0xa7, 0xe1, 0x57, + 0xfe, 0xa2, 0x05, 0x6e, 0xad, 0x2d, 0x9f, 0xef, 0x32, 0x84, 0x64, 0x65, 0x72, 0xa1, 0x73, 0xeb, + 0x77, 0xf9, 0x59, 0x27, 0x26, 0x9d, 0x71, 0xbe, 0xb7, 0xc5, 0x9a, 0xb2, 0xc5, 0xf4, 0x6f, 0xe9, + 0x1b, 0x15, 0xbf, 0x47, 0x05, 0x6e, 0x2d, 0x39, 0x7e, 0x93, 0x6b, 0xd4, 0x85, 0x93, 0x77, 0x2b, + 0x99, 0x3b, 0x6b, 0x61, 0x3a, 0x60, 0x70, 0xd9, 0x35, 0x1a, 0xa5, 0xa7, 0x3b, 0x34, 0x64, 0x3b, + 0x20, 0xdd, 0x9b, 0xd5, 0x05, 0xb1, 0x18, 0x6d, 0xf3, 0x9f, 0xed, 0x35, 0xd6, 0x56, 0xa9, 0xab, + 0x6f, 0x35, 0x59, 0x39, 0x65, 0xbb, 0xaa, 0xe6, 0x63, 0x7b, 0xc1, 0x50, 0x67, 0x7e, 0x34, 0xa9, + 0x57, 0xa6, 0xaf, 0xdd, 0x4d, 0xaf, 0x26, 0x59, 0xac, 0x87, 0xd6, 0xf3, 0x9d, 0xf5, 0x5b, 0x6a, + 0x95, 0x33, 0x55, 0x69, 0xe6, 0xa1, 0xf3, 0x15, 0x07, 0x70, 0xe4, 0x69, 0x08, 0x9d, 0xd1, 0x27, + 0xde, 0x07, 0x6b, 0xcb, 0xe3, 0xe6, 0xce, 0x7d, 0x4e, 0x95, 0x77, 0x9d, 0xf4, 0xb9, 0xbb, 0x67, + 0xdc, 0x8f, 0x53, 0xde, 0x8a, 0x79, 0x9f, 0x37, 0x0f, 0xa9, 0x4f, 0xa5, 0x48, 0xdc, 0x20, 0xe7, + 0x05, 0x65, 0x39, 0x9f, 0xfb, 0x6c, 0x47, 0x7e, 0x77, 0x9d, 0x95, 0xaf, 0x75, 0x75, 0xa5, 0x7b, + 0x78, 0xb9, 0x47, 0x22, 0x81, 0xef, 0x2b, 0x59, 0x1f, 0x29, 0xfd, 0x99, 0xc5, 0x22, 0x12, 0xb8, + 0x03, 0x92, 0x45, 0xde, 0xb9, 0x2b, 0xdf, 0x37, 0xcf, 0xae, 0x61, 0x2d, 0x3b, 0x6a, 0xad, 0xd9, + 0xe3, 0x1b, 0x20, 0xee, 0x69, 0xa3, 0x5b, 0x45, 0xee, 0x2d, 0xaf, 0x6e, 0xa7, 0x7f, 0xf7, 0x61, + 0x5f, 0xa5, 0x5d, 0xa7, 0x74, 0x45, 0xa5, 0xe6, 0xf6, 0x8f, 0xd8, 0x81, 0xef, 0x7a, 0xb7, 0xe9, + 0x5b, 0xd3, 0x53, 0x00, 0x89, 0x4c, 0x45, 0x6a, 0x6c, 0x04, 0x93, 0x49, 0x9b, 0xb7, 0xa6, 0x6b, + 0x96, 0xb4, 0x8f, 0x8b, 0x9e, 0xf2, 0xed, 0xe6, 0x8f, 0x3f, 0x9e, 0xe7, 0x99, 0xb7, 0x7d, 0xab, + 0x3a, 0x5b, 0x6b, 0x47, 0x9d, 0x50, 0x8b, 0x4e, 0x19, 0x66, 0x69, 0x78, 0x36, 0x34, 0x3e, 0xef, + 0xcf, 0x75, 0xde, 0xe7, 0xf5, 0xf5, 0x3e, 0x5d, 0x1f, 0x5b, 0xad, 0xad, 0xf3, 0xf6, 0x3a, 0x4b, + 0xd5, 0x5b, 0x8f, 0x4b, 0xe7, 0xfd, 0x07, 0xf6, 0xab, 0xe6, 0xdd, 0xf1, 0x7d, 0xaa, 0xf9, 0xc7, + 0xda, 0xaa, 0xa0, +}; + +static unsigned char buf[18830]; + +int main() { + + unsigned long cksum = adler32(0, NULL, 0); + + decompress_zx02(compressed, buf); + cksum = adler32(cksum, buf, 18830); + + return cksum == 0xf748269d ? 0 : 1; +} From 13ddd6392cb24b90d585424bfe2fa7f7ca8f5afe Mon Sep 17 00:00:00 2001 From: Piotr Fusik <fox@scene.pl> Date: Wed, 14 May 2025 15:15:32 +0200 Subject: [PATCH 419/707] zlib: Make crc32 8 bytes shorter and 3 cycles/byte faster --- libsrc/zlib/crc32.s | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/libsrc/zlib/crc32.s b/libsrc/zlib/crc32.s index 41b5fe9db..f80b1f437 100644 --- a/libsrc/zlib/crc32.s +++ b/libsrc/zlib/crc32.s @@ -1,6 +1,7 @@ ; ; 2001-11-14, Piotr Fusik ; 2018-05-20, Christian Kruger +; 2025-05-14, Piotr Fusik ; ; unsigned long __fastcall__ crc32 (unsigned long crc, ; const unsigned char* buf, @@ -9,7 +10,7 @@ .export _crc32 - .import compleax, incsp2, incsp4, popptr1, popeax + .import compleax, incsp4, popptr1, popeax .importzp sreg, ptr1, ptr2, tmp1, tmp2 POLYNOMIAL = $EDB88320 @@ -58,15 +59,12 @@ make_table: inx bne @L1 inc table_initialised -RET: rts _crc32: -; ptr2 = (len & 0xff) == 0 ? len : len + 0x100; - tay - beq @L1 +; ptr2 = len + 0x100 inx -@L1: sta ptr2 + sta ptr2 stx ptr2+1 ; ptr1 = buf jsr popptr1 @@ -78,20 +76,15 @@ _crc32: bne @dont_make jsr make_table @dont_make: -; eax = crc - jsr popeax -; if (len == 0) return crc; - ldy ptr2 - bne @L2 - ldy ptr2+1 - beq RET -@L2: ; eax = ~crc + jsr popeax jsr compleax stx tmp2 ldy #0 +@L1: cpy ptr2 + beq @low_end ; crc = (crc >> 8) ^ table[(crc & 0xff) ^ *p++]; -@L3: eor (ptr1),y +@L2: eor (ptr1),y tax lda table_0,x eor tmp2 @@ -106,12 +99,12 @@ _crc32: sta sreg+1 lda tmp1 iny - bne @L4 + bne @L1 inc ptr1+1 -@L4: dec ptr2 - bne @L3 + jmp @L1 +@low_end: dec ptr2+1 - bne @L3 + bne @L2 ldx tmp2 jmp compleax From 9cdba1b6d850c50aee2cb559ccffa3cec3910752 Mon Sep 17 00:00:00 2001 From: John Murkerson <john@zifmia.org> Date: Wed, 14 May 2025 14:37:51 -0400 Subject: [PATCH 420/707] Fix Atari buffer overrun on keyboard EOF --- libsrc/atari/read.s | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsrc/atari/read.s b/libsrc/atari/read.s index 228ca9ee2..b50bd2856 100644 --- a/libsrc/atari/read.s +++ b/libsrc/atari/read.s @@ -147,6 +147,7 @@ icbll_copy: sta dataptr+1 lda ICBLL,x sta copylen + beq copied ; length = 0 if EOF pha ; remember for return value ldy #0 ldx index @@ -159,7 +160,7 @@ copy: lda linebuf,x bne copy pla ; length - pha ; save length to return at okdone +copied: pha ; save length to return at okdone clc adc index From 500887ec23e57cd2c4d2db88f3996530eb97ed4f Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sat, 17 May 2025 17:18:05 +0200 Subject: [PATCH 421/707] Fix #2599. The compiler handled all functions returning an int but without a "return" statement by silently adding "return 0" instead of emitting a warning. This is the desired behavior for the "main" function in C99 and above, but the compiler applied it to all functions. --- src/cc65/function.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc65/function.c b/src/cc65/function.c index fed0349dd..3123079d3 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -636,7 +636,9 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* If this is the main function in a C99 environment returning an int, ** let it always return zero. Otherwise output a warning. */ - if (IS_Get (&Standard) >= STD_C99 && GetUnqualRawTypeCode (ReturnType) == T_INT) { + if (F_IsMainFunc (CurrentFunc) && + IS_Get (&Standard) >= STD_C99 && + GetUnqualRawTypeCode (ReturnType) == T_INT) { g_getimmed (CF_INT | CF_CONST, 0, 0); } else if (IS_Get (&WarnReturnType)) { Warning ("Control reaches end of non-void function [-Wreturn-type]"); From 81e1312416c4e290fefbc4079be8f67850109eb4 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 20 May 2025 13:50:33 +0200 Subject: [PATCH 422/707] Remove the unused function ClearDiagnosticStrBufs(). --- src/cc65/error.c | 13 +------------ src/cc65/error.h | 3 --- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/cc65/error.c b/src/cc65/error.c index d6e7d7cbd..6575a1e54 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -506,23 +506,12 @@ void InitDiagnosticStrBufs (void) void DoneDiagnosticStrBufs (void) /* Done with tracked string buffers used for diagnostics */ -{ - ClearDiagnosticStrBufs (); - DoneCollection (&DiagnosticStrBufs); -} - - - -void ClearDiagnosticStrBufs (void) -/* Free all tracked string buffers */ { unsigned I; - for (I = 0; I < CollCount (&DiagnosticStrBufs); ++I) { SB_Done (CollAtUnchecked (&DiagnosticStrBufs, I)); } - - CollDeleteAll (&DiagnosticStrBufs); + DoneCollection (&DiagnosticStrBufs); } diff --git a/src/cc65/error.h b/src/cc65/error.h index 5af862f9f..3cb2f75a9 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -159,9 +159,6 @@ void InitDiagnosticStrBufs (void); void DoneDiagnosticStrBufs (void); /* Done with tracked string buffers used for diagnostics */ -void ClearDiagnosticStrBufs (void); -/* Free all tracked string buffers */ - struct StrBuf* NewDiagnosticStrBuf (void); /* Get a new tracked string buffer */ From c7c7377f7aaef38a51ad1bb37f2fda555b9a87d4 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 20 May 2025 13:50:33 +0200 Subject: [PATCH 423/707] Remove the unused function ClearDiagnosticStrBufs(). --- src/cc65/error.c | 13 +------------ src/cc65/error.h | 3 --- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/cc65/error.c b/src/cc65/error.c index d6e7d7cbd..6575a1e54 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -506,23 +506,12 @@ void InitDiagnosticStrBufs (void) void DoneDiagnosticStrBufs (void) /* Done with tracked string buffers used for diagnostics */ -{ - ClearDiagnosticStrBufs (); - DoneCollection (&DiagnosticStrBufs); -} - - - -void ClearDiagnosticStrBufs (void) -/* Free all tracked string buffers */ { unsigned I; - for (I = 0; I < CollCount (&DiagnosticStrBufs); ++I) { SB_Done (CollAtUnchecked (&DiagnosticStrBufs, I)); } - - CollDeleteAll (&DiagnosticStrBufs); + DoneCollection (&DiagnosticStrBufs); } diff --git a/src/cc65/error.h b/src/cc65/error.h index 5af862f9f..3cb2f75a9 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -159,9 +159,6 @@ void InitDiagnosticStrBufs (void); void DoneDiagnosticStrBufs (void); /* Done with tracked string buffers used for diagnostics */ -void ClearDiagnosticStrBufs (void); -/* Free all tracked string buffers */ - struct StrBuf* NewDiagnosticStrBuf (void); /* Get a new tracked string buffer */ From b5b7ea422e8615399b8653ca10f5752338608ac0 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Wed, 21 May 2025 11:04:21 +0200 Subject: [PATCH 424/707] Make sure, the command line setting for the "Unreachable code" warning is checked in all cases before outputting such a warning. Fixes #2655. --- src/cc65/error.c | 12 ++++++++++++ src/cc65/error.h | 5 +++++ src/cc65/stmt.c | 4 ++-- src/cc65/testexpr.c | 2 +- test/misc/Makefile | 5 +++++ test/misc/bug2655.c | 18 ++++++++++++++++++ test/misc/bug2655.ref | 2 ++ 7 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 test/misc/bug2655.c create mode 100644 test/misc/bug2655.ref diff --git a/src/cc65/error.c b/src/cc65/error.c index 6575a1e54..b67fa1afd 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -379,6 +379,18 @@ void PPWarning (const char* Format, ...) +void UnreachableCodeWarning (void) +/* Print a warning about unreachable code at the current location if these +** warnings are enabled. +*/ +{ + if (IS_Get (&WarnUnreachableCode)) { + Warning ("Unreachable code"); + } +} + + + IntStack* FindWarning (const char* Name) /* Search for a warning in the WarnMap table and return a pointer to the ** intstack that holds its state. Return NULL if there is no such warning. diff --git a/src/cc65/error.h b/src/cc65/error.h index 3cb2f75a9..b3cdc49ab 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -127,6 +127,11 @@ void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...) attribute (( void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2))); /* Print a warning message. For use within the preprocessor */ +void UnreachableCodeWarning (void); +/* Print a warning about unreachable code at the current location if these +** warnings are enabled. +*/ + IntStack* FindWarning (const char* Name); /* Search for a warning in the WarnMap table and return a pointer to the ** intstack that holds its state. Return NULL if there is no such warning. diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index c86f25f8a..e28b844b5 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -188,8 +188,8 @@ static int IfStatement (void) /* If the if expression was always true, the code in the else branch ** is never executed. Output a warning if this is the case. */ - if (TestResult == TESTEXPR_TRUE && IS_Get (&WarnUnreachableCode)) { - Warning ("Unreachable code"); + if (TestResult == TESTEXPR_TRUE) { + UnreachableCodeWarning (); } /* Define the target for the first test */ diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index 14160f13f..ced563d01 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -76,7 +76,7 @@ unsigned Test (unsigned Label, int Invert) /* Constant rvalue */ if (!Invert && Expr.IVal == 0) { g_jump (Label); - Warning ("Unreachable code"); + UnreachableCodeWarning (); } else if (Invert && Expr.IVal != 0) { g_jump (Label); } diff --git a/test/misc/Makefile b/test/misc/Makefile index f5225b14b..48293e504 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -134,6 +134,11 @@ $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) # these need reference data that can't be generated by a host-compiled program, # in a useful way +$(WORKDIR)/bug2655.$1.$2.prg: bug2655.c $(ISEQUAL) | $(WORKDIR) + $(if $(QUIET),echo misc/bug2655.$1.$2.prg) + $(CC65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/bug2655.$1.$2.out + $(ISEQUAL) $(WORKDIR)/bug2655.$1.$2.out bug2655.ref + $(WORKDIR)/limits.$1.$2.prg: limits.c $(ISEQUAL) | $(WORKDIR) $(if $(QUIET),echo misc/limits.$1.$2.prg) $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) diff --git a/test/misc/bug2655.c b/test/misc/bug2655.c new file mode 100644 index 000000000..e0b1c939c --- /dev/null +++ b/test/misc/bug2655.c @@ -0,0 +1,18 @@ +void f1(void) +{ + if (1) { + f1(); + } else { + f1(); + } +} + +void f2(void) +{ + if (0) { + f2(); + } else { + f2(); + } +} + diff --git a/test/misc/bug2655.ref b/test/misc/bug2655.ref new file mode 100644 index 000000000..99e2d6698 --- /dev/null +++ b/test/misc/bug2655.ref @@ -0,0 +1,2 @@ +bug2655.c:5: Warning: Unreachable code +bug2655.c:12: Warning: Unreachable code From 7be7ce4e9ba6ec93ac009c6bee12fc27ef36690b Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Wed, 21 May 2025 11:21:40 +0200 Subject: [PATCH 425/707] Remove tabs. --- src/cc65/error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/error.c b/src/cc65/error.c index b67fa1afd..db0debf8c 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -385,7 +385,7 @@ void UnreachableCodeWarning (void) */ { if (IS_Get (&WarnUnreachableCode)) { - Warning ("Unreachable code"); + Warning ("Unreachable code"); } } From 6628c4ff4333d82c40fa13db9b6e4356ce405951 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 24 May 2025 18:34:44 +0200 Subject: [PATCH 426/707] fix cpeekc/cpeekcolor/cpeekrevers for atari 800 --- libsrc/atari/cpeekc.s | 35 +++++++++++++++++++++++ libsrc/atari/cpeekchar.s | 35 ----------------------- libsrc/atari/cpeekcolor.s | 8 ++++++ libsrc/atari/cpeekrevers.s | 18 ++++++++++++ targettest/conio.c | 57 ++++++++++++++++++++++++++++++++------ 5 files changed, 109 insertions(+), 44 deletions(-) create mode 100644 libsrc/atari/cpeekc.s delete mode 100644 libsrc/atari/cpeekchar.s create mode 100644 libsrc/atari/cpeekcolor.s create mode 100644 libsrc/atari/cpeekrevers.s diff --git a/libsrc/atari/cpeekc.s b/libsrc/atari/cpeekc.s new file mode 100644 index 000000000..a51e477a6 --- /dev/null +++ b/libsrc/atari/cpeekc.s @@ -0,0 +1,35 @@ +; +; 2016-02-28, Groepaz +; 2017-06-21, Greg King +; +; char cpeekc (void); +; + + .export _cpeekc + + .include "atari.inc" + + +_cpeekc: + lda OLDCHR ; get char under cursor + and #<~$80 ; remove reverse bit + + ;; convert internal screen code to AtSCII + + tay + and #%01100000 + asl a + asl a + rol a + rol a + tax + tya + eor intats,x + ldx #>$0000 + rts + + .rodata +intats: .byte %00100000 ; -> %001xxxxx + .byte %01100000 ; -> %010xxxxx + .byte %01000000 ; -> %000xxxxx + .byte %00000000 ; -> %011xxxxx diff --git a/libsrc/atari/cpeekchar.s b/libsrc/atari/cpeekchar.s deleted file mode 100644 index ff502074d..000000000 --- a/libsrc/atari/cpeekchar.s +++ /dev/null @@ -1,35 +0,0 @@ - - .export _cpeekc - - .import mul40 - .importzp ptr4 - - .include "atari.inc" - - .segment "CODE" - -_cpeekc: - - lda ROWCRS - jsr mul40 ; destroys tmp4 - clc - adc SAVMSC ; add start of screen memory - sta ptr4 - txa - adc SAVMSC+1 - sta ptr4+1 - - ldy COLCRS - lda (ptr4),y ; get char - tax - - ;; convert to asc - - ;; FIXME: ugly hack here to make tetris fx work :=P - lda #' ' - cpx #0 - beq @l - lda #0 -@l: - ldx #0 - rts diff --git a/libsrc/atari/cpeekcolor.s b/libsrc/atari/cpeekcolor.s new file mode 100644 index 000000000..ed275ec95 --- /dev/null +++ b/libsrc/atari/cpeekcolor.s @@ -0,0 +1,8 @@ +; +; 2017-06-03, Greg King +; +; unsigned char cpeekcolor (void); +; + + .import return1 + .export _cpeekcolor := return1 ; always COLOR_WHITE diff --git a/libsrc/atari/cpeekrevers.s b/libsrc/atari/cpeekrevers.s new file mode 100644 index 000000000..15b26fcd4 --- /dev/null +++ b/libsrc/atari/cpeekrevers.s @@ -0,0 +1,18 @@ +; +; 2017-06-21, Greg King +; +; unsigned char cpeekrevers (void); +; + + .export _cpeekrevers + + .include "atari.inc" + + +_cpeekrevers: + lda OLDCHR ; get char under cursor + and #$80 ; get reverse bit + asl a + tax ; ldx #>$0000 + rol a ; return boolean value + rts diff --git a/targettest/conio.c b/targettest/conio.c index efe82d7c6..f65f886c5 100644 --- a/targettest/conio.c +++ b/targettest/conio.c @@ -32,6 +32,48 @@ static char grid[5][5] = { {CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER} }; +void colortest(void) +{ + unsigned int i, j; + cputsxy(0, 2, "Colors:" ); + for (i = 0; i < 3; ++i) { + gotoxy(i, 3 + i); + for (j = 0; j < NUMCOLS; ++j) { + (void)textcolor(j); + cputc('X'); + } + } +} + +#define LINE_PEEKTEST 11 + +void peektest(void) +{ + int j; + char buf[NUMCOLS]; + char cbuf[NUMCOLS]; + char rbuf[NUMCOLS]; + + gotoxy(0, LINE_PEEKTEST); + for (j = 0; j < NUMCOLS; ++j) { + (void)textcolor(j); + revers((j >> 1)&1); + cputc('a' + j); + } + for (j = 0; j < NUMCOLS; ++j) { + gotoxy(j, LINE_PEEKTEST); + buf[j] = cpeekc(); + cbuf[j] = cpeekcolor(); + rbuf[j] = cpeekrevers(); + } + gotoxy(0, (LINE_PEEKTEST+1)); + for (j = 0; j < NUMCOLS; ++j) { + (void)textcolor(cbuf[j]); + revers(rbuf[j]); + cputc(buf[j]); + } +} + void main(void) { unsigned int i, j, n; @@ -52,16 +94,13 @@ void main(void) (void)bordercolor(bcol); (void)bgcolor(bgcol); - cputsxy(0, 2, "Colors:" ); - for (i = 0; i < 3; ++i) { - gotoxy(i, 3 + i); - for (j = 0; j < NUMCOLS; ++j) { - (void)textcolor(j); - cputc('X'); - } - } - (void)textcolor(tcol); + colortest(); + peektest(); + (void)textcolor(tcol); + revers(0); + + gotoxy(4,5); cprintf("\n\n\r Screensize: %ux%u", xsize, ysize); chlinexy(0, 6, xsize); From 228316ff58cd9ac7fd70727713f8a486f09b3a4c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 24 May 2025 19:19:49 +0200 Subject: [PATCH 427/707] NES complete now (tested and conio test updated), replaces what is in #532 --- libsrc/nes/color.s | 4 ++-- libsrc/nes/cpeekc.s | 37 +++++++++++++++++++++++++++++++++++++ libsrc/nes/cpeekchar.s | 34 ---------------------------------- libsrc/nes/cpeekcolor.s | 8 ++++++++ libsrc/nes/cpeekrevers.s | 37 +++++++++++++++++++++++++++++++++++++ targettest/conio.c | 1 + 6 files changed, 85 insertions(+), 36 deletions(-) create mode 100644 libsrc/nes/cpeekc.s delete mode 100644 libsrc/nes/cpeekchar.s create mode 100644 libsrc/nes/cpeekcolor.s create mode 100644 libsrc/nes/cpeekrevers.s diff --git a/libsrc/nes/color.s b/libsrc/nes/color.s index e3aef9a28..cd1a950ea 100644 --- a/libsrc/nes/color.s +++ b/libsrc/nes/color.s @@ -9,11 +9,11 @@ .export _textcolor, _bgcolor, _bordercolor - .import return0, ppubuf_put + .import return0, return1, ppubuf_put .include "nes.inc" -_textcolor = return0 +_textcolor = return1 _bordercolor = return0 .proc _bgcolor diff --git a/libsrc/nes/cpeekc.s b/libsrc/nes/cpeekc.s new file mode 100644 index 000000000..315a2df5c --- /dev/null +++ b/libsrc/nes/cpeekc.s @@ -0,0 +1,37 @@ +; +; 2016-02-28, Groepaz +; 2017-08-17, Greg King +; +; char cpeekc (void); +; + + .export _cpeekc + + .import ppubuf_waitempty + .forceimport initconio + + .include "nes.inc" + + +_cpeekc: + ; wait until all console data has been written + jsr ppubuf_waitempty + + ldy SCREEN_PTR+1 + lda SCREEN_PTR + +; waiting for vblank is incredibly slow :// +vwait: +; ldx PPU_STATUS +; bpl vwait + + ldx #>$0000 + sty PPU_VRAM_ADDR2 + sta PPU_VRAM_ADDR2 + lda PPU_VRAM_IO ; first read is invalid + lda PPU_VRAM_IO ; get data + stx PPU_VRAM_ADDR2 + stx PPU_VRAM_ADDR2 + + and #<~$80 ; remove reverse bit + rts diff --git a/libsrc/nes/cpeekchar.s b/libsrc/nes/cpeekchar.s deleted file mode 100644 index 55230edbc..000000000 --- a/libsrc/nes/cpeekchar.s +++ /dev/null @@ -1,34 +0,0 @@ - - .export _cpeekc - - .import ppubuf_waitempty - - .include "nes.inc" - - .segment "CODE" - -_cpeekc: - - ; wait until all console data has been written - jsr ppubuf_waitempty - - ldy SCREEN_PTR+1 - ldx SCREEN_PTR - -; waiting for vblank is incredibly slow :// -vwait: -; lda $2002 ;wait -; bpl vwait - - lda #0 - sty $2006 - stx $2006 - ldy $2007 ; first read is invalid - ldy $2007 ; get data - sta $2006 - sta $2006 - - tya - and #$7f ; ?!?! - rts - diff --git a/libsrc/nes/cpeekcolor.s b/libsrc/nes/cpeekcolor.s new file mode 100644 index 000000000..ed275ec95 --- /dev/null +++ b/libsrc/nes/cpeekcolor.s @@ -0,0 +1,8 @@ +; +; 2017-06-03, Greg King +; +; unsigned char cpeekcolor (void); +; + + .import return1 + .export _cpeekcolor := return1 ; always COLOR_WHITE diff --git a/libsrc/nes/cpeekrevers.s b/libsrc/nes/cpeekrevers.s new file mode 100644 index 000000000..8b1542bc0 --- /dev/null +++ b/libsrc/nes/cpeekrevers.s @@ -0,0 +1,37 @@ +; +; 2016-02-28, Groepaz +; 2017-08-17, Greg King +; +; char cpeekrevers (void); +; + + .export _cpeekrevers + + .import ppubuf_waitempty + .forceimport initconio + + .include "nes.inc" + + +_cpeekrevers: + ; wait until all console data has been written + jsr ppubuf_waitempty + + ldy SCREEN_PTR+1 + lda SCREEN_PTR + +; waiting for vblank is incredibly slow :// +vwait: +; ldx PPU_STATUS +; bpl vwait + + ldx #>$0000 + sty PPU_VRAM_ADDR2 + sta PPU_VRAM_ADDR2 + lda PPU_VRAM_IO ; first read is invalid + lda PPU_VRAM_IO ; get data + stx PPU_VRAM_ADDR2 + stx PPU_VRAM_ADDR2 + + and #<$80 ; get reverse bit + rts diff --git a/targettest/conio.c b/targettest/conio.c index f65f886c5..e054319e5 100644 --- a/targettest/conio.c +++ b/targettest/conio.c @@ -59,6 +59,7 @@ void peektest(void) (void)textcolor(j); revers((j >> 1)&1); cputc('a' + j); + rbuf[j] = (j >> 1)&1; } for (j = 0; j < NUMCOLS; ++j) { gotoxy(j, LINE_PEEKTEST); From 8d42c4a8c5ea357f9c037cb466c764963545b562 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 24 May 2025 20:03:44 +0200 Subject: [PATCH 428/707] fix cpeekc/cpeekcolor/cpeekrevers/cpeeks for atmos, replaces what is in #532 --- include/atmos.h | 11 ++++++++ libsrc/atmos/cpeekc.s | 21 +++++++++++++++ libsrc/atmos/cpeekchar.s | 30 --------------------- libsrc/atmos/cpeekcolor.s | 10 +++++++ libsrc/atmos/cpeekrevers.s | 22 ++++++++++++++++ libsrc/atmos/cpeeks.s | 54 ++++++++++++++++++++++++++++++++++++++ targettest/Makefile | 3 ++- targettest/conio.c | 14 ++++++++++ 8 files changed, 134 insertions(+), 31 deletions(-) create mode 100644 libsrc/atmos/cpeekc.s delete mode 100644 libsrc/atmos/cpeekchar.s create mode 100644 libsrc/atmos/cpeekcolor.s create mode 100644 libsrc/atmos/cpeekrevers.s create mode 100644 libsrc/atmos/cpeeks.s diff --git a/include/atmos.h b/include/atmos.h index 460a0010f..9b1b021c1 100644 --- a/include/atmos.h +++ b/include/atmos.h @@ -169,6 +169,17 @@ void atmos_tock (void); void atmos_zap (void); /* Raygun sound effect */ + +/* The following #defines will cause the matching function prototypes +** in conio.h to be overlaid by macroes with the same names, +** thereby saving the function call overhead. +*/ +#define _textcolor(color) COLOR_WHITE +#define _bgcolor(color) COLOR_BLACK +#define _bordercolor(color) COLOR_BLACK +#define _cpeekcolor(color) COLOR_WHITE + + void waitvsync (void); /* Wait for start of next frame */ diff --git a/libsrc/atmos/cpeekc.s b/libsrc/atmos/cpeekc.s new file mode 100644 index 000000000..f0f5f99b1 --- /dev/null +++ b/libsrc/atmos/cpeekc.s @@ -0,0 +1,21 @@ +; +; 2016-02-28, Groepaz +; 2017-06-19, Greg King +; +; char cpeekc (void); +; +; Atmos version +; + + .export _cpeekc + + .import setscrptr + .importzp ptr2 + + +_cpeekc: + jsr setscrptr ; Set ptr2 and .Y to the cursor's address + lda (ptr2),y ; Get char + and #<~$80 ; Remove revers() bit + ldx #>$0000 + rts diff --git a/libsrc/atmos/cpeekchar.s b/libsrc/atmos/cpeekchar.s deleted file mode 100644 index fba51bf72..000000000 --- a/libsrc/atmos/cpeekchar.s +++ /dev/null @@ -1,30 +0,0 @@ - - .include "atmos.inc" - - .export _cpeekc - -_cpeekc: - - ldy CURS_Y - ldx ScrTabLo,y - stx @l+1 - ldx ScrTabHi,y - stx @l+2 - ldx CURS_X -@l: - lda $bb80,x -;; inc COORDX_TEXT - ldx #0 - rts - - ; FIXME: is that table available elsewhere? -.rodata -ScrTabLo: - .repeat 28, Line - .byte <(SCREEN + Line * 40) - .endrep - -ScrTabHi: - .repeat 28, Line - .byte >(SCREEN + Line * 40) - .endrep diff --git a/libsrc/atmos/cpeekcolor.s b/libsrc/atmos/cpeekcolor.s new file mode 100644 index 000000000..307c04e96 --- /dev/null +++ b/libsrc/atmos/cpeekcolor.s @@ -0,0 +1,10 @@ +; +; 2017-06-03, Greg King +; +; unsigned char cpeekcolor (void); +; +; Atmos version +; + + .import return1 + .export _cpeekcolor := return1 ; always COLOR_WHITE diff --git a/libsrc/atmos/cpeekrevers.s b/libsrc/atmos/cpeekrevers.s new file mode 100644 index 000000000..53f907511 --- /dev/null +++ b/libsrc/atmos/cpeekrevers.s @@ -0,0 +1,22 @@ +; +; 2017-06-08, Greg King +; +; unsigned char cpeekrevers (void); +; +; Atmos version +; + + .export _cpeekrevers + + .import setscrptr + .importzp ptr2 + + +_cpeekrevers: + jsr setscrptr ; Set ptr2 and .Y to the cursor's address + lda (ptr2),y ; Get char + and #$80 ; get reverse bit + asl a + tax ; ldx #>$0000 + rol a ; return boolean value + rts diff --git a/libsrc/atmos/cpeeks.s b/libsrc/atmos/cpeeks.s new file mode 100644 index 000000000..e54563e7d --- /dev/null +++ b/libsrc/atmos/cpeeks.s @@ -0,0 +1,54 @@ +; +; 2017-06-20, Greg King +; +; void cpeeks (char* s, unsigned length); +; + + .export _cpeeks + + .import setscrptr, popax + .importzp ptr1, ptr2, ptr3, tmp1, tmp2 + + .macpack generic + + +_cpeeks: + eor #<$FFFF ; counting a word upward is faster + sta ptr3 ; so, we use -(length + 1) + txa + eor #>$FFFF + sta ptr3+1 + + jsr setscrptr ; Set ptr2 and .Y to the cursor's address + sty tmp2 + + jsr popax + sta tmp1 ; (will be a .Y index) + stx ptr1+1 + ldx #<$0000 + stx ptr1 + bze L3 ; branch always + +L4: ldy tmp2 + lda (ptr2),y ; Get char + iny + bnz L2 + inc ptr2+1 +L2: sty tmp2 + and #<~$80 ; Remove reverse bit + ldy tmp1 + sta (ptr1),y + iny + bnz L1 + inc ptr1+1 +L1: sty tmp1 + +L3: inc ptr3 ; count length + bnz L4 + inc ptr3+1 + bnz L4 + + txa ; terminate the string + ldy tmp1 + sta (ptr1),y + rts diff --git a/targettest/Makefile b/targettest/Makefile index 4d989d0df..35b767727 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -540,12 +540,13 @@ EXELIST_sym1 = \ strnlen \ strqtok-test -# omitted: clock-test cpeek-test conio deb dir-test em-test exec-test1 exec-test2 +# omitted: clock-test cpeek-test deb dir-test em-test exec-test1 exec-test2 # fileio-test ft mouse-test posixio-test rename-test seek ser-test EXELIST_atmos = \ minimal \ arg-test \ clock \ + conio \ cprintf \ cursor \ div-test \ diff --git a/targettest/conio.c b/targettest/conio.c index e054319e5..56fc5dcda 100644 --- a/targettest/conio.c +++ b/targettest/conio.c @@ -24,6 +24,12 @@ #define NUMCOLS 16 #endif +#if defined(__ATMOS__) +// FIXME: those should be defined elsewhere? +#define CH_HLINE '-' +#define CH_VLINE '!' +#endif + static char grid[5][5] = { {CH_ULCORNER, CH_HLINE, CH_TTEE, CH_HLINE, CH_URCORNER}, {CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE }, @@ -73,6 +79,14 @@ void peektest(void) revers(rbuf[j]); cputc(buf[j]); } + gotoxy(0, LINE_PEEKTEST); + cpeeks(buf, NUMCOLS); + (void)textcolor(1); + revers(0); + gotoxy(20, LINE_PEEKTEST); + for (j = 0; j < NUMCOLS; ++j) { + cputc(buf[j]); + } } void main(void) From 5c72deb0b98ad6e71d64f446a93d3700117bb7d9 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 25 May 2025 01:38:32 +0200 Subject: [PATCH 429/707] prepare osic1p cpeekc/cpeekcolor/cpeekrevers, replaces #532 --- libsrc/osic1p/cpeekc.s | 17 +++++++++++++++++ libsrc/osic1p/cpeekcolor.s | 8 ++++++++ libsrc/osic1p/cpeekrevers.s | 9 +++++++++ targettest/Makefile | 1 + targettest/conio.c | 15 ++++++++++++--- 5 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 libsrc/osic1p/cpeekc.s create mode 100644 libsrc/osic1p/cpeekcolor.s create mode 100644 libsrc/osic1p/cpeekrevers.s diff --git a/libsrc/osic1p/cpeekc.s b/libsrc/osic1p/cpeekc.s new file mode 100644 index 000000000..55a170501 --- /dev/null +++ b/libsrc/osic1p/cpeekc.s @@ -0,0 +1,17 @@ +; +; 2017-06-21, Greg King +; +; char cpeekc (void); +; +; Get a character from OSI C1P screen RAM. +; + .export _cpeekc + + .include "extzp.inc" + + +_cpeekc: + ldy CURS_X + lda (SCREEN_PTR),y + ldx #>$0000 + rts diff --git a/libsrc/osic1p/cpeekcolor.s b/libsrc/osic1p/cpeekcolor.s new file mode 100644 index 000000000..ed275ec95 --- /dev/null +++ b/libsrc/osic1p/cpeekcolor.s @@ -0,0 +1,8 @@ +; +; 2017-06-03, Greg King +; +; unsigned char cpeekcolor (void); +; + + .import return1 + .export _cpeekcolor := return1 ; always COLOR_WHITE diff --git a/libsrc/osic1p/cpeekrevers.s b/libsrc/osic1p/cpeekrevers.s new file mode 100644 index 000000000..ab7c68b35 --- /dev/null +++ b/libsrc/osic1p/cpeekrevers.s @@ -0,0 +1,9 @@ +; +; 2017-06-15, Greg King +; +; unsigned char cpeekrevers (void); +; +; Get a reverse attribute from screen RAM +; + .import return0 + .export _cpeekrevers := return0 ; No attribute diff --git a/targettest/Makefile b/targettest/Makefile index 35b767727..f78e22461 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -624,6 +624,7 @@ EXELIST_pce = \ # stroserror-test strqtok-test uname-test EXELIST_osic1p = \ minimal \ + conio \ cursor \ mul-test diff --git a/targettest/conio.c b/targettest/conio.c index 56fc5dcda..8ebb15bd5 100644 --- a/targettest/conio.c +++ b/targettest/conio.c @@ -15,12 +15,16 @@ #include <stdlib.h> #include <joystick.h> -#if defined(__GAMATE__) +#if defined(__GAMATE__) || defined(__OSIC1P__) /* there is not enough screen space to show all 256 characters at the bottom */ #define NUMCHARS 128 -#define NUMCOLS 4 #else #define NUMCHARS 256 +#endif + +#if defined(__GAMATE__) +#define NUMCOLS 4 +#else #define NUMCOLS 16 #endif @@ -79,6 +83,7 @@ void peektest(void) revers(rbuf[j]); cputc(buf[j]); } +#if !defined (__OSIC1P__) gotoxy(0, LINE_PEEKTEST); cpeeks(buf, NUMCOLS); (void)textcolor(1); @@ -87,6 +92,7 @@ void peektest(void) for (j = 0; j < NUMCOLS; ++j) { cputc(buf[j]); } +#endif } void main(void) @@ -134,7 +140,8 @@ void main(void) } } - gotoxy(0, ysize - 2 - ((NUMCHARS + xsize) / xsize)); + gotoxy(0, ysize - 3 - ((NUMCHARS + xsize) / xsize)); + // one line with 0123..pattern revers(1); for (i = 0; i < xsize; ++i) { cputc('0' + i % 10); @@ -147,9 +154,11 @@ void main(void) cputc(' '); } } + // fill last line of the block with '#' while(wherex() > 0) { cputc('#'); } + // one more line with 0123..pattern revers(1); for (i = 0; i < xsize; ++i) { cputc('0' + i % 10); From e9a15af29b406ec9e8ea64fd58997c03f6eb6463 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 25 May 2025 02:52:03 +0200 Subject: [PATCH 430/707] cleanup/fix pce cpeekc/cpeekcolor/cpeekrevers/cpeeks, replaces #532 --- libsrc/pce/cpeekc.s | 6 +++--- libsrc/pce/cpeekcolor.s | 6 +++--- libsrc/pce/cpeekrevers.s | 15 ++++++++------- libsrc/pce/cpeeks.s | 28 +++++++++++----------------- 4 files changed, 25 insertions(+), 30 deletions(-) diff --git a/libsrc/pce/cpeekc.s b/libsrc/pce/cpeekc.s index e144f94ac..326fe5203 100644 --- a/libsrc/pce/cpeekc.s +++ b/libsrc/pce/cpeekc.s @@ -14,11 +14,11 @@ _cpeekc: st0 #VDC_MARR ; Memory-Address Read ldy SCREEN_PTR ldx SCREEN_PTR+1 - sty VDC_DATA_LO - stx VDC_DATA_HI + sty a:VDC_DATA_LO + stx a:VDC_DATA_HI st0 #VDC_VRR ; VRAM Read Register - lda VDC_DATA_LO ; character + lda a:VDC_DATA_LO ; character and #<~$80 ; remove reverse bit ldx #0 rts diff --git a/libsrc/pce/cpeekcolor.s b/libsrc/pce/cpeekcolor.s index 8b96d29d4..ecee91ed5 100644 --- a/libsrc/pce/cpeekcolor.s +++ b/libsrc/pce/cpeekcolor.s @@ -14,11 +14,11 @@ _cpeekcolor: st0 #VDC_MARR ; Memory-Address Read ldy SCREEN_PTR ldx SCREEN_PTR+1 - sty VDC_DATA_LO - stx VDC_DATA_HI + sty a:VDC_DATA_LO + stx a:VDC_DATA_HI st0 #VDC_VRR ; VRAM Read Register - lda VDC_DATA_HI + lda a:VDC_DATA_HI and #<~$02 lsr a lsr a diff --git a/libsrc/pce/cpeekrevers.s b/libsrc/pce/cpeekrevers.s index 3f208fd10..8fa173202 100644 --- a/libsrc/pce/cpeekrevers.s +++ b/libsrc/pce/cpeekrevers.s @@ -14,13 +14,14 @@ _cpeekrevers: st0 #VDC_MARR ; Memory-Address Read ldy SCREEN_PTR ldx SCREEN_PTR+1 - sty VDC_DATA_LO - stx VDC_DATA_HI + sty a:VDC_DATA_LO + stx a:VDC_DATA_HI st0 #VDC_VRR ; VRAM Read Register - lda VDC_DATA_LO ; character (bit 7 is revers bit) - rol a - rol a - and #1 - ldx #0 + + lda a:VDC_DATA_LO ; character (bit 7 is revers bit) + and #$80 ; get reverse bit + asl a ; reverse bit to carry, A=0 + tax ; ldx #>$0000 + rol a ; reverse bit from carry rts diff --git a/libsrc/pce/cpeeks.s b/libsrc/pce/cpeeks.s index fe5e28687..322b9ba30 100644 --- a/libsrc/pce/cpeeks.s +++ b/libsrc/pce/cpeeks.s @@ -1,5 +1,6 @@ ; ; 2020-07-14, Groepaz +; 2020-07-15, Greg King ; ; void cpeeks (char* s, unsigned length); ; @@ -8,9 +9,7 @@ .export _cpeeks .import popax - .importzp ptr1, ptr2, tmp1, tmp2 - - .macpack generic + .importzp ptr1, ptr2 .include "pce.inc" .include "extzp.inc" @@ -22,35 +21,31 @@ _cpeeks: eor #>$FFFF sta ptr2+1 + st0 #VDC_CR ; Control Register + st2 #>$0088 ; make VRAM address increment by one + st0 #VDC_MARR ; Memory-Address Read ldy SCREEN_PTR ldx SCREEN_PTR+1 - sty VDC_DATA_LO - stx VDC_DATA_HI + sty a:VDC_DATA_LO + stx a:VDC_DATA_HI st0 #VDC_VRR ; VRAM Read Register jsr popax - sta tmp1 ; (will be a .Y index) + tay ; low byte of address will be used as index stx ptr1+1 - ldx #<$0000 stx ptr1 beq L2 ; branch always -L3: ldy tmp2 - lda VDC_DATA_LO ; get character - bit VDC_DATA_HI ; we need to "read" the highbyte to advance the address - iny - sty tmp2 +L3: lda a:VDC_DATA_LO ; get character + bit a:VDC_DATA_HI ; need to read high byte to advance VDC address and #<~$80 ; remove reverse bit - - ldy tmp1 sta (ptr1),y iny - bne L1 + bne L2 inc ptr1+1 -L1: sty tmp1 L2: inc ptr2 ; count length bne L3 @@ -58,6 +53,5 @@ L2: inc ptr2 ; count length bne L3 txa ; terminate the string - ldy tmp1 sta (ptr1),y rts From c996157f0ebd5b8ccf99a66049d2bf21b1ad35cb Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 25 May 2025 02:53:34 +0200 Subject: [PATCH 431/707] update conio test to reflect the state of cpeek implementation(s) --- targettest/conio.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/targettest/conio.c b/targettest/conio.c index 8ebb15bd5..db7752857 100644 --- a/targettest/conio.c +++ b/targettest/conio.c @@ -42,12 +42,15 @@ static char grid[5][5] = { {CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER} }; +#define LINE_COLORTEST 3 +#define LINE_PEEKTEST 11 + void colortest(void) { unsigned int i, j; cputsxy(0, 2, "Colors:" ); for (i = 0; i < 3; ++i) { - gotoxy(i, 3 + i); + gotoxy(i, LINE_COLORTEST + i); for (j = 0; j < NUMCOLS; ++j) { (void)textcolor(j); cputc('X'); @@ -55,8 +58,6 @@ void colortest(void) } } -#define LINE_PEEKTEST 11 - void peektest(void) { int j; @@ -69,13 +70,24 @@ void peektest(void) (void)textcolor(j); revers((j >> 1)&1); cputc('a' + j); - rbuf[j] = (j >> 1)&1; + buf[j] ='#'; + cbuf[j] = 1; + rbuf[j] = 0; } for (j = 0; j < NUMCOLS; ++j) { gotoxy(j, LINE_PEEKTEST); +// TODO: cpeekc() implementation missing for those: +#if !defined(__TELESTRAT__) buf[j] = cpeekc(); +#endif +// TODO: cpeekcolor() implementation missing for those: +#if !defined(__TELESTRAT__) cbuf[j] = cpeekcolor(); +#endif +// TODO: cpeekrevers() implementation missing for those: +#if !defined(__TELESTRAT__) rbuf[j] = cpeekrevers(); +#endif } gotoxy(0, (LINE_PEEKTEST+1)); for (j = 0; j < NUMCOLS; ++j) { @@ -83,7 +95,14 @@ void peektest(void) revers(rbuf[j]); cputc(buf[j]); } -#if !defined (__OSIC1P__) +// TODO: cpeeks() implementation missing for those: +#if !defined(__APPLE2__) && \ + !defined(__APPLE2ENH__) && \ + !defined(__ATARI__) && \ + !defined(__CX16__) && \ + !defined(__NES__) && \ + !defined(__TELESTRAT__) && \ + !defined(__OSIC1P__) gotoxy(0, LINE_PEEKTEST); cpeeks(buf, NUMCOLS); (void)textcolor(1); From bd63c6aa4b424bee3113772eefb210a7e48535c2 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 25 May 2025 03:23:54 +0200 Subject: [PATCH 432/707] move char block printing into function --- targettest/conio.c | 54 +++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/targettest/conio.c b/targettest/conio.c index db7752857..e270d3dab 100644 --- a/targettest/conio.c +++ b/targettest/conio.c @@ -114,6 +114,35 @@ void peektest(void) #endif } +void allchars(int xsize, int ysize) +{ + int i; + gotoxy(0, ysize - 2 - ((NUMCHARS + (xsize-1)) / xsize)); + // one line with 0123..pattern + revers(1); + for (i = 0; i < xsize; ++i) { + cputc('0' + i % 10); + } + revers(0); + for (i = 0; i < NUMCHARS; ++i) { + if ((i != '\n') && (i != '\r')) { + cputc(i); + } else { + cputc(' '); + } + } + // fill last line of the block with '#' + while(wherex() > 0) { + cputc('#'); + } + // one more line with 0123..pattern + revers(1); + for (i = 0; i < xsize; ++i) { + cputc('0' + i % 10); + } + revers(0); +} + void main(void) { unsigned int i, j, n; @@ -159,30 +188,7 @@ void main(void) } } - gotoxy(0, ysize - 3 - ((NUMCHARS + xsize) / xsize)); - // one line with 0123..pattern - revers(1); - for (i = 0; i < xsize; ++i) { - cputc('0' + i % 10); - } - revers(0); - for (i = 0; i < NUMCHARS; ++i) { - if ((i != '\n') && (i != '\r')) { - cputc(i); - } else { - cputc(' '); - } - } - // fill last line of the block with '#' - while(wherex() > 0) { - cputc('#'); - } - // one more line with 0123..pattern - revers(1); - for (i = 0; i < xsize; ++i) { - cputc('0' + i % 10); - } - revers(0); + allchars(xsize, ysize); cursor(1); for (;;) { From 0d9ae7cb708d3948ec02a776d28766b542ed0a58 Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Sun, 25 May 2025 03:44:36 +0200 Subject: [PATCH 433/707] Update kgetin.s use symbol from cbm_kernal.inc --- libsrc/plus4/kgetin.s | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libsrc/plus4/kgetin.s b/libsrc/plus4/kgetin.s index 14919f750..e77395b9a 100644 --- a/libsrc/plus4/kgetin.s +++ b/libsrc/plus4/kgetin.s @@ -1,14 +1,17 @@ -.export GETIN -.include "plus4.inc" + .export GETIN -KERNAL_GETIN := $FFE4 +.scope KERNAL + .include "cbm_kernal.inc" +.endscope + + .include "plus4.inc" .segment "LOWCODE" ; Stay out of ROM area. .proc GETIN sta ENABLE_ROM - jsr KERNAL_GETIN + jsr KERNAL::GETIN sta ENABLE_RAM rts .endproc From cd92e4f0af9eb1c1963136da44b74ac56f9be198 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Sun, 11 May 2025 11:49:53 +0200 Subject: [PATCH 434/707] Apple2: Set mousecard IRQ rate when possible --- libsrc/apple2/get_tv.s | 2 +- libsrc/apple2/libref.s | 3 +-- libsrc/apple2/mou/a2.stdmou.s | 29 ++++++++++++++++++++++++++++- libsrc/apple2/mouseref.s | 25 +++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 libsrc/apple2/mouseref.s diff --git a/libsrc/apple2/get_tv.s b/libsrc/apple2/get_tv.s index 830cc4ac1..b2eb4d857 100644 --- a/libsrc/apple2/get_tv.s +++ b/libsrc/apple2/get_tv.s @@ -8,7 +8,7 @@ .import _set_iigs_speed, _get_iigs_speed .import ostype - .constructor calibrate_tv, 2 + .constructor calibrate_tv, 8 ; After ostype .include "accelerator.inc" .include "apple2.inc" diff --git a/libsrc/apple2/libref.s b/libsrc/apple2/libref.s index 8aa54abab..e3d713a5d 100644 --- a/libsrc/apple2/libref.s +++ b/libsrc/apple2/libref.s @@ -2,10 +2,9 @@ ; Oliver Schmidt, 2013-05-31 ; - .export em_libref, mouse_libref, ser_libref, tgi_libref + .export em_libref, ser_libref, tgi_libref .import _exit em_libref := _exit -mouse_libref := _exit ser_libref := _exit tgi_libref := _exit diff --git a/libsrc/apple2/mou/a2.stdmou.s b/libsrc/apple2/mou/a2.stdmou.s index e48abbb41..9c2f96200 100644 --- a/libsrc/apple2/mou/a2.stdmou.s +++ b/libsrc/apple2/mou/a2.stdmou.s @@ -7,6 +7,7 @@ .include "zeropage.inc" .include "mouse-kernel.inc" .include "apple2.inc" + .include "get_tv.inc" .macpack module @@ -21,6 +22,7 @@ CLAMPMOUSE = $17 ; Sets mouse bounds in a window HOMEMOUSE = $18 ; Sets mouse to upper-left corner of clamp win INITMOUSE = $19 ; Resets mouse clamps to default values and ; sets mouse position to 0,0 +TIMEDATA = $1C ; Set mousecard's interrupt rate pos1_lo := $0478 pos1_hi := $0578 @@ -41,6 +43,7 @@ status := $0778 .byte MOUSE_API_VERSION ; Mouse driver API version number ; Library reference +libref: .addr $0000 ; Jump table @@ -169,7 +172,31 @@ next: inc ptr1+1 asl sta yparam+1 - ; The AppleMouse II Card needs the ROM switched in + ; Apple II technical notes "Varying VBL Interrupt Rate", + lda libref + ldx libref+1 + sta ptr1 + stx ptr1+1 + + .ifdef __APPLE2ENH__ + lda (ptr1) + .else + ldy #$00 + lda (ptr1),y + .endif + + cmp #TV::OTHER + beq :+ + + ; The TV values are aligned with the values the mousecard + ; expect: 0 for 60Hz, 1 for 50Hz. + .assert TV::NTSC = 0, error + .assert TV::PAL = 1, error + + ldx #TIMEDATA + jsr firmware + +: ; The AppleMouse II Card needs the ROM switched in ; to be able to detect an Apple //e and use RDVBL bit $C082 diff --git a/libsrc/apple2/mouseref.s b/libsrc/apple2/mouseref.s new file mode 100644 index 000000000..b0e75c367 --- /dev/null +++ b/libsrc/apple2/mouseref.s @@ -0,0 +1,25 @@ +; +; Colin Leroy-Mira, 2025-05-11 +; + + .export mouse_libref + .import _get_tv, ostype, return0 + + .constructor init_mousetv + + .include "get_tv.inc" + + .segment "ONCE" + +.proc init_mousetv + lda ostype + cmp #$40 ; Technical notes say not to change + bcs :+ ; interrupt rate on IIc/IIgs, so... + jsr _get_tv + sta mouse_libref +: rts ; ...don't update "Other" on those machines +.endproc + + .data + +mouse_libref: .byte TV::OTHER From e451134e233d1c9844f62e61a844ce42dc7c36a1 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Tue, 27 May 2025 05:03:17 +0000 Subject: [PATCH 435/707] fixes issue #2446 --- src/cl65/main.c | 14 +++++++++++++- src/common/fname.c | 21 +++++++++++++++++++++ src/common/fname.h | 6 ++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 31d805181..4a39263af 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -620,6 +620,9 @@ static void Assemble (const char* File) static void Compile (const char* File) /* Compile the given file */ { + /* A temporary file name passed to the assembler */ + char *TmpFile = NULL; + /* Remember the current compiler argument count */ unsigned ArgCount = CC65.ArgCount; @@ -657,6 +660,12 @@ static void Compile (const char* File) /* Add the file as argument for the compiler */ CmdAddArg (&CC65, File); + if (DoAssemble && DoLink) { + /* set a temporary output file name */ + TmpFile = MakeTmpFilename(File, ".s"); + CmdSetOutput (&CC65, TmpFile); + } + /* Add a NULL pointer to terminate the argument list */ CmdAddArg (&CC65, 0); @@ -671,7 +680,10 @@ static void Compile (const char* File) */ if (DoAssemble) { /* Assemble the intermediate file and remove it */ - AssembleIntermediate (File); + AssembleIntermediate (TmpFile ? TmpFile : File); + if (TmpFile) { + xfree(TmpFile); + } } } diff --git a/src/common/fname.c b/src/common/fname.c index 4e4f7c7fa..c5000bc72 100644 --- a/src/common/fname.c +++ b/src/common/fname.c @@ -33,6 +33,7 @@ +#include <stdio.h> #include <string.h> #include "xmalloc.h" @@ -115,3 +116,23 @@ char* MakeFilename (const char* Origin, const char* Ext) } return Out; } + + + +char* MakeTmpFilename (const char* Origin, const char* Ext) +/* Make a new temporary file name from Ext. tmpnam(3) is called +** and Ext is appended to generate the filename. Origin is ignored. +** The result is placed in a malloc'ed buffer and returned. +*/ +{ + char* Out; + char Buffer[L_tmpnam * 2]; /* a lazy way to ensure we have space for Ext */ + + tmpnam(Buffer); + strcat(Buffer, Ext); + + Out = xmalloc (strlen (Buffer) + 1); + strcpy (Out, Buffer); + + return Out; +} diff --git a/src/common/fname.h b/src/common/fname.h index 1b94d270c..1dc985f93 100644 --- a/src/common/fname.h +++ b/src/common/fname.h @@ -59,6 +59,12 @@ char* MakeFilename (const char* Origin, const char* Ext); ** The function may be used to create "foo.o" from "foo.s". */ +char* MakeTmpFilename (const char* Origin, const char* Ext); +/* Make a new temporary file name from Ext. tmpnam(3) is called +** and Ext is appended to generate the filename. Origin is ignored. +** The result is placed in a malloc'ed buffer and returned. +*/ + /* End of fname.h */ From 11d3338282f815cb579906edc40da179803d8c44 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Tue, 27 May 2025 06:00:24 +0000 Subject: [PATCH 436/707] bugfixes --- src/cl65/main.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 4a39263af..900602c87 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -526,12 +526,15 @@ static void Link (void) -static void AssembleFile (const char* File, unsigned ArgCount) +static void AssembleFile (const char* File, const char* TmpFile, unsigned ArgCount) /* Common routine to assemble a file. Will be called by Assemble() and ** AssembleIntermediate(). Adds options common for both routines and ** assembles the file. Will remove excess arguments after assembly. */ { + /* ObjName may be used for temporary or real filename */ + char *ObjName; + /* Set the target system */ CmdSetTarget (&CA65, Target); @@ -541,7 +544,8 @@ static void AssembleFile (const char* File, unsigned ArgCount) ** to the file list of the linker. The name of the output ** file is that of the input file with ".s" replaced by ".o". */ - char* ObjName = MakeFilename (File, ".o"); + ObjName = MakeFilename (TmpFile ? TmpFile : File, ".o"); + CmdSetOutput (&CA65, ObjName); CmdAddFile (&LD65, ObjName); /* This is just a temporary file, schedule it for removal */ CmdAddFile (&RM, ObjName); @@ -551,10 +555,15 @@ static void AssembleFile (const char* File, unsigned ArgCount) if (OutputName) { CmdSetOutput (&CA65, OutputName); } + else { + ObjName = MakeFilename (File, ".o"); + CmdSetOutput (&CA65, ObjName); + xfree (ObjName); + } } /* Add the file as argument for the assembler */ - CmdAddArg (&CA65, File); + CmdAddArg (&CA65, TmpFile ? TmpFile : File); /* Add a NULL pointer to terminate the argument list */ CmdAddArg (&CA65, 0); @@ -568,7 +577,7 @@ static void AssembleFile (const char* File, unsigned ArgCount) -static void AssembleIntermediate (const char* SourceFile) +static void AssembleIntermediate (const char* SourceFile, const char* TmpFile) /* Assemble an intermediate file which was generated by a previous processing ** step with SourceFile as input. The -dep options won't be added and ** the intermediate assembler file is removed after assembly. @@ -578,18 +587,20 @@ static void AssembleIntermediate (const char* SourceFile) ** name. It's the same name with the extension replaced by ".s" */ char* AsmName = MakeFilename (SourceFile, ".s"); + char* AsmTmpName = TmpFile ? MakeFilename(TmpFile, ".s") : NULL; /* Assemble the intermediate assembler file */ - AssembleFile (AsmName, CA65.ArgCount); + AssembleFile (AsmName, AsmTmpName, CA65.ArgCount); /* Remove the input file */ - if (remove (AsmName) < 0) { + if (remove (AsmTmpName ? AsmTmpName : AsmName) < 0) { Warning ("Cannot remove temporary file '%s': %s", - AsmName, strerror (errno)); + AsmTmpName ? AsmTmpName : AsmName, strerror (errno)); } /* Free the assembler file name which was allocated from the heap */ xfree (AsmName); + xfree (AsmTmpName); } @@ -612,7 +623,7 @@ static void Assemble (const char* File) } /* Use the common routine */ - AssembleFile (File, ArgCount); + AssembleFile (File, NULL, ArgCount); } @@ -660,7 +671,7 @@ static void Compile (const char* File) /* Add the file as argument for the compiler */ CmdAddArg (&CC65, File); - if (DoAssemble && DoLink) { + if (DoAssemble) { /* set a temporary output file name */ TmpFile = MakeTmpFilename(File, ".s"); CmdSetOutput (&CC65, TmpFile); @@ -680,7 +691,7 @@ static void Compile (const char* File) */ if (DoAssemble) { /* Assemble the intermediate file and remove it */ - AssembleIntermediate (TmpFile ? TmpFile : File); + AssembleIntermediate (File, TmpFile); if (TmpFile) { xfree(TmpFile); } @@ -717,7 +728,7 @@ static void CompileRes (const char* File) */ if (DoAssemble) { /* Assemble the intermediate file and remove it */ - AssembleIntermediate (File); + AssembleIntermediate (File, NULL); } } @@ -753,7 +764,7 @@ static void ConvertO65 (const char* File) */ if (DoAssemble) { /* Assemble the intermediate file and remove it */ - AssembleIntermediate (File); + AssembleIntermediate (File, NULL); } } From 9a2f754e8d5ecea6fc17ade5165e64b4f66897c6 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Tue, 27 May 2025 06:18:24 +0000 Subject: [PATCH 437/707] fixes problems found by github autobuild --- src/cl65/main.c | 2 +- src/common/fname.c | 16 +++++++++++++--- src/common/fname.h | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 900602c87..8d8aac932 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -673,7 +673,7 @@ static void Compile (const char* File) if (DoAssemble) { /* set a temporary output file name */ - TmpFile = MakeTmpFilename(File, ".s"); + TmpFile = MakeTmpFilename(".s"); CmdSetOutput (&CC65, TmpFile); } diff --git a/src/common/fname.c b/src/common/fname.c index c5000bc72..f026f776d 100644 --- a/src/common/fname.c +++ b/src/common/fname.c @@ -119,16 +119,26 @@ char* MakeFilename (const char* Origin, const char* Ext) -char* MakeTmpFilename (const char* Origin, const char* Ext) +char* MakeTmpFilename (const char* Ext) /* Make a new temporary file name from Ext. tmpnam(3) is called -** and Ext is appended to generate the filename. Origin is ignored. +** and Ext is appended to generate the filename. ** The result is placed in a malloc'ed buffer and returned. */ { char* Out; char Buffer[L_tmpnam * 2]; /* a lazy way to ensure we have space for Ext */ - tmpnam(Buffer); + /* + ** gcc emits the following warning here: + ** + ** warning: the use of `tmpnam' is dangerous, better use `mkstemp' + ** + ** however, mkstemp actually opens a file, which we do not want. + ** we could write our own version, but then we would have to struggle + ** with supporting multiple build environments. tmpnam(3) is fine + ** here. + */ + (void) tmpnam(Buffer); strcat(Buffer, Ext); Out = xmalloc (strlen (Buffer) + 1); diff --git a/src/common/fname.h b/src/common/fname.h index 1dc985f93..cd163e4e7 100644 --- a/src/common/fname.h +++ b/src/common/fname.h @@ -59,7 +59,7 @@ char* MakeFilename (const char* Origin, const char* Ext); ** The function may be used to create "foo.o" from "foo.s". */ -char* MakeTmpFilename (const char* Origin, const char* Ext); +char* MakeTmpFilename (const char* Ext); /* Make a new temporary file name from Ext. tmpnam(3) is called ** and Ext is appended to generate the filename. Origin is ignored. ** The result is placed in a malloc'ed buffer and returned. From ca8b0726088083d8e5e08d0472915d6489efd867 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Tue, 27 May 2025 06:30:12 +0000 Subject: [PATCH 438/707] fixed another pedantic github build problem --- src/common/fname.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/common/fname.c b/src/common/fname.c index f026f776d..4dc7006f7 100644 --- a/src/common/fname.c +++ b/src/common/fname.c @@ -134,12 +134,17 @@ char* MakeTmpFilename (const char* Ext) ** 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 fine - ** here. + ** 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) */ - (void) tmpnam(Buffer); - strcat(Buffer, Ext); + strcat(tmpnam(Buffer), Ext); Out = xmalloc (strlen (Buffer) + 1); strcpy (Out, Buffer); From a1139aa6b8696063fa32e3696295f46db48b2b11 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Tue, 27 May 2025 06:31:54 +0000 Subject: [PATCH 439/707] removed dangling space --- src/common/fname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/fname.c b/src/common/fname.c index 4dc7006f7..e67470b33 100644 --- a/src/common/fname.c +++ b/src/common/fname.c @@ -138,7 +138,7 @@ char* MakeTmpFilename (const char* Ext) ** ** 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. ** From 9ae0eaafcc97b25fd145320bac4120c8bd6bb0dd Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Tue, 27 May 2025 14:13:52 +0000 Subject: [PATCH 440/707] fixed inaccurate comment --- src/common/fname.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/fname.h b/src/common/fname.h index cd163e4e7..852c4ae56 100644 --- a/src/common/fname.h +++ b/src/common/fname.h @@ -61,7 +61,7 @@ char* MakeFilename (const char* Origin, const char* Ext); char* MakeTmpFilename (const char* Ext); /* Make a new temporary file name from Ext. tmpnam(3) is called -** and Ext is appended to generate the filename. Origin is ignored. +** and Ext is appended to generate the filename. ** The result is placed in a malloc'ed buffer and returned. */ From 816666615b6e407ddbd924ee1ee5afaeb314b1b1 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Tue, 27 May 2025 16:31:23 +0200 Subject: [PATCH 441/707] Apple2: Make 80-columns support dynamic on apple2 target Add a machinetype identifier to help us quickly identify Apple //e (bit 7) and //e enhanced (bit 6). Use it in conio functions for 80-columns code instead of relying entirely on the __APPLE2ENH__ target. Move videomode() to the apple2 target, and have it return an error if 80-columns hardware is not available - this is a lie for now, it is considered available on //e enhanced, which may not be true, and not available on //e, which may also be not true. An ulterior patch will make that check correctly. Adapt the box/line drawing characters so that one can use MouseText on the apple2 target if it is available, by defining DYN_DRAW_BOX. No change by default: MouseText is considered available on apple2enh and not available on apple2. --- doc/apple2.sgml | 5 ++ doc/funcref.sgml | 12 +++-- include/apple2.h | 72 ++++++++++++++++++++++++- include/apple2enh.h | 23 -------- include/conio.h | 13 ++++- libsrc/apple2/boxchars.s | 73 ++++++++++++++++++++++++++ libsrc/apple2/cgetc.s | 13 +++-- libsrc/apple2/cpeekc.s | 19 +++++-- libsrc/apple2/cputc.s | 60 +++++++++++++++------ libsrc/apple2/dynchline.s | 41 +++++++++++++++ libsrc/apple2/dyncvline.s | 40 ++++++++++++++ libsrc/apple2/get_ostype.s | 2 + libsrc/apple2/gotoxy.s | 14 +++-- libsrc/apple2/libref.s | 3 +- libsrc/apple2/machinetype.s | 24 +++++++++ libsrc/apple2/mcbdefault.s | 19 ++++--- libsrc/apple2/{chline.s => mtchline.s} | 19 +++---- libsrc/apple2/{cvline.s => mtcvline.s} | 24 ++++----- libsrc/apple2/tgi/a2.hi.s | 37 ++++++++++--- libsrc/apple2/tgiref.s | 18 +++++++ libsrc/apple2/videomode.s | 39 ++++++++++---- libsrc/apple2/wherex.s | 13 +++-- targettest/conio.c | 47 +++++++++++++++++ 23 files changed, 523 insertions(+), 107 deletions(-) create mode 100644 libsrc/apple2/boxchars.s create mode 100644 libsrc/apple2/dynchline.s create mode 100644 libsrc/apple2/dyncvline.s create mode 100644 libsrc/apple2/machinetype.s rename libsrc/apple2/{chline.s => mtchline.s} (68%) rename libsrc/apple2/{cvline.s => mtcvline.s} (57%) create mode 100644 libsrc/apple2/tgiref.s diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 9cff996b7..719e799f4 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -361,6 +361,7 @@ usage. <item>rebootafterexit <item>ser_apple2_slot <item>tgi_apple2_mix +<item>videomode </itemize> @@ -406,6 +407,10 @@ The names in the parentheses denote the symbols to be used for static linking of with <tt/-S $4000/ to reserve the first hires page or with <tt/-S $6000/ to reserve both hires pages. + Note that the second hires page is only available if the text display is not in + 80 column mode. This can be asserted by calling <tt/videomode (VIDEOMODE_40COL);/ + before installing the driver. + The function <tt/tgi_apple2_mix()/ allows to activate 4 lines of text. The function doesn't clear the corresponding area at the bottom of the screen. diff --git a/doc/funcref.sgml b/doc/funcref.sgml index e534b47be..07d538781 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -103,6 +103,7 @@ function. <item><ref id="gmtime_dt" name="gmtime_dt"> <item><ref id="mktime_dt" name="mktime_dt"> <item>rebootafterexit +<item><ref id="videomode" name="videomode"> </itemize> @@ -8477,24 +8478,27 @@ used in presence of a prototype. <tag/Function/Switch to either 40- or 80-column text mode, or a standard graphics mode. <tag/Header/<tt/ +<ref id="apple2.h" name="apple2.h">, <ref id="apple2enh.h" name="apple2enh.h">, <ref id="c128.h" name="c128.h">, <ref id="cx16.h" name="cx16.h">/ <tag/Declaration/ -<tt>unsigned __fastcall__ videomode (unsigned Mode); /* for apple2enh and c128 */</tt><newline> -<tt>signed char __fastcall__ videomode (signed char Mode); /* for cx16 */</tt> +<tt>unsigned __fastcall__ videomode (unsigned Mode); /* for c128 */</tt><newline> +<tt>signed char __fastcall__ videomode (signed char Mode); /* for apple2 and cx16 */</tt> <tag/Description/Switch to a 40- or 80-column text or graphics mode, depending on the argument. If the requested mode is already active, nothing happens. The old mode is returned from the call. <tag/Notes/<itemize> -<item>The function is specific to the Commodore 128, the enhanced Apple //e, +<item>The function is specific to the Commodore 128, the Apple II, and the Commander X16. <item>This function replaces <ref id="toggle_videomode" name="toggle_videomode">. <item>The function is available as only a fastcall function, so it may be used only in the presence of a prototype. +<item>On Apple II, this functions returns the previously active video mode, or -1 +if the mode is not supported due to lack of hardware. </itemize> -<tag/Availability/C128, enhanced Apple //e, and CX16 +<tag/Availability/C128, Apple II, and CX16 <tag/See also/ <ref id="fast" name="fast">, <ref id="isfast" name="isfast">, diff --git a/include/apple2.h b/include/apple2.h index 9f7526f59..e4c8d89b1 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -83,7 +83,57 @@ #define CH_CURS_LEFT 0x08 #define CH_CURS_RIGHT 0x15 -#if !defined(__APPLE2ENH__) +#if defined(__APPLE2ENH__) + +/* MouseText-based functions for boxes and lines drawing */ +void mt_chline (unsigned char length); +void mt_cvline (unsigned char length); +void mt_chlinexy (unsigned char x, unsigned char y, unsigned char length); +void mt_cvlinexy (unsigned char x, unsigned char y, unsigned char length); + +#define CH_HLINE 0x5F +#define CH_VLINE 0xDF +#define CH_ULCORNER 0x5F +#define CH_URCORNER 0x20 +#define CH_LLCORNER 0xD4 +#define CH_LRCORNER 0xDF +#define CH_TTEE 0x5F +#define CH_BTEE 0xD4 +#define CH_LTEE 0xD4 +#define CH_RTEE 0xDF +#define CH_CROSS 0xD4 + +#define _chline(length) mt_chline(length) +#define _chlinexy(x,y,length) mt_chlinexy(x,y,length) +#define _cvline(length) mt_cvline(length) +#define _cvlinexy(x,y,length) mt_cvlinexy(x,y,length) + +#else + +/* Functions that don't depend on MouseText to draw boxes and lines */ +void dyn_chline (unsigned char h, unsigned char length); +void dyn_cvline (unsigned char v, unsigned char length); +void dyn_chlinexy (unsigned char h, unsigned char x, unsigned char y, unsigned char length); +void dyn_cvlinexy (unsigned char v, unsigned char x, unsigned char y, unsigned char length); + +#if defined(DYN_BOX_DRAW) +/* When the user defines DYN_BOX_DRAW, we'll adapt to the machine +** we run on. + */ +extern char CH_HLINE; +extern char CH_VLINE; +extern char CH_ULCORNER; +extern char CH_URCORNER; +extern char CH_LLCORNER; +extern char CH_LRCORNER; +extern char CH_TTEE; +extern char CH_BTEE; +extern char CH_LTEE; +extern char CH_RTEE; +extern char CH_CROSS; + +#else +/* Otherwise, fallback to safety and don't use MouseText at all. */ #define CH_HLINE '-' #define CH_VLINE '!' #define CH_ULCORNER '+' @@ -95,7 +145,14 @@ #define CH_LTEE '+' #define CH_RTEE '+' #define CH_CROSS '+' -#endif +#endif /* DYN_BOX_DRAW */ + +#define _chline(length) dyn_chline(CH_HLINE, length) +#define _chlinexy(x, y, length) dyn_chlinexy(CH_HLINE, x ,y, length) +#define _cvline(length) dyn_cvline(CH_VLINE, length) +#define _cvlinexy(x, y, length) dyn_cvlinexy(CH_VLINE, x, y, length) + +#endif /* __APPLE2ENH__ */ /* Masks for joy_read */ #define JOY_UP_MASK 0x10 @@ -127,6 +184,12 @@ #define TV_PAL 1 #define TV_OTHER 2 +/* Video modes */ +#define VIDEOMODE_40x24 0x15 +#define VIDEOMODE_80x24 0x00 +#define VIDEOMODE_40COL VIDEOMODE_40x24 +#define VIDEOMODE_80COL VIDEOMODE_80x24 + extern unsigned char _dos_type; /* Valid _dos_type values: ** @@ -255,6 +318,11 @@ unsigned char __fastcall__ allow_lowercase (unsigned char onoff); */ #endif +signed char __fastcall__ videomode (unsigned mode); +/* Set the video mode, return the old mode, or -1 if 80-column hardware is not +** installed. Call with one of the VIDEOMODE_xx constants. +*/ + /* End of apple2.h */ diff --git a/include/apple2enh.h b/include/apple2enh.h index 864d24986..1dc75ae13 100644 --- a/include/apple2enh.h +++ b/include/apple2enh.h @@ -57,18 +57,6 @@ #define CH_CURS_UP 0x0B #define CH_CURS_DOWN 0x0A -#define CH_HLINE 0x5F -#define CH_VLINE 0xDF -#define CH_ULCORNER 0x5F -#define CH_URCORNER 0x20 -#define CH_LLCORNER 0xD4 -#define CH_LRCORNER 0xDF -#define CH_TTEE 0x5F -#define CH_BTEE 0xD4 -#define CH_LTEE 0xD4 -#define CH_RTEE 0xDF -#define CH_CROSS 0xD4 - /* These are defined to be OpenApple + NumberKey */ #define CH_F1 0xB1 #define CH_F2 0xB2 @@ -81,12 +69,6 @@ #define CH_F9 0xB9 #define CH_F10 0xB0 -/* Video modes */ -#define VIDEOMODE_40x24 0x15 -#define VIDEOMODE_80x24 0x00 -#define VIDEOMODE_40COL VIDEOMODE_40x24 -#define VIDEOMODE_80COL VIDEOMODE_80x24 - /*****************************************************************************/ @@ -112,11 +94,6 @@ extern void a2e_lo_tgi[]; -unsigned __fastcall__ videomode (unsigned mode); -/* Set the video mode, return the old mode. Call with one of the VIDEOMODE_xx -** constants. -*/ - void waitvsync (void); /* Wait for start of next frame */ diff --git a/include/conio.h b/include/conio.h index bac20e3c5..cf84d1742 100644 --- a/include/conio.h +++ b/include/conio.h @@ -216,7 +216,18 @@ void __fastcall__ cputhex16 (unsigned val); # define cpeekrevers() _cpeekrevers() #endif - +#ifdef _chline +# define chline(len) _chline(len) +#endif +#ifdef _cvline +# define cvline(len) _cvline(len) +#endif +#ifdef _chlinexy +# define chlinexy(x, y, len) _chlinexy(x, y, len) +#endif +#ifdef _cvlinexy +# define cvlinexy(x, y, len) _cvlinexy(x, y, len) +#endif /* End of conio.h */ #endif diff --git a/libsrc/apple2/boxchars.s b/libsrc/apple2/boxchars.s new file mode 100644 index 000000000..8feee3bd3 --- /dev/null +++ b/libsrc/apple2/boxchars.s @@ -0,0 +1,73 @@ +; +; Colin Leroy-Mira and Oliver Schmidt, 26.05.2025 +; +; Initialize box-drawing characters according to +; MouseText availability +; + +.ifndef __APPLE2ENH__ + + .constructor initboxchars + .import machinetype + + .export _CH_HLINE + .export _CH_VLINE + .export _CH_ULCORNER + .export _CH_URCORNER + .export _CH_LLCORNER + .export _CH_LRCORNER + .export _CH_TTEE + .export _CH_BTEE + .export _CH_LTEE + .export _CH_RTEE + .export _CH_CROSS + + .segment "ONCE" + +initboxchars: + bit machinetype ; IIe enhanced or newer? + bvs out + + ldx #NUM_BOXCHARS ; No mousetext, patch characters +: lda std_boxchars,x + sta boxchars,x + dex + bpl :- + +out: rts + +; Replacement chars for when MouseText is not available +std_boxchars: .byte '!' + .byte '-' + .byte '+' + .byte '+' + .byte '+' + .byte '+' + + .data + +; MouseText-based box characters +boxchars: +VERT: .byte $DF +HORIZ: .byte $5F +ULCORNER: .byte $5F +URCORNER: .byte $20 +LLCORNER: .byte $D4 +LRCORNER: .byte $DF + +NUM_BOXCHARS = *-boxchars + +; exported symbols, referencing our 6 bytes +_CH_HLINE = HORIZ +_CH_VLINE = VERT +_CH_ULCORNER = ULCORNER +_CH_URCORNER = URCORNER +_CH_LLCORNER = LLCORNER +_CH_LRCORNER = LRCORNER +_CH_TTEE = ULCORNER +_CH_BTEE = LLCORNER +_CH_LTEE = LLCORNER +_CH_RTEE = LRCORNER +_CH_CROSS = LLCORNER + +.endif ; not __APPLE2ENH__ diff --git a/libsrc/apple2/cgetc.s b/libsrc/apple2/cgetc.s index d2ebe5db8..b82238b02 100644 --- a/libsrc/apple2/cgetc.s +++ b/libsrc/apple2/cgetc.s @@ -7,6 +7,10 @@ ; .export _cgetc + + .ifndef __APPLE2ENH__ + .import machinetype + .endif .import cursor, putchardirect .include "zeropage.inc" @@ -18,11 +22,14 @@ _cgetc: beq :+ ; Show caret. - .ifdef __APPLE2ENH__ - lda #$7F | $80 ; Checkerboard, screen code - .else + .ifndef __APPLE2ENH__ lda #' ' | $40 ; Blank, flashing + bit machinetype + bpl put_caret .endif + + lda #$7F | $80 ; Checkerboard, screen code +put_caret: jsr putchardirect ; Saves old character in tmp3 ; Wait for keyboard strobe. diff --git a/libsrc/apple2/cpeekc.s b/libsrc/apple2/cpeekc.s index a6a082eab..4f5361461 100644 --- a/libsrc/apple2/cpeekc.s +++ b/libsrc/apple2/cpeekc.s @@ -4,14 +4,24 @@ ; char cpeekc (void); ; + .ifndef __APPLE2ENH__ + .import machinetype + .endif + .export _cpeekc .include "apple2.inc" _cpeekc: ldy CH - .ifdef __APPLE2ENH__ + sec ; Assume main memory + + .ifndef __APPLE2ENH__ + bit machinetype + bpl peek + .endif + bit RD80VID ; In 80 column mode? bpl peek ; No, just go ahead lda OURCH @@ -21,13 +31,12 @@ _cpeekc: php sei ; No valid MSLOT et al. in aux memory bit HISCR ; Assume SET80COL - .endif + peek: lda (BASL),Y ; Get character - .ifdef __APPLE2ENH__ bcs :+ ; In main memory bit LOWSCR plp -: .endif - eor #$80 ; Invert high bit + +: eor #$80 ; Invert high bit ldx #>$0000 rts diff --git a/libsrc/apple2/cputc.s b/libsrc/apple2/cputc.s index fdf799357..aa4a383b3 100644 --- a/libsrc/apple2/cputc.s +++ b/libsrc/apple2/cputc.s @@ -5,13 +5,13 @@ ; void __fastcall__ cputc (char c); ; - .ifdef __APPLE2ENH__ .constructor initconio - .endif .export _cputcxy, _cputc .export cputdirect, newline, putchar, putchardirect .import gotoxy, VTABZ + .ifndef __APPLE2ENH__ + .import machinetype .import uppercasemask .endif @@ -22,12 +22,16 @@ .segment "ONCE" - .ifdef __APPLE2ENH__ initconio: + .ifndef __APPLE2ENH__ + bit machinetype + bmi :+ + rts +: + .endif sta SETALTCHAR ; Switch in alternate charset bit LORES ; Limit SET80COL-HISCR to text rts - .endif .code @@ -52,14 +56,22 @@ _cputc: cputdirect: jsr putchar - .ifdef __APPLE2ENH__ + + .ifndef __APPLE2ENH__ + bit machinetype + bpl :+ + .endif bit RD80VID ; In 80 column mode? bpl :+ inc OURCH ; Bump to next column lda OURCH + .ifdef __APPLE2ENH__ bra check ; Must leave CH alone -: .endif - inc CH ; Bump to next column + .else + jmp check + .endif + +: inc CH ; Bump to next column lda CH check: cmp WNDWDTH bcc done @@ -67,13 +79,24 @@ check: cmp WNDWDTH left: .ifdef __APPLE2ENH__ stz CH ; Goto left edge of screen - bit RD80VID ; In 80 column mode? - bpl done - stz OURCH ; Goto left edge of screen .else - lda #$00 ; Goto left edge of screen + lda #$00 sta CH .endif + + .ifndef __APPLE2ENH__ + bit machinetype + bpl done + .endif + + bit RD80VID ; In 80 column mode? + bpl done + .ifdef __APPLE2ENH__ + stz OURCH ; Goto left edge of screen + .else + sta OURCH + .endif + done: rts newline: @@ -100,8 +123,14 @@ mask: and INVFLG ; Apply normal, inverse, flash putchardirect: tax ldy CH - .ifdef __APPLE2ENH__ + sec ; Assume main memory + + .ifndef __APPLE2ENH__ + bit machinetype + bpl put + .endif + bit RD80VID ; In 80 column mode? bpl put ; No, just go ahead lda OURCH @@ -111,14 +140,13 @@ putchardirect: php sei ; No valid MSLOT et al. in aux memory bit HISCR ; Assume SET80COL - .endif + put: lda (BASL),Y ; Get current character sta tmp3 ; Save old character for _cgetc txa sta (BASL),Y - .ifdef __APPLE2ENH__ + bcs :+ ; In main memory bit LOWSCR plp -: .endif - rts +: rts diff --git a/libsrc/apple2/dynchline.s b/libsrc/apple2/dynchline.s new file mode 100644 index 000000000..74cc5a41e --- /dev/null +++ b/libsrc/apple2/dynchline.s @@ -0,0 +1,41 @@ +; +; Ullrich von Bassewitz, 08.08.1998 +; Colin Leroy-Mira, 26.05.2025 +; +; void __fastcall__ dyn_chlinexy (unsigned char c, unsigned char x, unsigned char y, unsigned char length); +; void __fastcall__ dyn_chline (unsigned char c, unsigned char length); +; + +.ifndef __APPLE2ENH__ + + .export _dyn_chlinexy, _dyn_chline, chlinedirect + .import gotoxy, cputdirect, popa + .import machinetype + + .include "zeropage.inc" + .include "apple2.inc" + +_dyn_chlinexy: + pha ; Save the length + jsr gotoxy ; Call this one, will pop params + pla ; Restore the length and run into _chline + +_dyn_chline: + pha + jsr popa ; Get the character to draw + eor #$80 ; Invert high bit + tax + pla + +chlinedirect: + stx tmp1 + cmp #$00 ; Is the length zero? + beq done ; Jump if done + sta tmp2 +: lda tmp1 ; Screen code + jsr cputdirect ; Direct output + dec tmp2 + bne :- +done: rts + +.endif diff --git a/libsrc/apple2/dyncvline.s b/libsrc/apple2/dyncvline.s new file mode 100644 index 000000000..b74126a4d --- /dev/null +++ b/libsrc/apple2/dyncvline.s @@ -0,0 +1,40 @@ +; +; Ullrich von Bassewitz, 08.08.1998 +; Colin Leroy-Mira, 26.05.2025 +; +; void __fastcall__ dyn_cvlinexy (unsigned char c, unsigned char x, unsigned char y, unsigned char length); +; void __fastcall__ dyn_cvline (unsigned char c, unsigned char length); +; + +.ifndef __APPLE2ENH__ + + .export _dyn_cvlinexy, _dyn_cvline + .import gotoxy, putchar, newline, popa + .import machinetype + + .include "zeropage.inc" + +_dyn_cvlinexy: + pha ; Save the length + jsr gotoxy ; Call this one, will pop params + pla ; Restore the length and run into _cvline + +_dyn_cvline: + pha + jsr popa ; Get the character to draw + eor #$80 ; Invert high bit + tax + pla + + stx tmp1 + cmp #$00 ; Is the length zero? + beq done ; Jump if done + sta tmp2 +: lda tmp1 ; Screen code + jsr putchar ; Write, no cursor advance + jsr newline ; Advance cursor to next line + dec tmp2 + bne :- +done: rts + +.endif diff --git a/libsrc/apple2/get_ostype.s b/libsrc/apple2/get_ostype.s index ea9ff25cc..0bd53717c 100644 --- a/libsrc/apple2/get_ostype.s +++ b/libsrc/apple2/get_ostype.s @@ -4,6 +4,8 @@ ; unsigned char get_ostype (void) ; + ; Priority higher than the default one so that things depending + ; on ostype can get ostype set when called at normal priority .constructor initostype, 9 .export _get_ostype, ostype diff --git a/libsrc/apple2/gotoxy.s b/libsrc/apple2/gotoxy.s index 2a0261eba..2ecd2a513 100644 --- a/libsrc/apple2/gotoxy.s +++ b/libsrc/apple2/gotoxy.s @@ -8,6 +8,10 @@ .export gotoxy, _gotoxy, _gotox .import popa, VTABZ + .ifndef __APPLE2ENH__ + .import machinetype + .endif + .include "apple2.inc" gotoxy: @@ -22,9 +26,13 @@ _gotoxy: _gotox: sta CH ; Store X - .ifdef __APPLE2ENH__ + + .ifndef __APPLE2ENH__ + bit machinetype + bpl :+ + .endif + bit RD80VID ; In 80 column mode? bpl :+ sta OURCH ; Store X -: .endif - rts +: rts diff --git a/libsrc/apple2/libref.s b/libsrc/apple2/libref.s index e3d713a5d..9c6994a5d 100644 --- a/libsrc/apple2/libref.s +++ b/libsrc/apple2/libref.s @@ -2,9 +2,8 @@ ; Oliver Schmidt, 2013-05-31 ; - .export em_libref, ser_libref, tgi_libref + .export em_libref, ser_libref .import _exit em_libref := _exit ser_libref := _exit -tgi_libref := _exit diff --git a/libsrc/apple2/machinetype.s b/libsrc/apple2/machinetype.s new file mode 100644 index 000000000..7fa70f29f --- /dev/null +++ b/libsrc/apple2/machinetype.s @@ -0,0 +1,24 @@ +.ifndef __APPLE2ENH__ + + .constructor initmachinetype, 8 + + .import ostype + .export machinetype + + .segment "ONCE" + +initmachinetype: + ldx ostype + cpx #$31 ; Apple //e enhanced? + ror machinetype ; Carry to high bit + cpx #$30 ; Apple //e? + ror machinetype + rts + + .data + +; bit 7: Machine is a //e or newer +; bit 6: Machine is a //e enhanced or newer +machinetype: .byte 0 + +.endif diff --git a/libsrc/apple2/mcbdefault.s b/libsrc/apple2/mcbdefault.s index 556a9d8fb..6a369114c 100644 --- a/libsrc/apple2/mcbdefault.s +++ b/libsrc/apple2/mcbdefault.s @@ -9,6 +9,10 @@ .export _mouse_def_callbacks + .ifndef __APPLE2ENH__ + .import machinetype + .endif + .include "apple2.inc" ; ------------------------------------------------------------------------ @@ -42,11 +46,14 @@ cursor = '+' | $40 ; Flashing crosshair .endif getcursor: - .ifdef __APPLE2ENH__ + .ifndef __APPLE2ENH__ + bit machinetype + bpl column + .endif bit RD80VID ; In 80 column mode? bpl column ; No, skip bank switching switch: bit LOWSCR ; Patched at runtime - .endif + column: ldx #$00 ; Patched at runtime getscr: lda $0400,x ; Patched at runtime cmp #cursor @@ -55,9 +62,7 @@ getscr: lda $0400,x ; Patched at runtime setcursor: lda #cursor setscr: sta $0400,x ; Patched at runtime - .ifdef __APPLE2ENH__ bit LOWSCR ; Doesn't hurt in 40 column mode - .endif rts ; ------------------------------------------------------------------------ @@ -65,9 +70,7 @@ setscr: sta $0400,x ; Patched at runtime .code done: - .ifdef __APPLE2ENH__ bit LOWSCR ; Doesn't hurt in 40 column mode - .endif return: rts ; Hide the mouse cursor. @@ -108,14 +111,14 @@ movex: inx bcs :- stx column+1 - .ifdef __APPLE2ENH__ + + ; Patch switch anyway, it will just be skipped over if in 40-col mode adc #7 / 2 ; Left or right half of 40-col column? ldx #<LOWSCR ; Columns 1,3,5..79 bcs :+ .assert LOWSCR + 1 = HISCR, error inx ; Columns 0,2,4..78 : stx switch+1 - .endif rts ; Move the mouse cursor y position to the value in A/X. diff --git a/libsrc/apple2/chline.s b/libsrc/apple2/mtchline.s similarity index 68% rename from libsrc/apple2/chline.s rename to libsrc/apple2/mtchline.s index be157ca9e..71347c563 100644 --- a/libsrc/apple2/chline.s +++ b/libsrc/apple2/mtchline.s @@ -1,27 +1,26 @@ ; ; Ullrich von Bassewitz, 08.08.1998 +; Colin Leroy-Mira, 26.05.2025 ; -; void __fastcall__ chlinexy (unsigned char x, unsigned char y, unsigned char length); -; void __fastcall__ chline (unsigned char length); +; void __fastcall__ mt_chlinexy (unsigned char x, unsigned char y, unsigned char length); +; void __fastcall__ mt_chline (unsigned char length); ; - .export _chlinexy, _chline, chlinedirect +.ifdef __APPLE2ENH__ + + .export _mt_chlinexy, _mt_chline, chlinedirect .import gotoxy, cputdirect .include "zeropage.inc" .include "apple2.inc" -_chlinexy: +_mt_chlinexy: pha ; Save the length jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _chline -_chline: - .ifdef __APPLE2ENH__ +_mt_chline: ldx #'_' | $80 ; Underscore, screen code - .else - ldx #'-' | $80 ; Minus, screen code - .endif chlinedirect: stx tmp1 @@ -33,3 +32,5 @@ chlinedirect: dec tmp2 bne :- done: rts + +.endif diff --git a/libsrc/apple2/cvline.s b/libsrc/apple2/mtcvline.s similarity index 57% rename from libsrc/apple2/cvline.s rename to libsrc/apple2/mtcvline.s index 86bbf11f4..03e11bf51 100644 --- a/libsrc/apple2/cvline.s +++ b/libsrc/apple2/mtcvline.s @@ -1,34 +1,32 @@ ; ; Ullrich von Bassewitz, 08.08.1998 +; Colin Leroy-Mira, 26.05.2025 ; -; void __fastcall__ cvlinexy (unsigned char x, unsigned char y, unsigned char length); -; void __fastcall__ cvline (unsigned char length); +; void __fastcall__ mt_cvlinexy (unsigned char x, unsigned char y, unsigned char length); +; void __fastcall__ mt_cvline (unsigned char length); ; - .export _cvlinexy, _cvline +.ifdef __APPLE2ENH__ + + .export _mt_cvlinexy, _mt_cvline .import gotoxy, putchar, newline .include "zeropage.inc" -_cvlinexy: +_mt_cvlinexy: pha ; Save the length jsr gotoxy ; Call this one, will pop params pla ; Restore the length and run into _cvline -_cvline: - .ifdef __APPLE2ENH__ - ldx #$5F ; Left vertical line MouseText character - .else - ldx #'!' | $80 ; Exclamation mark, screen code - .endif - - stx tmp1 +_mt_cvline: cmp #$00 ; Is the length zero? beq done ; Jump if done sta tmp2 -: lda tmp1 ; Screen code +: lda #$5F ; Left vertical line MouseText character jsr putchar ; Write, no cursor advance jsr newline ; Advance cursor to next line dec tmp2 bne :- done: rts + +.endif diff --git a/libsrc/apple2/tgi/a2.hi.s b/libsrc/apple2/tgi/a2.hi.s index 1d5bdb68b..27c494421 100644 --- a/libsrc/apple2/tgi/a2.hi.s +++ b/libsrc/apple2/tgi/a2.hi.s @@ -83,7 +83,10 @@ Y2 := ptr4 .byte $74, $67, $69 ; "tgi" .byte TGI_API_VERSION ; TGI API version number + +libref: .addr $0000 ; Library reference + .word 280 ; X resolution .word 192 ; Y resolution .byte 8 ; Number of drawing colors @@ -120,6 +123,10 @@ pages: .byte 2 ; Number of screens available .bss +.ifndef __APPLE2ENH__ +machinetype: .res 1 +.endif + ; Absolute variables used in the code ERROR: .res 1 ; Error code @@ -146,13 +153,22 @@ FONT: ; most of the time. ; Must set an error code: NO INSTALL: - .ifdef __APPLE2ENH__ + .ifndef __APPLE2ENH__ + lda libref + ldx libref+1 + sta ptr1 + stx ptr1+1 + ldy #$0 + lda (ptr1),y + sta machinetype + bpl :+ + .endif ; No page switching if 80 column store is enabled bit RD80COL bpl :+ lda #$01 sta pages -: .endif +: ; Fall through @@ -175,10 +191,16 @@ INIT: ; Switch into graphics mode bit MIXCLR bit HIRES - .ifdef __APPLE2ENH__ + + .ifndef __APPLE2ENH__ + bit machinetype + bpl clr_txt + .endif + sta IOUDISON bit DHIRESOFF - .endif + +clr_txt: bit TXTCLR ; Beagle Bros Shape Mechanic fonts don't @@ -200,11 +222,14 @@ DONE: bit TXTSET bit LOWSCR - .ifdef __APPLE2ENH__ + .ifndef __APPLE2ENH__ + bit machinetype + bpl reset_wndtop + .endif ; Limit SET80COL-HISCR to text bit LORES - .endif +reset_wndtop: ; Reset the text window top lda #$00 sta WNDTOP diff --git a/libsrc/apple2/tgiref.s b/libsrc/apple2/tgiref.s new file mode 100644 index 000000000..e9bcab5e8 --- /dev/null +++ b/libsrc/apple2/tgiref.s @@ -0,0 +1,18 @@ +; +; Colin Leroy-Mira, 2025-05-10 +; + + .export tgi_libref + .import _exit + +.ifndef __APPLE2ENH__ + + .import machinetype + +tgi_libref := machinetype + +.else + +tgi_libref := _exit + +.endif diff --git a/libsrc/apple2/videomode.s b/libsrc/apple2/videomode.s index 414105b18..d8310427f 100644 --- a/libsrc/apple2/videomode.s +++ b/libsrc/apple2/videomode.s @@ -1,17 +1,40 @@ ; ; Oliver Schmidt, 07.09.2009 ; -; unsigned __fastcall__ videomode (unsigned mode); +; signed char __fastcall__ videomode (unsigned mode); ; - .ifdef __APPLE2ENH__ - .export _videomode + .ifndef __APPLE2ENH__ + .import machinetype + .endif + + .import returnFFFF + .include "apple2.inc" + .include "mli.inc" + + +VIDEOMODE_40x24 = $15 +VIDEOMODE_80x24 = $00 .segment "LOWCODE" _videomode: + ; Functionally equivalent to previous assumption that + ; __APPLE2ENH__ == 80 columns hardware present. Will be + ; correctly checked in the very near future. + .ifndef __APPLE2ENH__ + bit machinetype + bvs set_mode + + ; No 80 column card, return error if requested mode is 80cols + cmp #VIDEOMODE_40x24 + beq out + jmp returnFFFF +set_mode: + .endif + ; Get and save current videomode flag bit RD80VID php @@ -31,10 +54,8 @@ _videomode: ; Return ctrl-char code for setting previous ; videomode using the saved videomode flag - lda #$15 ; Ctrl-char code for 40 cols + lda #VIDEOMODE_40x24 plp - bpl :+ - lda #$00 ; Ctrl-char code for 80 cols -: rts ; X was preserved all the way - - .endif ; __APPLE2ENH__ + bpl out + lda #VIDEOMODE_80x24 +out: rts ; X was preserved all the way diff --git a/libsrc/apple2/wherex.s b/libsrc/apple2/wherex.s index 4d4f856f0..b447ac6e9 100644 --- a/libsrc/apple2/wherex.s +++ b/libsrc/apple2/wherex.s @@ -4,16 +4,23 @@ ; unsigned char wherex (void); ; + .ifndef __APPLE2ENH__ + .import machinetype + .endif + .export _wherex .include "apple2.inc" _wherex: lda CH - .ifdef __APPLE2ENH__ + .ifndef __APPLE2ENH__ + bit machinetype + bpl :+ + .endif bit RD80VID ; In 80 column mode? bpl :+ lda OURCH -: .endif - ldx #>$0000 + +: ldx #>$0000 rts diff --git a/targettest/conio.c b/targettest/conio.c index e270d3dab..09b4a9e44 100644 --- a/targettest/conio.c +++ b/targettest/conio.c @@ -9,6 +9,15 @@ * */ +/* Box drawing characters are usually constant expressions. However, there + * are scenarios where this is not the case. To ensure compatibility with + * code that assumes they are constant expressions, the scenarios in question + * must be explicitly enabled by defining DYN_BOX_DRAW. Currently, the only + * such scenario is the apple2 target. There, DYN_BOX_DRAW can be used to + * enable the use of MouseText characters on exactly those machines that + * support them. + */ +#define DYN_BOX_DRAW #include <conio.h> #include <string.h> @@ -34,6 +43,10 @@ #define CH_VLINE '!' #endif +#if defined(DYN_BOX_DRAW) +static char grid[5][5]; +#else + static char grid[5][5] = { {CH_ULCORNER, CH_HLINE, CH_TTEE, CH_HLINE, CH_URCORNER}, {CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE }, @@ -41,6 +54,35 @@ static char grid[5][5] = { {CH_VLINE, ' ', CH_VLINE, ' ', CH_VLINE }, {CH_LLCORNER, CH_HLINE, CH_BTEE, CH_HLINE, CH_LRCORNER} }; +#endif + +#if defined(DYN_BOX_DRAW) +static void init_grid(void) +{ + /* Programmatically fill the array with extern chars + * instead of constants. */ + grid[0][0] = CH_ULCORNER; + grid[2][0] = CH_LTEE; + grid[4][0] = CH_LLCORNER; + + grid[0][2] = CH_TTEE; + grid[2][2] = CH_CROSS; + grid[4][2] = CH_BTEE; + + grid[0][4] = CH_URCORNER; + grid[2][4] = CH_RTEE; + grid[4][4] = CH_LRCORNER; + + grid[1][1] = grid[1][3] = + grid[3][1] = grid[3][3] = ' '; + + grid[1][0] = grid[1][2] = grid[1][4] = + grid[3][0] = grid[3][2] = grid[3][4] = CH_VLINE; + grid[0][1] = grid[0][3] = + grid[2][1] = grid[2][3] = + grid[4][1] = grid[4][3] = CH_HLINE; +} +#endif #define LINE_COLORTEST 3 #define LINE_PEEKTEST 11 @@ -152,6 +194,11 @@ void main(void) joy_install(joy_static_stddrv); #endif + +#if defined(DYN_BOX_DRAW) + init_grid(); +#endif + clrscr(); screensize(&xsize, &ysize); cputs("cc65 conio test\n\r"); From e444f4c40e919a5ada2c52fdea8420a9d6dff74c Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Tue, 27 May 2025 22:42:07 +0200 Subject: [PATCH 442/707] Apple2: Safely check for 80-columns card Check the Pascal ID bytes for an 80-columns card to avoid blindly jumping into a $C300 that could be totally unrelated. --- libsrc/apple2/detect80cols.s | 56 ++++++++++++++++++++++++++++++++++++ libsrc/apple2/exec.s | 7 +++-- libsrc/apple2/videomode.s | 15 ++-------- 3 files changed, 63 insertions(+), 15 deletions(-) create mode 100644 libsrc/apple2/detect80cols.s diff --git a/libsrc/apple2/detect80cols.s b/libsrc/apple2/detect80cols.s new file mode 100644 index 000000000..19e6fda74 --- /dev/null +++ b/libsrc/apple2/detect80cols.s @@ -0,0 +1,56 @@ +; +; Colin Leroy-Mira, 27/05/2025 +; +; Verify the presence of a 80 columns card in slot 3, +; and publish a flag accordingly. +; + .export aux80col + + .ifndef __APPLE2ENH__ + .import machinetype + .endif + + .constructor detect80cols + + .include "apple2.inc" + + .data + +aux80col: .byte 0 + + .segment "ONCE" + +IdOfsTable: ; Table of bytes positions, used to check four + ; specific bytes on the slot's firmware to make + ; sure this is a serial card. + .byte $05 ; Pascal 1.0 ID byte + .byte $07 ; Pascal 1.0 ID byte + .byte $0B ; Pascal 1.1 generic signature byte + .byte $0C ; Device signature byte + +IdValTable: ; Table of expected values for the four checked + ; bytes + .byte $38 ; ID Byte 0 (from Pascal 1.0), fixed + .byte $18 ; ID Byte 1 (from Pascal 1.0), fixed + .byte $01 ; Generic signature for Pascal 1.1, fixed + .byte $88 ; Device signature byte (80 columns card) + +IdTableLen = * - IdValTable + +detect80cols: + .ifndef __APPLE2ENH__ + lda machinetype ; Check we're on a //e at least, otherwise we + bpl NoDev ; handle no 80cols hardware (like Videx) + .endif + + ldx #IdTableLen-1 +: ldy IdOfsTable,x ; Check Pascal 1.1 Firmware Protocol ID bytes + lda IdValTable,x + cmp $C300,y + bne NoDev + dex + bpl :- + + dec aux80col ; We have an 80-columns card! Set flag to $FF + +NoDev: rts diff --git a/libsrc/apple2/exec.s b/libsrc/apple2/exec.s index ec90f19bb..4e5e77a6e 100644 --- a/libsrc/apple2/exec.s +++ b/libsrc/apple2/exec.s @@ -6,6 +6,7 @@ .export _exec .import mli_file_info_direct + .import aux80col .import pushname, popname, popax, done, _exit .include "zeropage.inc" @@ -115,7 +116,8 @@ setbuf: lda #$00 ; Low byte sta io_buffer stx io_buffer+1 - .ifdef __APPLE2ENH__ + bit aux80col + bpl :+ ; Calling the 80 column firmware needs the ROM switched ; in, otherwise it copies the F8 ROM to the LC (@ $CEF4) bit $C082 @@ -128,9 +130,8 @@ setbuf: lda #$00 ; Low byte ; Switch in LC bank 2 for R/O bit $C080 - .endif - ; Reset stack as we already passed +: ; Reset stack as we already passed ; the point of no return anyway ldx #$FF txs diff --git a/libsrc/apple2/videomode.s b/libsrc/apple2/videomode.s index d8310427f..ea9eb28df 100644 --- a/libsrc/apple2/videomode.s +++ b/libsrc/apple2/videomode.s @@ -5,14 +5,10 @@ ; .export _videomode - .ifndef __APPLE2ENH__ - .import machinetype - .endif - + .import aux80col .import returnFFFF .include "apple2.inc" - .include "mli.inc" VIDEOMODE_40x24 = $15 @@ -21,19 +17,14 @@ VIDEOMODE_80x24 = $00 .segment "LOWCODE" _videomode: - ; Functionally equivalent to previous assumption that - ; __APPLE2ENH__ == 80 columns hardware present. Will be - ; correctly checked in the very near future. - .ifndef __APPLE2ENH__ - bit machinetype - bvs set_mode + bit aux80col + bmi set_mode ; No 80 column card, return error if requested mode is 80cols cmp #VIDEOMODE_40x24 beq out jmp returnFFFF set_mode: - .endif ; Get and save current videomode flag bit RD80VID From 842ec4b481513ea54f829132ec2fe842c1c6dbc5 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Thu, 29 May 2025 14:26:25 +0000 Subject: [PATCH 443/707] tmpfiles for the *.grc -> *.s -> *.o -> exe path --- src/cl65/main.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 8d8aac932..d68e7c7e7 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -378,6 +378,14 @@ static void CmdSetOutput (CmdDesc* Cmd, const char* File) +static void CmdSetAsmOutput (CmdDesc* Cmd, const char* File) +/* Set the output asm file in a command desc for grc65 */ +{ + CmdAddArg2 (Cmd, "-s", File); +} + + + static void CmdSetTarget (CmdDesc* Cmd, target_t Target) /* Set the output file in a command desc */ { @@ -703,6 +711,9 @@ static void Compile (const char* File) static void CompileRes (const char* File) /* Compile the given geos resource file */ { + /* tmp Asm file name, if needed */ + char* AsmName = NULL; + /* Remember the current assembler argument count */ unsigned ArgCount = GRC.ArgCount; @@ -711,6 +722,14 @@ static void CompileRes (const char* File) */ CmdSetTarget (&GRC, Target); + /* Changes to output file name must come + ** BEFORE adding the file + */ + if (DoAssemble && DoLink) { + AsmName = MakeTmpFilename(".s"); + CmdSetAsmOutput(&GRC, AsmName); + } + /* Add the file as argument for the resource compiler */ CmdAddArg (&GRC, File); @@ -728,7 +747,10 @@ static void CompileRes (const char* File) */ if (DoAssemble) { /* Assemble the intermediate file and remove it */ - AssembleIntermediate (File, NULL); + AssembleIntermediate (File, AsmName); + if (AsmName) { + xfree(AsmName); + } } } From 779c393e65fae1c5a64115f8e4673817cdcc5be7 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Thu, 29 May 2025 15:05:03 +0000 Subject: [PATCH 444/707] fixes *.s -> *.o -> exe path --- src/cl65/main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index d68e7c7e7..b48841149 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -552,7 +552,12 @@ static void AssembleFile (const char* File, const char* TmpFile, unsigned ArgCou ** to the file list of the linker. The name of the output ** file is that of the input file with ".s" replaced by ".o". */ - ObjName = MakeFilename (TmpFile ? TmpFile : File, ".o"); + if (TmpFile) { + ObjName = MakeFilename (TmpFile, ".o"); + } + else { + ObjName = MakeTmpFilename (".o"); + } CmdSetOutput (&CA65, ObjName); CmdAddFile (&LD65, ObjName); /* This is just a temporary file, schedule it for removal */ From f8c51ffd3d7de98e6a4ef6a710cf3cd2975806d2 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Mon, 26 May 2025 18:03:12 +0200 Subject: [PATCH 445/707] Spare a few bytes --- libsrc/apple2/extra/iobuf-0800.s | 13 ++++++------ libsrc/conio/cputs.s | 34 ++++++++++---------------------- 2 files changed, 17 insertions(+), 30 deletions(-) diff --git a/libsrc/apple2/extra/iobuf-0800.s b/libsrc/apple2/extra/iobuf-0800.s index 694b91fdb..b00dba6ae 100644 --- a/libsrc/apple2/extra/iobuf-0800.s +++ b/libsrc/apple2/extra/iobuf-0800.s @@ -54,18 +54,20 @@ iobuf_alloc: rts ; Mark table entry as used -: lda #$FF - sta table,x +: dec table,x ; Convert table index to address hibyte txa asl asl - clc + ; Skip clearing carry, it can't be set as long as MAX_FDS*4 is + ; less than 64. + .assert MAX_FDS*4 < $40, error adc #>$0800 ; Store address in "memptr" - ldy #$01 + ; (Y still equals 0 from popptr1) + iny sta (ptr1),y dey tya @@ -82,8 +84,7 @@ iobuf_free: ; Mark table entry as free tax - lda #$00 - sta table,x + inc table,x rts ; ------------------------------------------------------------------------ diff --git a/libsrc/conio/cputs.s b/libsrc/conio/cputs.s index 62e757b84..b822fddee 100644 --- a/libsrc/conio/cputs.s +++ b/libsrc/conio/cputs.s @@ -23,31 +23,17 @@ _cputsxy: _cputs: sta ptr1 ; Save s stx ptr1+1 +L0: .if (.cpu .bitand CPU_ISET_65SC02) - -L0: lda (ptr1) ; (5) - beq L9 ; (7) Jump if done - jsr _cputc ; (13) Output char, advance cursor - inc ptr1 ; (18) Bump low byte - bne L0 ; (20) Next char - inc ptr1+1 ; (25) Bump high byte - bne L0 - + lda (ptr1) ; (5) .else - -L0: ldy #0 ; (2) -L1: lda (ptr1),y ; (7) - beq L9 ; (9) Jump if done - iny - sty tmp1 ; (14) Save offset - jsr _cputc ; (20) Output char, advance cursor - ldy tmp1 ; (23) Get offset - bne L1 ; (25) Next char - inc ptr1+1 ; (30) Bump high byte - bne L1 - + ldy #0 ; (2) + lda (ptr1),y ; (7) .endif - -; Done - + beq L9 ; (7/9) Jump if done + jsr _cputc ; (13/15) Output char, advance cursor + inc ptr1 ; (18/20) Bump low byte + bne L0 ; (20/22) Next char + inc ptr1+1 ; (25/27) Bump high byte + bne L0 L9: rts From 89daccaa435b1d1bdb9e1860cdaa4671718502a8 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Wed, 21 May 2025 20:47:21 +0200 Subject: [PATCH 446/707] Apple2: automatically enable lowercase starting from //e --- libsrc/apple2/uppercasemask.s | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libsrc/apple2/uppercasemask.s b/libsrc/apple2/uppercasemask.s index 8b993bb1e..b0f05eee7 100644 --- a/libsrc/apple2/uppercasemask.s +++ b/libsrc/apple2/uppercasemask.s @@ -4,6 +4,25 @@ .export uppercasemask + .ifndef __APPLE2ENH__ + .import machinetype + .constructor detectlowercase + .endif + + .ifndef __APPLE2ENH__ + + .segment "ONCE" + +detectlowercase: + bit machinetype + bpl :+ + + lda #$FF + sta uppercasemask +: rts + + .endif + .data uppercasemask: .byte $DF ; Convert to uppercase From d03529067aaf3898d2e2f1ce42ca90e5f7f2f822 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Sat, 31 May 2025 13:27:52 +0200 Subject: [PATCH 447/707] Apple2: don't define _allow_lowercase and uppercasemask on APPLE2ENH --- libsrc/apple2/allow_lowercase.s | 7 ++++++- libsrc/apple2/uppercasemask.s | 9 ++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/libsrc/apple2/allow_lowercase.s b/libsrc/apple2/allow_lowercase.s index 648276b4c..b78544a66 100644 --- a/libsrc/apple2/allow_lowercase.s +++ b/libsrc/apple2/allow_lowercase.s @@ -4,8 +4,11 @@ ; unsigned char __fastcall__ allow_lowercase (unsigned char onoff); ; +.ifndef __APPLE2ENH__ + .export _allow_lowercase - .import uppercasemask, return0, return1 + .import return0 + .import uppercasemask, return1 _allow_lowercase: tax @@ -21,3 +24,5 @@ _allow_lowercase: values: .byte $DF ; Force uppercase .byte $FF ; Keep lowercase + +.endif diff --git a/libsrc/apple2/uppercasemask.s b/libsrc/apple2/uppercasemask.s index b0f05eee7..cd818c5bf 100644 --- a/libsrc/apple2/uppercasemask.s +++ b/libsrc/apple2/uppercasemask.s @@ -2,14 +2,12 @@ ; Oliver Schmidt, 2024-08-06 ; +.ifndef __APPLE2ENH__ + .export uppercasemask - .ifndef __APPLE2ENH__ .import machinetype .constructor detectlowercase - .endif - - .ifndef __APPLE2ENH__ .segment "ONCE" @@ -21,8 +19,9 @@ detectlowercase: sta uppercasemask : rts - .endif .data uppercasemask: .byte $DF ; Convert to uppercase + +.endif From c75c305c5919d49f2710d2a1d213244ccf153950 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Sat, 31 May 2025 13:22:01 +0200 Subject: [PATCH 448/707] Apple2: Fix inconsistency (use bit like everywhere else) --- libsrc/apple2/detect80cols.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/apple2/detect80cols.s b/libsrc/apple2/detect80cols.s index 19e6fda74..c6f263566 100644 --- a/libsrc/apple2/detect80cols.s +++ b/libsrc/apple2/detect80cols.s @@ -39,7 +39,7 @@ IdTableLen = * - IdValTable detect80cols: .ifndef __APPLE2ENH__ - lda machinetype ; Check we're on a //e at least, otherwise we + bit machinetype ; Check we're on a //e at least, otherwise we bpl NoDev ; handle no 80cols hardware (like Videx) .endif From df99b9a107b96eb2c43f934866b7c76680496950 Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Sat, 31 May 2025 19:00:11 +0200 Subject: [PATCH 449/707] fix codestyle --- src/cl65/main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index b48841149..42126e6d7 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -554,8 +554,7 @@ static void AssembleFile (const char* File, const char* TmpFile, unsigned ArgCou */ if (TmpFile) { ObjName = MakeFilename (TmpFile, ".o"); - } - else { + } else { ObjName = MakeTmpFilename (".o"); } CmdSetOutput (&CA65, ObjName); @@ -567,8 +566,7 @@ static void AssembleFile (const char* File, const char* TmpFile, unsigned ArgCou /* This is the final step. If an output name is given, set it */ if (OutputName) { CmdSetOutput (&CA65, OutputName); - } - else { + } else { ObjName = MakeFilename (File, ".o"); CmdSetOutput (&CA65, ObjName); xfree (ObjName); From d3ef3e1b62c90901b39bcb04f68d30584c329771 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Sun, 25 May 2025 16:22:24 +0200 Subject: [PATCH 450/707] Apple2: Don't depend on apple2enh definition for characters Up, Down and Del, as well as Open-Apple, exist on non-enhanced Apple //e. --- include/apple2.h | 20 ++++++++++++++++++++ include/apple2enh.h | 25 ------------------------- libsrc/apple2/cgetc.s | 10 +++++++--- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/include/apple2.h b/include/apple2.h index e4c8d89b1..430a3e1b1 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -83,6 +83,26 @@ #define CH_CURS_LEFT 0x08 #define CH_CURS_RIGHT 0x15 +/* These characters are not available on the ][+, but + * are on the //e. */ +#if defined(__APPLE2ENH__) || defined(APPLE2_INCLUDE_IIE_CHARS) +#define CH_DEL 0x7F +#define CH_CURS_UP 0x0B +#define CH_CURS_DOWN 0x0A + +/* These are defined to be OpenApple + NumberKey */ +#define CH_F1 0xB1 +#define CH_F2 0xB2 +#define CH_F3 0xB3 +#define CH_F4 0xB4 +#define CH_F5 0xB5 +#define CH_F6 0xB6 +#define CH_F7 0xB7 +#define CH_F8 0xB8 +#define CH_F9 0xB9 +#define CH_F10 0xB0 +#endif + #if defined(__APPLE2ENH__) /* MouseText-based functions for boxes and lines drawing */ diff --git a/include/apple2enh.h b/include/apple2enh.h index 1dc75ae13..8c463fccf 100644 --- a/include/apple2enh.h +++ b/include/apple2enh.h @@ -46,31 +46,6 @@ -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Characters codes */ -#define CH_DEL 0x7F -#define CH_CURS_UP 0x0B -#define CH_CURS_DOWN 0x0A - -/* These are defined to be OpenApple + NumberKey */ -#define CH_F1 0xB1 -#define CH_F2 0xB2 -#define CH_F3 0xB3 -#define CH_F4 0xB4 -#define CH_F5 0xB5 -#define CH_F6 0xB6 -#define CH_F7 0xB7 -#define CH_F8 0xB8 -#define CH_F9 0xB9 -#define CH_F10 0xB0 - - - /*****************************************************************************/ /* Variables */ /*****************************************************************************/ diff --git a/libsrc/apple2/cgetc.s b/libsrc/apple2/cgetc.s index b82238b02..f0b9566ff 100644 --- a/libsrc/apple2/cgetc.s +++ b/libsrc/apple2/cgetc.s @@ -51,10 +51,14 @@ put_caret: ; At this time, the high bit of the key pressed is set. : bit KBDSTRB ; Clear keyboard strobe - .ifdef __APPLE2ENH__ + + .ifndef __APPLE2ENH__ + bit machinetype ; Apple //e or more recent? + bpl clear + .endif bit BUTN0 ; Check if OpenApple is down bmi done - .endif - and #$7F ; If not down, then clear high bit + +clear: and #$7F ; If not down, then clear high bit done: ldx #>$0000 rts From a9ab23ad51a72db17be9d846b38f5b1a5852b8c7 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Tue, 27 May 2025 16:22:37 +0200 Subject: [PATCH 451/707] Make waitvsync available on apple2 --- doc/funcref.sgml | 12 ++++++++++-- libsrc/apple2/waitvsync.s | 23 +++++++++++++++++------ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 07d538781..a235eb2e0 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -104,6 +104,7 @@ function. <item><ref id="mktime_dt" name="mktime_dt"> <item>rebootafterexit <item><ref id="videomode" name="videomode"> +<item><ref id="waitvsync" name="waitvsync"> </itemize> @@ -119,6 +120,7 @@ function. <item><ref id="mktime_dt" name="mktime_dt"> <item>rebootafterexit <item><ref id="videomode" name="videomode"> +<item><ref id="waitvsync" name="waitvsync"> </itemize> @@ -8516,14 +8518,20 @@ if the mode is not supported due to lack of hardware. <descrip> <tag/Function/Wait until the start of the next video frame. <tag/Header/<tt/ -<ref id="apple2enh.h" name="apple2enh.h">, +<ref id="apple2.h" name="apple2.h">, <ref id="atmos.h" name="atmos.h">, <ref id="cbm.h" name="cbm.h">, <ref id="gamate.h" name="gamate.h">, <ref id="nes.h" name="nes.h">, <ref id="pce.h" name="pce.h">/ -<tag/Declaration/<tt/void waitvsync (void);/ +<tag/Declaration/ +<tt>void waitvsync (void);</tt><newline> +<tt>signed char waitvsync (void); /* For Apple II */</tt><newline> <tag/Description/Wait for vertical sync, to reduce flickering. +<tag/Notes/<itemize> +<item>The function will return -1 when the feature is not supported, +like on the Apple ][+. +</itemize> <tag/Availability/Platforms served by the headers above (Atmos requires the VSync hack) <tag/Example/None. diff --git a/libsrc/apple2/waitvsync.s b/libsrc/apple2/waitvsync.s index 486b93a53..e03796ad9 100644 --- a/libsrc/apple2/waitvsync.s +++ b/libsrc/apple2/waitvsync.s @@ -3,11 +3,13 @@ ; ; void waitvsync (void); ; - .ifdef __APPLE2ENH__ - .export _waitvsync .import ostype + .ifndef __APPLE2ENH__ + .import machinetype + .endif + .include "apple2.inc" _waitvsync: @@ -15,18 +17,27 @@ _waitvsync: bmi iigs ; $8x bvs iic ; $4x + .ifndef __APPLE2ENH__ + bit machinetype ; IIe/enh? + bmi :+ + + lda #$FF ; ][+ Unsupported + tax + rts + .endif + : bit RDVBLBAR bpl :- ; Blanking : bit RDVBLBAR bmi :- ; Drawing - rts + bpl out ; Apple IIgs TechNote #40, VBL Signal iigs: bit RDVBLBAR bmi iigs ; Blanking : bit RDVBLBAR bpl :- ; Drawing - rts + bmi out ; Apple IIc TechNote #9, Detecting VBL iic: php @@ -42,6 +53,6 @@ iic: php bit DISVBL : sta IOUDISON ; IIc Tech Ref Man: The firmware normally leaves IOUDIS on. plp +out: lda #$00 + tax rts - - .endif ; __APPLE2ENH__ From 01223073992f51481b160e339af0edb09a1ac7bb Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Wed, 28 May 2025 08:40:51 +0200 Subject: [PATCH 452/707] Apple2: Dynamic IIe check on a2_lo_tgi --- doc/funcref.sgml | 5 ++--- include/apple2.h | 3 +++ include/apple2enh.h | 11 ----------- libsrc/apple2/tgi/a2.lo.s | 26 ++++++++++++++++++++++---- libsrc/apple2/waitvsync.s | 23 +++++++++-------------- 5 files changed, 36 insertions(+), 32 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index a235eb2e0..5eab5adcd 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -8526,11 +8526,10 @@ if the mode is not supported due to lack of hardware. <ref id="pce.h" name="pce.h">/ <tag/Declaration/ <tt>void waitvsync (void);</tt><newline> -<tt>signed char waitvsync (void); /* For Apple II */</tt><newline> <tag/Description/Wait for vertical sync, to reduce flickering. <tag/Notes/<itemize> -<item>The function will return -1 when the feature is not supported, -like on the Apple ][+. +<item>The function will silently fail when the feature is not +supported, like on the Apple ][+. </itemize> <tag/Availability/Platforms served by the headers above (Atmos requires the VSync hack) diff --git a/include/apple2.h b/include/apple2.h index 430a3e1b1..82f8dd3e4 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -343,6 +343,9 @@ signed char __fastcall__ videomode (unsigned mode); ** installed. Call with one of the VIDEOMODE_xx constants. */ +void waitvsync (void); +/* Wait for start of next frame */ + /* End of apple2.h */ diff --git a/include/apple2enh.h b/include/apple2enh.h index 8c463fccf..84e6f4ab3 100644 --- a/include/apple2enh.h +++ b/include/apple2enh.h @@ -63,16 +63,5 @@ extern void a2e_lo_tgi[]; -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -void waitvsync (void); -/* Wait for start of next frame */ - - - /* End of apple2enh.h */ #endif diff --git a/libsrc/apple2/tgi/a2.lo.s b/libsrc/apple2/tgi/a2.lo.s index 8b00c5d20..b0f608e86 100644 --- a/libsrc/apple2/tgi/a2.lo.s +++ b/libsrc/apple2/tgi/a2.lo.s @@ -53,7 +53,7 @@ Y2 := ptr4 .byte $74, $67, $69 ; "tgi" .byte TGI_API_VERSION ; TGI API version number - .addr $0000 ; Library reference +libref: .addr $0000 ; Library reference .word 40 ; X resolution .word 48 ; Y resolution .byte 16 ; Number of drawing colors @@ -93,6 +93,10 @@ Y2 := ptr4 ERROR: .res 1 ; Error code MIX: .res 1 ; 4 lines of text +.ifndef __APPLE2ENH__ +machinetype: .res 1 +.endif + ; ------------------------------------------------------------------------ .rodata @@ -126,11 +130,15 @@ INIT: bit $C082 ; Switch in ROM jsr SETGR bit MIXCLR - .ifdef __APPLE2ENH__ + + .ifndef __APPLE2ENH__ + bit machinetype + bpl lc_in + .endif + sta IOUDISON bit DHIRESOFF - .endif - bit $C080 ; Switch in LC bank 2 for R/O +lc_in: bit $C080 ; Switch in LC bank 2 for R/O ; Done, reset the error code lda #TGI_ERR_OK @@ -144,6 +152,16 @@ INIT: ; most of the time. ; Must set an error code: NO INSTALL: + .ifndef __APPLE2ENH__ + lda libref + ldx libref+1 + sta ptr1 + stx ptr1+1 + ldy #$0 + lda (ptr1),y + sta machinetype + bpl :+ + .endif ; Fall through ; UNINSTALL routine. Is called before the driver is removed from memory. May diff --git a/libsrc/apple2/waitvsync.s b/libsrc/apple2/waitvsync.s index e03796ad9..d02071915 100644 --- a/libsrc/apple2/waitvsync.s +++ b/libsrc/apple2/waitvsync.s @@ -13,31 +13,28 @@ .include "apple2.inc" _waitvsync: + .ifndef __APPLE2ENH__ + bit machinetype ; IIe/enh? + bpl out ; No, silently fail + .endif + bit ostype bmi iigs ; $8x bvs iic ; $4x - .ifndef __APPLE2ENH__ - bit machinetype ; IIe/enh? - bmi :+ - - lda #$FF ; ][+ Unsupported - tax - rts - .endif - + ; Apple IIe : bit RDVBLBAR bpl :- ; Blanking : bit RDVBLBAR bmi :- ; Drawing - bpl out + rts ; Apple IIgs TechNote #40, VBL Signal iigs: bit RDVBLBAR bmi iigs ; Blanking : bit RDVBLBAR bpl :- ; Drawing - bmi out + rts ; Apple IIc TechNote #9, Detecting VBL iic: php @@ -53,6 +50,4 @@ iic: php bit DISVBL : sta IOUDISON ; IIc Tech Ref Man: The firmware normally leaves IOUDIS on. plp -out: lda #$00 - tax - rts +out: rts From 81ca41b73633a87ed03467cbf83b803ada570c3c Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Sun, 1 Jun 2025 23:19:51 +0200 Subject: [PATCH 453/707] kill dangling spaces --- libsrc/plus4/tgi/ted-hi.s | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsrc/plus4/tgi/ted-hi.s b/libsrc/plus4/tgi/ted-hi.s index 5a804c304..61dd9c2c4 100644 --- a/libsrc/plus4/tgi/ted-hi.s +++ b/libsrc/plus4/tgi/ted-hi.s @@ -218,7 +218,7 @@ INIT: DONE: lda $FF12 ora #%00000100 ; Fetch from ROM sta $FF12 - + .if LBASE <> CHRBASE lda #>CHRBASE ; Reset character/color matrix address sta $FF14 @@ -366,7 +366,7 @@ SETPALETTE: sta LBASE+$02e8,y iny bne @L2 - + ; Get chroma values from the low nybble of the palette entries lda PALETTE+1 ; Foreground chroma @@ -455,7 +455,7 @@ GETPIXEL: beq @L1 iny -@L1: +@L1: tya ; Get color value into A ldx #$00 ; Clear high byte rts From d7c84d1434388eccf574cb4a385e4a8e5908d681 Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Sun, 1 Jun 2025 23:20:51 +0200 Subject: [PATCH 454/707] kill spaces --- libsrc/plus4/crt0.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index 890ff6c2c..d1eea9472 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -197,7 +197,7 @@ nohandler: ; 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 +; 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: From a1fe6b84654d51f1a54a408b28b6dbed2e752fca Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Sun, 1 Jun 2025 23:22:44 +0200 Subject: [PATCH 455/707] kill spaces --- samples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Makefile b/samples/Makefile index 03835f06b..abdaa4ee8 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -451,7 +451,7 @@ multdemo: multidemo.o ovrldemo: overlaydemo.o $(LD) $(LDFLAGS) -o $@ -C $(SYS)-overlay.cfg -m $@.map $^ $(SYS).lib -OVERLAYLIST := +OVERLAYLIST := ifneq ($(filter ovrldemo,$(EXELIST_$(SYS))),) OVERLAYLIST += $(foreach I,1 2 3,ovrldemo.$I) From 9318c781ae2a36f03172e542d7344bbee12ebd55 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Tue, 3 Jun 2025 20:54:55 +0000 Subject: [PATCH 456/707] fixes #2666, double charmap of char literals --- src/ca65/scanner.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 8b910e672..da9883e52 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -1550,7 +1550,6 @@ CharAgain: ** string later. */ ReadStringConst ('\''); - TgtTranslateStrBuf(&CurTok.SVal); if (SB_GetLen (&CurTok.SVal) == 1) { CurTok.IVal = SB_AtUnchecked (&CurTok.SVal, 0); CurTok.Tok = TOK_CHARCON; @@ -1562,7 +1561,6 @@ CharAgain: ** Hack: Pass 0 to ReadStringConst for special handling. */ ReadStringConst(0); - TgtTranslateStrBuf(&CurTok.SVal); if (SB_GetLen(&CurTok.SVal) != 1) { Error ("Illegal character constant"); goto CharAgain; From 3d118dc6e55e9909ac47ab446f5f88630b47f53e Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Wed, 4 Jun 2025 02:06:40 +0000 Subject: [PATCH 457/707] rename "sp" to "spc", avoid conflict with 4510 opcodes --- asminc/zeropage.inc | 2 +- doc/atari.sgml | 2 +- doc/ca65.sgml | 6 +- doc/cc65-intern.sgml | 12 +- doc/customizing.sgml | 4 +- doc/sim65.sgml | 2 +- libsrc/apple2/callmain.s | 2 +- libsrc/apple2/crt0.s | 6 +- libsrc/apple2/exec.s | 4 +- libsrc/apple2/filename.s | 14 +-- libsrc/apple2/mli_file_info_direct.s | 4 +- libsrc/apple2/mou/a2.stdmou.s | 4 +- libsrc/apple2/open.s | 4 +- libsrc/apple2/syschdir.s | 4 +- libsrc/apple2/sysmkdir.s | 4 +- libsrc/apple2/sysremove.s | 4 +- libsrc/apple2/sysrename.s | 8 +- libsrc/atari/crt0.s | 8 +- libsrc/atari/diopncls.s | 8 +- libsrc/atari/fdtable.s | 4 +- libsrc/atari/mcbpm.s | 14 +-- libsrc/atari/mou/atrjoy.s | 4 +- libsrc/atari/mou/atrst.s | 4 +- libsrc/atari/mou/atrtt.s | 4 +- libsrc/atari/sysrename.s | 22 ++-- libsrc/atari/ucase_fn.s | 12 +- libsrc/atari2600/crt0.s | 4 +- libsrc/atari5200/crt0.s | 4 +- libsrc/atari7800/crt0.s | 4 +- libsrc/atari7800/mono_setcursor.s | 2 +- libsrc/atari7800/setcursor.s | 2 +- libsrc/atmos/crt0.s | 8 +- libsrc/c128/crt0.s | 8 +- libsrc/c128/mou/c128-1351.s | 4 +- libsrc/c128/mou/c128-inkwell.s | 4 +- libsrc/c128/mou/c128-joy.s | 4 +- libsrc/c128/mou/c128-pot.s | 4 +- libsrc/c16/crt0.s | 8 +- libsrc/c64/crt0.s | 8 +- libsrc/c64/mou/c64-1351.s | 4 +- libsrc/c64/mou/c64-inkwell.s | 4 +- libsrc/c64/mou/c64-joy.s | 4 +- libsrc/c64/mou/c64-pot.s | 4 +- libsrc/cbm/dir.s | 8 +- libsrc/cbm/open.s | 2 +- libsrc/cbm/write.s | 2 +- libsrc/cbm510/crt0.s | 12 +- libsrc/cbm510/mou/cbm510-inkwl.s | 4 +- libsrc/cbm510/mou/cbm510-joy.s | 4 +- libsrc/cbm610/crt0.s | 12 +- libsrc/common/_fopen.s | 10 +- libsrc/common/_heap.s | 6 +- libsrc/common/_idiv32by16r16.s | 8 +- libsrc/common/_printf.s | 14 +-- libsrc/common/_udiv32by16r16.s | 8 +- libsrc/common/fprintf.s | 8 +- libsrc/common/fread.s | 14 +-- libsrc/common/fscanf.s | 8 +- libsrc/common/interrupt.s | 4 +- libsrc/common/itoa.s | 10 +- libsrc/common/longjmp.s | 6 +- libsrc/common/lz4.s | 2 +- libsrc/common/memcpy.s | 6 +- libsrc/common/memset.s | 6 +- libsrc/common/printf.s | 6 +- libsrc/common/realloc.s | 2 +- libsrc/common/scanf.s | 6 +- libsrc/common/setjmp.s | 6 +- libsrc/common/snprintf.s | 8 +- libsrc/common/sprintf.s | 8 +- libsrc/common/sscanf.s | 8 +- libsrc/common/vfprintf.s | 10 +- libsrc/common/vfscanf.s | 8 +- libsrc/common/vprintf.s | 14 +-- libsrc/common/vscanf.s | 12 +- libsrc/common/vsnprintf.s | 14 +-- libsrc/common/vsscanf.s | 10 +- libsrc/conio/cprintf.s | 6 +- libsrc/conio/cscanf.s | 4 +- libsrc/conio/vcprintf.s | 10 +- libsrc/creativision/crt0.s | 4 +- libsrc/cx16/crt0.s | 4 +- libsrc/cx16/mou/cx16-std.s | 4 +- libsrc/dbg/dbgdump.s | 12 +- libsrc/dbg/dbgsupp.s | 8 +- libsrc/gamate/crt0.s | 4 +- libsrc/geos-common/drivers/geos-stdmou.s | 12 +- libsrc/geos-common/system/crt0.s | 6 +- libsrc/kim1/crt0.s | 4 +- libsrc/lynx/crt0.s | 4 +- libsrc/lynx/lseek.s | 2 +- libsrc/nes/crt0.s | 4 +- libsrc/none/crt0.s | 4 +- libsrc/osic1p/crt0.s | 4 +- libsrc/pce/_printf.s | 12 +- libsrc/pce/crt0.s | 6 +- libsrc/pce/memcpy.s | 6 +- libsrc/pet/crt0.s | 8 +- libsrc/plus4/crt0.s | 8 +- libsrc/rp6502/crt0.s | 4 +- libsrc/rp6502/ria.s | 2 +- libsrc/rp6502/xreg.s | 6 +- libsrc/runtime/add.s | 24 ++-- libsrc/runtime/addeqsp.s | 10 +- libsrc/runtime/addysp.s | 8 +- libsrc/runtime/and.s | 8 +- libsrc/runtime/bpushbsp.s | 4 +- libsrc/runtime/decsp1.s | 8 +- libsrc/runtime/decsp2.s | 8 +- libsrc/runtime/decsp3.s | 8 +- libsrc/runtime/decsp4.s | 8 +- libsrc/runtime/decsp5.s | 8 +- libsrc/runtime/decsp6.s | 8 +- libsrc/runtime/decsp7.s | 8 +- libsrc/runtime/decsp8.s | 8 +- libsrc/runtime/enter.s | 10 +- libsrc/runtime/eq.s | 2 +- libsrc/runtime/icmp.s | 14 +-- libsrc/runtime/incsp1.s | 6 +- libsrc/runtime/incsp2.s | 16 +-- libsrc/runtime/ladd.s | 12 +- libsrc/runtime/laddeqsp.s | 18 +-- libsrc/runtime/land.s | 12 +- libsrc/runtime/lcmp.s | 10 +- libsrc/runtime/ldau0sp.s | 6 +- libsrc/runtime/ldauisp.s | 6 +- libsrc/runtime/ldaxsp.s | 6 +- libsrc/runtime/ldeaxysp.s | 10 +- libsrc/runtime/leaaxsp.s | 6 +- libsrc/runtime/leave.s | 18 +-- libsrc/runtime/lmul.s | 12 +- libsrc/runtime/lor.s | 12 +- libsrc/runtime/lpop.s | 12 +- libsrc/runtime/lpush.s | 12 +- libsrc/runtime/lrsub.s | 12 +- libsrc/runtime/lsub.s | 12 +- libsrc/runtime/lsubeqsp.s | 18 +-- libsrc/runtime/ludiv.s | 12 +- libsrc/runtime/lxor.s | 12 +- libsrc/runtime/or.s | 8 +- libsrc/runtime/popa.s | 10 +- libsrc/runtime/popptr1.s | 8 +- libsrc/runtime/popsreg.s | 8 +- libsrc/runtime/pusha.s | 16 +-- libsrc/runtime/pushax.s | 14 +-- libsrc/runtime/pushbsp.s | 4 +- libsrc/runtime/pushlysp.s | 10 +- libsrc/runtime/pushwsp.s | 16 +-- libsrc/runtime/regswap.s | 6 +- libsrc/runtime/regswap1.s | 6 +- libsrc/runtime/regswap2.s | 10 +- libsrc/runtime/rsub.s | 8 +- libsrc/runtime/staspidx.s | 6 +- libsrc/runtime/staxsp.s | 8 +- libsrc/runtime/staxspi.s | 8 +- libsrc/runtime/steaxsp.s | 12 +- libsrc/runtime/stkchk.s | 14 +-- libsrc/runtime/sub.s | 8 +- libsrc/runtime/subeqsp.s | 10 +- libsrc/runtime/subysp.s | 8 +- libsrc/runtime/swap.s | 14 +-- libsrc/runtime/tosint.s | 12 +- libsrc/runtime/toslong.s | 26 ++-- libsrc/runtime/xor.s | 8 +- libsrc/runtime/zeropage.s | 2 +- libsrc/sim6502/crt0.s | 4 +- libsrc/sim6502/exehdr.s | 4 +- libsrc/supervision/crt0.s | 4 +- libsrc/sym1/crt0.s | 4 +- libsrc/telestrat/crt0.s | 8 +- libsrc/telestrat/open.s | 2 +- libsrc/telestrat/wherex.s | 2 +- libsrc/tgi/tgi_outtextxy.s | 10 +- libsrc/vic20/crt0.s | 8 +- libsrc/zlib/inflatemem.s | 10 +- samples/getsp.s | 6 +- samples/tinyshell.c | 12 +- src/cc65/codegen.c | 152 +++++++++++------------ src/cc65/codeinfo.c | 4 +- src/cc65/codeinfo.h | 4 +- src/cc65/codeopt.c | 2 +- src/cc65/codeoptutil.c | 22 ++-- src/cc65/coptadd.c | 60 ++++----- src/cc65/coptadd.h | 20 +-- src/cc65/coptbool.c | 12 +- src/cc65/coptcmp.c | 16 +-- src/cc65/coptcmp.h | 4 +- src/cc65/coptmisc.c | 22 ++-- src/cc65/coptptrload.c | 10 +- src/cc65/coptptrload.h | 8 +- src/cc65/coptptrstore.c | 12 +- src/cc65/coptptrstore.h | 10 +- src/cc65/coptstop.c | 6 +- src/cc65/coptstore.c | 2 +- src/cc65/locals.c | 2 +- src/cc65/stdfunc.c | 34 ++--- src/dbginfo/dbgsh.c | 2 +- src/sim65/main.c | 2 +- targettest/atari/mem.c | 2 +- targettest/ft.c | 12 +- targettest/getsp.s | 6 +- test/asm/opcodes/m740-opcodes.s | 2 +- test/val/bug1652-optimizer.c | 8 +- test/val/cq85.c | 2 +- 204 files changed, 908 insertions(+), 908 deletions(-) diff --git a/asminc/zeropage.inc b/asminc/zeropage.inc index 6627d86b6..75e498b39 100644 --- a/asminc/zeropage.inc +++ b/asminc/zeropage.inc @@ -8,7 +8,7 @@ ; by the compiler, ready for usage in asm code. - .globalzp sp, sreg, regsave + .globalzp spc, sreg, regsave .globalzp ptr1, ptr2, ptr3, ptr4 .globalzp tmp1, tmp2, tmp3, tmp4 .globalzp regbank diff --git a/doc/atari.sgml b/doc/atari.sgml index 060bc8ad4..96948f791 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -1121,7 +1121,7 @@ If BSS and/or the stack shouldn't stay at the end of the program, some parts of the cc65 runtime lib need to be replaced/modified. common/_heap.s defines the location of the heap and atari/crt0.s -defines the location of the stack by initializing sp. +defines the location of the stack by initializing spc. <sect1>Upgrading from an older cc65 version<p> diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 80224a84e..20684c283 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4788,17 +4788,17 @@ bit. Using <tscreen><verb> .if (.cpu .bitand CPU_ISET_65SC02) - lda (sp) + lda (spc) .else ldy #$00 - lda (sp),y + lda (spc),y .endif </verb></tscreen> it is possible to determine if the <tscreen><verb> - lda (sp) + lda (spc) </verb></tscreen> instruction is supported, which is the case for the 65SC02, 65C02 and 65816 diff --git a/doc/cc65-intern.sgml b/doc/cc65-intern.sgml index 904cee070..3f1c99008 100644 --- a/doc/cc65-intern.sgml +++ b/doc/cc65-intern.sgml @@ -131,7 +131,7 @@ All other parameters will be pushed to the C-stack from left to right. The rightmost parameter will have the lowest address on the stack, and multi-byte parameters will have their least significant byte at the lower address. -The <tt/sp/ pseudo-register is a zeropage pointer to the base of the C-stack. +The <tt/spc/ pseudo-register is a zeropage pointer to the base of the C-stack. If the function is variadic, the <tt/Y/ register will contain the number of bytes pushed to the stack for this function. @@ -153,10 +153,10 @@ void cdecl foo(unsigned bar, unsigned char baz); ; Example code for accessing bar. The variable is in A/X after this code snippet: ; ldy #2 ; Offset of high byte of bar - lda (sp),y ; High byte now in A + lda (spc),y ; High byte now in A tax ; High byte now in X dey ; Offset of low byte of bar - lda (sp),y ; Low byte now in A + lda (spc),y ; Low byte now in A </verb></tscreen> <sect1>Epilogue, after the function call<p> @@ -175,12 +175,12 @@ used if the return type is 32-bit. If the function has a void return type, the compiler will not depend on the result of <tt>A/X/sreg</tt>, so these may be clobbered by the function. -The C-stack pointer <tt/sp/ must be restored by the function to its value before the +The C-stack pointer <tt/spc/ must be restored by the function to its value before the function call prologue. It may pop all of its parameters from the C-stack (e.g. using the <tt/runtime/ function <tt/popa/), -or it could adjust <tt/sp/ directly. +or it could adjust <tt/spc/ directly. If the function is variadic, the <tt/Y/ register contains the number of bytes -pushed to the stack on entry, which may be added to <tt/sp/ to restore its +pushed to the stack on entry, which may be added to <tt/spc/ to restore its original state. The internal pseudo-register <tt/regbank/ must not be changed by the function. diff --git a/doc/customizing.sgml b/doc/customizing.sgml index 58631eb3c..04af5e7d5 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -193,9 +193,9 @@ _init: LDX #$FF ; Initialize stack pointer to $01FF ; Set cc65 argument stack pointer LDA #<(__RAM_START__ + __RAM_SIZE__) - STA sp + STA spc LDA #>(__RAM_START__ + __RAM_SIZE__) - STA sp+1 + STA spc+1 ; --------------------------------------------------------------------------- ; Initialize memory storage diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 9c3764e1d..831531533 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -209,7 +209,7 @@ Internally, the binary program file has a 12 byte header provided by the library <item>1 byte <bf/CPU type/: <tt/0/ = 6502, <tt/1/ = 65C02 -<item>1 byte <bf/sp address/: the zero page address of the C parameter stack pointer <tt/sp/ used by the paravirtualization functions +<item>1 byte <bf/spc address/: the zero page address of the C parameter stack pointer <tt/spc/ used by the paravirtualization functions <item>1 word <bf/load address/: where to load the data from the file into memory (default: <tt/$0200/) diff --git a/libsrc/apple2/callmain.s b/libsrc/apple2/callmain.s index 71a8b5611..687075318 100644 --- a/libsrc/apple2/callmain.s +++ b/libsrc/apple2/callmain.s @@ -54,7 +54,7 @@ exit: ldx #$02 ; Copy back the zero-page stuff. ldx #zpspace-1 : lda zpsave,x - sta sp,x + sta spc,x dex bpl :- diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index 628303687..31e868259 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -43,7 +43,7 @@ ; Save the zero-page locations that we need. init: ldx #zpspace-1 -: lda sp,x +: lda spc,x sta zpsave,x dex bpl :- @@ -81,8 +81,8 @@ basic: lda HIMEM ldx HIMEM+1 ; Set up the C stack. -: sta sp - stx sp+1 +: sta spc + stx spc+1 ; ProDOS TechRefMan, chapter 5.3.5: ; "Your system program should place in the RESET vector the diff --git a/libsrc/apple2/exec.s b/libsrc/apple2/exec.s index 4e5e77a6e..5d81f3b60 100644 --- a/libsrc/apple2/exec.s +++ b/libsrc/apple2/exec.s @@ -42,9 +42,9 @@ _exec: ; binary programs so we should do the same too in any case ; especially as _we_ rely on it in mainargs.s for argv[0] ldy #$00 - lda (sp),y + lda (spc),y tay -: lda (sp),y +: lda (spc),y sta $0280,y dey bpl :- diff --git a/libsrc/apple2/filename.s b/libsrc/apple2/filename.s index 0d4b6bedd..5a892172f 100644 --- a/libsrc/apple2/filename.s +++ b/libsrc/apple2/filename.s @@ -34,8 +34,8 @@ pushname: sta mliparam + MLI::ON_LINE::UNIT_NUM ; Use allocated pathname buffer - lda sp - ldx sp+1 + lda spc + ldx spc+1 sta mliparam + MLI::ON_LINE::DATA_BUFFER stx mliparam + MLI::ON_LINE::DATA_BUFFER+1 @@ -46,16 +46,16 @@ pushname: bcs addsp65 ; Get volume name length - lda (sp),y + lda (spc),y and #15 ; Max volume name length ; Bracket volume name with slashes to form prefix sta tmp1 lda #'/' - sta (sp),y + sta (spc),y ldy tmp1 iny ; Leading slash - sta (sp),y + sta (spc),y iny ; Trailing slash ; Adjust source pointer for copy @@ -69,7 +69,7 @@ pushname: ; Copy source to allocated pathname buffer copy: lda (ptr1),y - sta (sp),y + sta (spc),y beq setlen iny cpy #FILENAME_MAX @@ -86,7 +86,7 @@ addsp65:ldy #FILENAME_MAX setlen: tya jsr decsp1 ; Preserves A ldy #$00 - sta (sp),y + sta (spc),y ; Return success tya diff --git a/libsrc/apple2/mli_file_info_direct.s b/libsrc/apple2/mli_file_info_direct.s index c15ebc28f..510457f51 100644 --- a/libsrc/apple2/mli_file_info_direct.s +++ b/libsrc/apple2/mli_file_info_direct.s @@ -11,8 +11,8 @@ ; Returns with carry set on error, and sets errno mli_file_info_direct: ; Set pushed name - lda sp - ldx sp+1 + lda spc + ldx spc+1 sta mliparam + MLI::INFO::PATHNAME stx mliparam + MLI::INFO::PATHNAME+1 diff --git a/libsrc/apple2/mou/a2.stdmou.s b/libsrc/apple2/mou/a2.stdmou.s index 9c2f96200..40a894035 100644 --- a/libsrc/apple2/mou/a2.stdmou.s +++ b/libsrc/apple2/mou/a2.stdmou.s @@ -341,10 +341,10 @@ MOVE: ldy #$00 ; Start at top of stack ; Set x - lda (sp),y + lda (spc),y iny sta pos1_lo,x - lda (sp),y + lda (spc),y sta pos1_hi,x ; Update cursor diff --git a/libsrc/apple2/open.s b/libsrc/apple2/open.s index 7ece7f18d..29bc20bcc 100644 --- a/libsrc/apple2/open.s +++ b/libsrc/apple2/open.s @@ -101,8 +101,8 @@ found: tya bne oserr1 ; Set pushed name - lda sp - ldx sp+1 + lda spc + ldx spc+1 sta mliparam + MLI::OPEN::PATHNAME stx mliparam + MLI::OPEN::PATHNAME+1 diff --git a/libsrc/apple2/syschdir.s b/libsrc/apple2/syschdir.s index b3f81e2a5..d0fdb5551 100644 --- a/libsrc/apple2/syschdir.s +++ b/libsrc/apple2/syschdir.s @@ -17,8 +17,8 @@ __syschdir: bne oserr ; Set pushed name - lda sp - ldx sp+1 + lda spc + ldx spc+1 sta mliparam + MLI::PREFIX::PATHNAME stx mliparam + MLI::PREFIX::PATHNAME+1 diff --git a/libsrc/apple2/sysmkdir.s b/libsrc/apple2/sysmkdir.s index 7759da260..2e79d81ac 100644 --- a/libsrc/apple2/sysmkdir.s +++ b/libsrc/apple2/sysmkdir.s @@ -23,8 +23,8 @@ __sysmkdir: bne oserr ; Set pushed name - lda sp - ldx sp+1 + lda spc + ldx spc+1 sta mliparam + MLI::CREATE::PATHNAME stx mliparam + MLI::CREATE::PATHNAME+1 diff --git a/libsrc/apple2/sysremove.s b/libsrc/apple2/sysremove.s index 08c4dff68..864794e3d 100644 --- a/libsrc/apple2/sysremove.s +++ b/libsrc/apple2/sysremove.s @@ -16,8 +16,8 @@ __sysremove: bne oserr ; Set pushed name - lda sp - ldx sp+1 + lda spc + ldx spc+1 sta mliparam + MLI::DESTROY::PATHNAME stx mliparam + MLI::DESTROY::PATHNAME+1 diff --git a/libsrc/apple2/sysrename.s b/libsrc/apple2/sysrename.s index 0fe8dd7b1..e1ffb1454 100644 --- a/libsrc/apple2/sysrename.s +++ b/libsrc/apple2/sysrename.s @@ -22,8 +22,8 @@ __sysrename: bne oserr1 ; Save pushed oldname - lda sp - ldx sp+1 + lda spc + ldx spc+1 sta ptr3 stx ptr3+1 @@ -40,8 +40,8 @@ __sysrename: stx mliparam + MLI::RENAME::PATHNAME+1 ; Set pushed newname - lda sp - ldx sp+1 + lda spc + ldx spc+1 sta mliparam + MLI::RENAME::NEW_PATHNAME stx mliparam + MLI::RENAME::NEW_PATHNAME+1 diff --git a/libsrc/atari/crt0.s b/libsrc/atari/crt0.s index 50e3ca7b6..be49b142f 100644 --- a/libsrc/atari/crt0.s +++ b/libsrc/atari/crt0.s @@ -59,8 +59,8 @@ start: lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 + sta spc + stx spc+1 .else @@ -75,11 +75,11 @@ start: lda MEMTOP sbc #<__RESERVED_MEMORY__ sta APPMHI ; initialize our APPMHI value - sta sp ; set up runtime stack part 1 + sta spc ; set up runtime stack part 1 lda MEMTOP+1 sbc #>__RESERVED_MEMORY__ sta APPMHI+1 - sta sp+1 ; set up runtime stack part 2 + sta spc+1 ; set up runtime stack part 2 .endif diff --git a/libsrc/atari/diopncls.s b/libsrc/atari/diopncls.s index f40d6bba4..9e67829ef 100644 --- a/libsrc/atari/diopncls.s +++ b/libsrc/atari/diopncls.s @@ -16,7 +16,7 @@ .export sectsizetab .import ___oserror, __sio_call, _dio_read .import pushax, addysp, subysp - .importzp ptr2, sp + .importzp ptr2, spc .include "atari.inc" @@ -78,10 +78,10 @@ _dio_open: ldy #128 jsr subysp ; allocate buffer on the stack - lda sp + lda spc pha - lda sp+1 - pha ; save sp (buffer address) on processor stack + lda spc+1 + pha ; save spc (buffer address) on processor stack lda ptr2 ldx ptr2+1 diff --git a/libsrc/atari/fdtable.s b/libsrc/atari/fdtable.s index fd9f5021b..5556716dd 100644 --- a/libsrc/atari/fdtable.s +++ b/libsrc/atari/fdtable.s @@ -6,7 +6,7 @@ .include "atari.inc" .include "fd.inc" - .importzp tmp1,tmp2,tmp3,ptr4,sp + .importzp tmp1,tmp2,tmp3,ptr4,spc .import fd_table,fd_index .import fdt_to_fdi .export clriocb @@ -229,7 +229,7 @@ freefnd:txa beq l2 l1: ldy #0 - lda (sp),y ; get device + lda (spc),y ; get device l2: sta fd_table+ft_dev,x ; set device lda #1 sta fd_table+ft_usa,x ; set usage counter diff --git a/libsrc/atari/mcbpm.s b/libsrc/atari/mcbpm.s index 9e6ccc2c5..361af145e 100644 --- a/libsrc/atari/mcbpm.s +++ b/libsrc/atari/mcbpm.s @@ -8,7 +8,7 @@ ; .include "atari.inc" - .importzp sp + .importzp spc .export _mouse_pm_callbacks .constructor pm_init, 27 .destructor pm_down @@ -193,22 +193,22 @@ pm_init: .else -; use top of memory and lower sp accordingly - sta sp +; use top of memory and lower spc accordingly + sta spc sta MOUSE_PM_BASE - lda sp+1 + lda spc+1 and #7 ; offset within 2K cmp #3 + MOUSE_PM_RAW + 1 ; can we use it? bcc @decr ; no - lda sp+1 + lda spc+1 and #$F8 @set: adc #3 + MOUSE_PM_RAW - 1 ; CF is set, so adding MOUSE_PM_RAW + 3 sta MOUSE_PM_BASE+1 - sta sp+1 + sta spc+1 bne @cont ; jump always -@decr: lda sp+1 +@decr: lda spc+1 and #$F8 sbc #8 - 1 ; CF is clear, subtracts 8 bcs @set ; jump always diff --git a/libsrc/atari/mou/atrjoy.s b/libsrc/atari/mou/atrjoy.s index a93c7de13..425e1176a 100644 --- a/libsrc/atari/mou/atrjoy.s +++ b/libsrc/atari/mou/atrjoy.s @@ -241,11 +241,11 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (spc),y sta XPos+1 tax dey - lda (sp),y + lda (spc),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/atari/mou/atrst.s b/libsrc/atari/mou/atrst.s index 626b7a8f7..4a3b87f5c 100644 --- a/libsrc/atari/mou/atrst.s +++ b/libsrc/atari/mou/atrst.s @@ -399,12 +399,12 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (spc),y sta XPos+1 sta XPosWrk+1 tax dey - lda (sp),y + lda (spc),y sta XPos ; New X position sta XPosWrk jsr CMOVEX ; Move the cursor diff --git a/libsrc/atari/mou/atrtt.s b/libsrc/atari/mou/atrtt.s index f7c56e9f2..9870096fe 100644 --- a/libsrc/atari/mou/atrtt.s +++ b/libsrc/atari/mou/atrtt.s @@ -236,11 +236,11 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (spc),y sta XPos+1 tax dey - lda (sp),y + lda (spc),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/atari/sysrename.s b/libsrc/atari/sysrename.s index e526af5c8..f71ec5bb5 100644 --- a/libsrc/atari/sysrename.s +++ b/libsrc/atari/sysrename.s @@ -6,7 +6,7 @@ .include "atari.inc" .import findfreeiocb - .importzp tmp4, sp, ptr2, ptr3 + .importzp tmp4, spc, ptr2, ptr3 .import incsp2, subysp, addysp, popax .ifdef UCASE_FILENAME .importzp tmp3 @@ -118,19 +118,19 @@ L1: jsr subysp ; make room on the stack ; copy old name ldy #0 con: lda (ptr3),y - sta (sp),y + sta (spc),y beq copyend iny bne con copyend:lda #$20 ; space - sta (sp),y + sta (spc),y iny tya ; get current offset (beyond old name) clc - adc sp + adc spc sta ptr3 - lda sp+1 + lda spc+1 adc #0 sta ptr3+1 ; ptr3 now contains pointer to space for new filename @@ -143,9 +143,9 @@ cnn: lda (ptr2),y bne cnn copend2:ldx tmp4 - lda sp + lda spc sta ICBAL,x - lda sp+1 + lda spc+1 sta ICBAH,x lda #RENAME sta ICCOM,x @@ -160,13 +160,13 @@ copend2:ldx tmp4 ; clean up stack - lda sp + lda spc clc adc sspc - sta sp - lda sp+1 + sta spc + lda spc+1 adc sspc+1 - sta sp+1 + sta spc+1 ; handle status diff --git a/libsrc/atari/ucase_fn.s b/libsrc/atari/ucase_fn.s index f7f03915d..bec17e18e 100644 --- a/libsrc/atari/ucase_fn.s +++ b/libsrc/atari/ucase_fn.s @@ -24,7 +24,7 @@ .importzp tmp2 .import __defdev .endif - .importzp tmp3,ptr4,sp + .importzp tmp3,ptr4,spc .import subysp,addysp .export ucase_fn @@ -63,13 +63,13 @@ hasdev: ldy #0 loop2: lda (ptr4),y - sta (sp),y + sta (spc),y beq copy_end bmi L1 ; Not lowercase (also, invalid, should reject) cmp #'a' bcc L1 ; Not lowercase and #$DF ; make upper case char, assume ASCII chars - sta (sp),y ; store back + sta (spc),y ; store back L1: iny bpl loop2 ; bpl: this way we only support a max. length of 127 @@ -93,15 +93,15 @@ copy_end: jsr subysp ; adjust stack pointer dey cpdev: lda __defdev,y - sta (sp),y ; insert device name, number and ':' + sta (spc),y ; insert device name, number and ':' dey bpl cpdev hasdev2: .endif ; leave A and X pointing to the modified filename - lda sp - ldx sp+1 + lda spc + ldx spc+1 clc ; indicate success rts diff --git a/libsrc/atari2600/crt0.s b/libsrc/atari2600/crt0.s index 4f09a0a5a..b6ebd5db5 100644 --- a/libsrc/atari2600/crt0.s +++ b/libsrc/atari2600/crt0.s @@ -35,8 +35,8 @@ clearLoop: ; Initialize C stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) ldx #>(__RAM_START__ + __RAM_SIZE__) - sta sp - stx sp+1 + sta spc + stx spc+1 ; Call main jsr _main diff --git a/libsrc/atari5200/crt0.s b/libsrc/atari5200/crt0.s index 8f6e02273..6c28874ff 100644 --- a/libsrc/atari5200/crt0.s +++ b/libsrc/atari5200/crt0.s @@ -27,8 +27,8 @@ start: lda #<(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__) ldx #>(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__) - sta sp - stx sp+1 ; Set argument stack ptr + sta spc + stx spc+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/atari7800/crt0.s b/libsrc/atari7800/crt0.s index e791179f3..5a372eb0e 100644 --- a/libsrc/atari7800/crt0.s +++ b/libsrc/atari7800/crt0.s @@ -30,9 +30,9 @@ start: ; Set up parameter stack lda #<(__RAM3_START__ + __RAM3_SIZE__) - sta sp + sta spc lda #>(__RAM3_START__ + __RAM3_SIZE__) - sta sp+1 + sta spc+1 jsr copydata jsr zerobss diff --git a/libsrc/atari7800/mono_setcursor.s b/libsrc/atari7800/mono_setcursor.s index 02e0308f6..2136a7440 100644 --- a/libsrc/atari7800/mono_setcursor.s +++ b/libsrc/atari7800/mono_setcursor.s @@ -27,7 +27,7 @@ .constructor mono_init_cursor .interruptor mono_blink_cursor - .importzp sp + .importzp spc .import _zonecounter .import _mono_zones .import cursor diff --git a/libsrc/atari7800/setcursor.s b/libsrc/atari7800/setcursor.s index f438de24f..dabb8e984 100644 --- a/libsrc/atari7800/setcursor.s +++ b/libsrc/atari7800/setcursor.s @@ -27,7 +27,7 @@ .constructor init_cursor .interruptor blink_cursor - .importzp sp + .importzp spc .import _zonecounter .import _zones .import cursor diff --git a/libsrc/atmos/crt0.s b/libsrc/atmos/crt0.s index 8c2be656c..332002a3a 100644 --- a/libsrc/atmos/crt0.s +++ b/libsrc/atmos/crt0.s @@ -51,7 +51,7 @@ _exit: jsr donelib ldx #zpspace - 1 L2: lda zpsave,x - sta sp,x + sta spc,x dex bpl L2 @@ -68,7 +68,7 @@ L2: lda zpsave,x ; Save the zero-page area that we're about to use. init: ldx #zpspace - 1 -L1: lda sp,x +L1: lda spc,x sta zpsave,x dex bpl L1 @@ -85,8 +85,8 @@ L1: lda sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta spc + stx spc+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/c128/crt0.s b/libsrc/c128/crt0.s index ba6a78ac5..2517d991c 100644 --- a/libsrc/c128/crt0.s +++ b/libsrc/c128/crt0.s @@ -39,7 +39,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda sp,x +L1: lda spc,x sta zpsave,x dex bpl L1 @@ -58,8 +58,8 @@ L1: lda sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta spc + stx spc+1 ; Set argument stack ptr ; Call the module constructors. @@ -85,7 +85,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta spc,x dex bpl L2 diff --git a/libsrc/c128/mou/c128-1351.s b/libsrc/c128/mou/c128-1351.s index 76e28d9f7..a9237a6cb 100644 --- a/libsrc/c128/mou/c128-1351.s +++ b/libsrc/c128/mou/c128-1351.s @@ -296,11 +296,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (spc),y sta XPos+1 tax dey - lda (sp),y + lda (spc),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c128/mou/c128-inkwell.s b/libsrc/c128/mou/c128-inkwell.s index 2aac7d32d..b7cf54490 100644 --- a/libsrc/c128/mou/c128-inkwell.s +++ b/libsrc/c128/mou/c128-inkwell.s @@ -323,10 +323,10 @@ MOVE: sei ; No interrupts jsr MoveY ldy #$01 - lda (sp),y + lda (spc),y tax dey - lda (sp),y + lda (spc),y jsr MoveX ; Move the cursor cli ; Allow interrupts diff --git a/libsrc/c128/mou/c128-joy.s b/libsrc/c128/mou/c128-joy.s index d809db526..d1e45bc1e 100644 --- a/libsrc/c128/mou/c128-joy.s +++ b/libsrc/c128/mou/c128-joy.s @@ -297,11 +297,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (spc),y sta XPos+1 tax dey - lda (sp),y + lda (spc),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c128/mou/c128-pot.s b/libsrc/c128/mou/c128-pot.s index 1cbe4aa18..596ec6041 100644 --- a/libsrc/c128/mou/c128-pot.s +++ b/libsrc/c128/mou/c128-pot.s @@ -297,11 +297,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (spc),y sta XPos+1 tax dey - lda (sp),y + lda (spc),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c16/crt0.s b/libsrc/c16/crt0.s index 1df1e5c62..2dc73c7e5 100644 --- a/libsrc/c16/crt0.s +++ b/libsrc/c16/crt0.s @@ -24,7 +24,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda sp,x +L1: lda spc,x sta zpsave,x dex bpl L1 @@ -49,8 +49,8 @@ L1: lda sp,x bcc MemOk ldy #$80 ldx #$00 -MemOk: stx sp - sty sp+1 ; set argument stack ptr +MemOk: stx spc + sty spc+1 ; set argument stack ptr ; Call the module constructors. @@ -69,7 +69,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta spc,x dex bpl L2 diff --git a/libsrc/c64/crt0.s b/libsrc/c64/crt0.s index 4e5c7c9d4..e8aaaf8c6 100644 --- a/libsrc/c64/crt0.s +++ b/libsrc/c64/crt0.s @@ -55,7 +55,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta spc,x dex bpl L2 @@ -85,7 +85,7 @@ init: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda sp,x +L1: lda spc,x sta zpsave,x dex bpl L1 @@ -94,8 +94,8 @@ L1: lda sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta spc + stx spc+1 ; Set argument stack ptr ; Switch to the second charset. diff --git a/libsrc/c64/mou/c64-1351.s b/libsrc/c64/mou/c64-1351.s index ce0f18803..d49037479 100644 --- a/libsrc/c64/mou/c64-1351.s +++ b/libsrc/c64/mou/c64-1351.s @@ -239,11 +239,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (spc),y sta XPos+1 tax dey - lda (sp),y + lda (spc),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c64/mou/c64-inkwell.s b/libsrc/c64/mou/c64-inkwell.s index d2f14a6f0..4be817db3 100644 --- a/libsrc/c64/mou/c64-inkwell.s +++ b/libsrc/c64/mou/c64-inkwell.s @@ -249,10 +249,10 @@ MOVE: sei ; No interrupts jsr MoveY ldy #$01 - lda (sp),y + lda (spc),y tax dey - lda (sp),y + lda (spc),y jsr MoveX ; Move the cursor cli ; Allow interrupts diff --git a/libsrc/c64/mou/c64-joy.s b/libsrc/c64/mou/c64-joy.s index 5ee1b4f84..558b43c07 100644 --- a/libsrc/c64/mou/c64-joy.s +++ b/libsrc/c64/mou/c64-joy.s @@ -245,11 +245,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (spc),y sta XPos+1 tax dey - lda (sp),y + lda (spc),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c64/mou/c64-pot.s b/libsrc/c64/mou/c64-pot.s index 9bdf24f62..8147bb333 100644 --- a/libsrc/c64/mou/c64-pot.s +++ b/libsrc/c64/mou/c64-pot.s @@ -230,11 +230,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (spc),y sta XPos+1 tax dey - lda (sp),y + lda (spc),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/cbm/dir.s b/libsrc/cbm/dir.s index 734485aaf..c8057cf93 100644 --- a/libsrc/cbm/dir.s +++ b/libsrc/cbm/dir.s @@ -44,10 +44,10 @@ __dirread: ; Replace dir by dir->fd ldy #2 - lda (sp),y + lda (spc),y sta ptr1 iny - lda (sp),y + lda (spc),y sta ptr1+1 ldy #DIR::fd+1 lda (ptr1),y @@ -55,10 +55,10 @@ __dirread: dey lda (ptr1),y ldy #2 - sta (sp),y + sta (spc),y pla iny - sta (sp),y + sta (spc),y ; Get count, save it again, clear the high byte and call read(). By the ; previous actions, the stack frame is as read() needs it, and read() will diff --git a/libsrc/cbm/open.s b/libsrc/cbm/open.s index 47224925d..16c71e02e 100644 --- a/libsrc/cbm/open.s +++ b/libsrc/cbm/open.s @@ -12,7 +12,7 @@ .import opencmdchannel, closecmdchannel, readdiskerror .import fnunit, fnisfile .import _close - .importzp sp, tmp2, tmp3 + .importzp spc, tmp2, tmp3 .include "errno.inc" .include "fcntl.inc" diff --git a/libsrc/cbm/write.s b/libsrc/cbm/write.s index 172e45382..a699c691c 100644 --- a/libsrc/cbm/write.s +++ b/libsrc/cbm/write.s @@ -8,7 +8,7 @@ .constructor initstdout .import rwcommon - .importzp sp, ptr1, ptr2, ptr3 + .importzp spc, ptr1, ptr2, ptr3 .include "cbm.inc" .include "errno.inc" diff --git a/libsrc/cbm510/crt0.s b/libsrc/cbm510/crt0.s index 86137b1ca..0731673b3 100644 --- a/libsrc/cbm510/crt0.s +++ b/libsrc/cbm510/crt0.s @@ -117,7 +117,7 @@ entry: php tya sec sbc #7 - sta $1FF ; Save new sp + sta $1FF ; Save new spc tay tsx @@ -145,7 +145,7 @@ entry: php iny sta (sysp1),y - ldy $1FF ; Restore sp in bank 15 + ldy $1FF ; Restore spc in bank 15 lda #.hibyte(expull-1) sta (sysp1),y @@ -245,7 +245,7 @@ L1: lda extzp,x dex bpl L1 -; Save the old stack pointer from the system bank; and, set up our hw sp. +; Save the old stack pointer from the system bank; and, set up our hw spc. tsx txa @@ -279,9 +279,9 @@ L3: lda vectors,x ; Set up the C stack. lda #.lobyte(callbank15::entry) - sta sp + sta spc lda #.hibyte(callbank15::entry) - sta sp+1 + sta spc+1 ; Set up the subroutine and jump vector table that redirects Kernal calls to ; the system bank. @@ -495,7 +495,7 @@ _exit: pha ; Save the return code on stack ; Set up the welcome code at the stack bottom in the system bank. ldy #$FF - lda (sysp1),y ; Load system bank sp + lda (sysp1),y ; Load system bank spc tax iny ; Y = 0 lda #$58 ; CLI opcode diff --git a/libsrc/cbm510/mou/cbm510-inkwl.s b/libsrc/cbm510/mou/cbm510-inkwl.s index ea6d95934..e6e239fbd 100644 --- a/libsrc/cbm510/mou/cbm510-inkwl.s +++ b/libsrc/cbm510/mou/cbm510-inkwl.s @@ -256,10 +256,10 @@ MOVE: sei ; No interrupts jsr MoveY ldy #$01 - lda (sp),y + lda (spc),y tax dey - lda (sp),y + lda (spc),y jsr MoveX ; Move the cursor cli ; Allow interrupts diff --git a/libsrc/cbm510/mou/cbm510-joy.s b/libsrc/cbm510/mou/cbm510-joy.s index 4daa49272..f974c112f 100644 --- a/libsrc/cbm510/mou/cbm510-joy.s +++ b/libsrc/cbm510/mou/cbm510-joy.s @@ -225,11 +225,11 @@ MOVE: sei ; No interrupts jsr MoveY ; Set new y position ldy #1 - lda (sp),y + lda (spc),y sta XPos+1 tax dey - lda (sp),y + lda (spc),y jsr MoveX ; Move the pointer cli ; Allow interrupts diff --git a/libsrc/cbm610/crt0.s b/libsrc/cbm610/crt0.s index 0ad343d7f..814dbbdac 100644 --- a/libsrc/cbm610/crt0.s +++ b/libsrc/cbm610/crt0.s @@ -115,7 +115,7 @@ entry: php tya sec sbc #7 - sta $1FF ; Save new sp + sta $1FF ; Save new spc tay tsx @@ -143,7 +143,7 @@ entry: php iny sta (sysp1),y - ldy $1FF ; Restore sp in bank 15 + ldy $1FF ; Restore spc in bank 15 lda #.hibyte(expull-1) sta (sysp1),y @@ -243,7 +243,7 @@ L1: lda extzp,x dex bpl L1 -; Save the old stack pointer from the system bank; and, set up our hw sp. +; Save the old stack pointer from the system bank; and, set up our hw spc. tsx txa @@ -277,9 +277,9 @@ L3: lda vectors,x ; Set up the C stack. lda #.lobyte(callbank15::entry) - sta sp + sta spc lda #.hibyte(callbank15::entry) - sta sp+1 + sta spc+1 ; Set up the subroutine and jump vector table that redirects Kernal calls to ; the system bank. @@ -400,7 +400,7 @@ _exit: pha ; Save the return code ; Set up the welcome code at the stack bottom in the system bank. ldy #$FF - lda (sysp1),y ; Load system bank sp + lda (sysp1),y ; Load system bank spc tax iny ; Y = 0 lda #$58 ; CLI opcode diff --git a/libsrc/common/_fopen.s b/libsrc/common/_fopen.s index 17a1ec19b..3959ff1a7 100644 --- a/libsrc/common/_fopen.s +++ b/libsrc/common/_fopen.s @@ -9,7 +9,7 @@ .import _open .import pushax, incsp4, return0 - .importzp sp, ptr1 + .importzp spc, ptr1 .include "errno.inc" @@ -28,10 +28,10 @@ ; Get a pointer to the mode string ldy #1 - lda (sp),y + lda (spc),y sta ptr1+1 dey - lda (sp),y + lda (spc),y sta ptr1 ; Look at the first character in mode @@ -78,10 +78,10 @@ invmode: modeok: ldy #$00 txa ; Mode -> A - sta (sp),y + sta (spc),y tya iny - sta (sp),y + sta (spc),y ldy #4 ; Size of arguments in bytes jsr _open ; Will cleanup the stack diff --git a/libsrc/common/_heap.s b/libsrc/common/_heap.s index eb680fa20..aa609a7a1 100644 --- a/libsrc/common/_heap.s +++ b/libsrc/common/_heap.s @@ -6,7 +6,7 @@ .constructor initheap, 24 .import __BSS_RUN__, __BSS_SIZE__, __STACKSIZE__ - .importzp sp + .importzp spc .include "_heap.inc" @@ -31,10 +31,10 @@ ___heaplast: initheap: sec - lda sp + lda spc sbc #<__STACKSIZE__ sta ___heapend - lda sp+1 + lda spc+1 sbc #>__STACKSIZE__ sta ___heapend+1 rts diff --git a/libsrc/common/_idiv32by16r16.s b/libsrc/common/_idiv32by16r16.s index 7df78f4dd..6884bcf7e 100644 --- a/libsrc/common/_idiv32by16r16.s +++ b/libsrc/common/_idiv32by16r16.s @@ -20,17 +20,17 @@ ; Copy from stack to zeropage. This assumes ptr1 and ptr2 are adjacent. ldy #3 -@L1: lda (sp),y +@L1: lda (spc),y sta ptr1,y dey bpl @L1 lda #4 clc - adc sp - sta sp + adc spc + sta spc bcc @L2 - inc sp+1 + inc spc+1 @L2: pla ; Old rhs jmp idiv32by16r16 diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index d7eeb072d..3b445f5e7 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -338,25 +338,25 @@ MainLoop: jsr decsp6 ; 3 args ldy #5 lda OutData+1 - sta (sp),y + sta (spc),y dey lda OutData - sta (sp),y + sta (spc),y dey lda FSave+1 - sta (sp),y + sta (spc),y dey lda FSave - sta (sp),y + sta (spc),y dey lda FCount+1 - sta (sp),y + sta (spc),y dey lda FCount .if (.cpu .bitand ::CPU_ISET_65SC02) - sta (sp) + sta (spc) .else - sta (sp),y + sta (spc),y .endif jsr CallOutFunc ; Call the output function diff --git a/libsrc/common/_udiv32by16r16.s b/libsrc/common/_udiv32by16r16.s index a1d5f4e66..452fcba50 100644 --- a/libsrc/common/_udiv32by16r16.s +++ b/libsrc/common/_udiv32by16r16.s @@ -21,17 +21,17 @@ ; Copy from stack to zeropage. This assumes ptr1 and ptr2 are adjacent. ldy #3 -@L1: lda (sp),y +@L1: lda (spc),y sta ptr1,y dey bpl @L1 lda #4 clc - adc sp - sta sp + adc spc + sta spc bcc @L2 - inc sp+1 + inc spc+1 @L2: jmp udiv32by16r16m diff --git a/libsrc/common/fprintf.s b/libsrc/common/fprintf.s index 1582e6521..21e30121e 100644 --- a/libsrc/common/fprintf.s +++ b/libsrc/common/fprintf.s @@ -6,7 +6,7 @@ .export _fprintf .import addysp, decsp4, _vfprintf - .importzp sp, ptr1 + .importzp spc, ptr1 .macpack generic @@ -38,9 +38,9 @@ _fprintf: ; Calculate a pointer to the Format argument lda ParamSize - add sp + add spc sta ptr1 - ldx sp+1 + ldx spc+1 bcc @L1 inx @L1: stx ptr1+1 @@ -49,7 +49,7 @@ _fprintf: ldy #4-1 @L2: lda (ptr1),y - sta (sp),y + sta (spc),y dey bpl @L2 diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index b39b9d748..81c401bf3 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -14,7 +14,7 @@ .import pushwysp .import tosumulax, tosudivax - .importzp ptr1, sp + .importzp ptr1, spc .include "errno.inc" .include "_file.inc" @@ -136,23 +136,23 @@ ; to read() by one, so read() starts to store data at buf+1. .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (spc) sta ptr1 add #1 - sta (sp) + sta (spc) ldy #1 .else ldy #0 - lda (sp),y + lda (spc),y sta ptr1 add #1 - sta (sp),y + sta (spc),y iny .endif - lda (sp),y + lda (spc),y sta ptr1+1 adc #0 - sta (sp),y ; ptr1 = buf++; + sta (spc),y ; ptr1 = buf++; ; Get the buffered character and place it as first character into the read ; buffer. diff --git a/libsrc/common/fscanf.s b/libsrc/common/fscanf.s index a3d1ec0a1..1af61c4cb 100644 --- a/libsrc/common/fscanf.s +++ b/libsrc/common/fscanf.s @@ -6,7 +6,7 @@ .export _fscanf .import addysp, decsp4, _vfscanf - .importzp sp, ptr1 + .importzp spc, ptr1 .macpack generic @@ -50,9 +50,9 @@ _fscanf: ; Calculate a pointer to the Format argument lda ParamSize - add sp + add spc sta ptr1 - ldx sp+1 + ldx spc+1 bcc @L1 inx @L1: stx ptr1+1 @@ -61,7 +61,7 @@ _fscanf: ldy #4-1 @L2: lda (ptr1),y - sta (sp),y + sta (spc),y dey bpl @L2 diff --git a/libsrc/common/interrupt.s b/libsrc/common/interrupt.s index 6bdbb5fe4..5a53a2dd8 100644 --- a/libsrc/common/interrupt.s +++ b/libsrc/common/interrupt.s @@ -93,8 +93,8 @@ zpsave: .res zpsavespace ; Set C level interrupt stack lda irqsp ldx irqsp+1 - sta sp - stx sp+1 + sta spc + stx spc+1 ; Call C level interrupt request handler jsr irqvec diff --git a/libsrc/common/itoa.s b/libsrc/common/itoa.s index 808f9bc33..02e2b8f9e 100644 --- a/libsrc/common/itoa.s +++ b/libsrc/common/itoa.s @@ -8,7 +8,7 @@ .export _itoa, _utoa .import addysp1 .import __hextab - .importzp sp, sreg, ptr2, ptr3, tmp1 + .importzp spc, sreg, ptr2, ptr3, tmp1 .rodata specval: @@ -21,18 +21,18 @@ specval: dopop: sta tmp1 ; will lose high byte ldy #0 - lda (sp),y + lda (spc),y sta ptr2 sta ptr3 iny - lda (sp),y + lda (spc),y sta ptr2+1 sta ptr3+1 iny - lda (sp),y + lda (spc),y sta sreg iny - lda (sp),y + lda (spc),y sta sreg+1 jmp addysp1 ; Bump stack pointer diff --git a/libsrc/common/longjmp.s b/libsrc/common/longjmp.s index 91606a442..a4508569f 100644 --- a/libsrc/common/longjmp.s +++ b/libsrc/common/longjmp.s @@ -7,7 +7,7 @@ .export _longjmp .import popptr1 - .importzp sp, ptr1, ptr2 + .importzp spc, ptr1, ptr2 _longjmp: sta ptr2 ; Save retval @@ -23,10 +23,10 @@ _longjmp: lda (ptr1),y iny - sta sp + sta spc lda (ptr1),y iny - sta sp+1 + sta spc+1 ; Get the old stack pointer diff --git a/libsrc/common/lz4.s b/libsrc/common/lz4.s index c53841897..ebedcc1e3 100644 --- a/libsrc/common/lz4.s +++ b/libsrc/common/lz4.s @@ -61,7 +61,7 @@ ; } ; } - .importzp sp, sreg, regsave, regbank + .importzp spc, sreg, regsave, regbank .importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 .macpack longbranch .import memcpy_upwards,pushax,popax diff --git a/libsrc/common/memcpy.s b/libsrc/common/memcpy.s index fd090c788..0cbb7d4a5 100644 --- a/libsrc/common/memcpy.s +++ b/libsrc/common/memcpy.s @@ -12,7 +12,7 @@ .export _memcpy, memcpy_upwards, memcpy_getparams .import popax, popptr1 - .importzp sp, ptr1, ptr2, ptr3 + .importzp spc, ptr1, ptr2, ptr3 ; ---------------------------------------------------------------------- _memcpy: @@ -70,10 +70,10 @@ memcpy_getparams: ; IMPORTANT! Function has to leave with Y=0! iny ; Y=0 guaranteed by popptr1, we need '1' here... ; (direct stack access is three cycles faster ; (total cycle count with return)) - lda (sp),y + lda (spc),y tax stx ptr2+1 ; save high byte of ptr2 dey ; Y = 0 - lda (sp),y ; Get ptr2 low + lda (spc),y ; Get ptr2 low sta ptr2 rts diff --git a/libsrc/common/memset.s b/libsrc/common/memset.s index be78fc30d..6241d7800 100644 --- a/libsrc/common/memset.s +++ b/libsrc/common/memset.s @@ -17,7 +17,7 @@ .export _memset, _bzero, ___bzero .import popax - .importzp sp, ptr1, ptr2, ptr3 + .importzp spc, ptr1, ptr2, ptr3 _bzero: ___bzero: @@ -36,10 +36,10 @@ _memset: common: ; Fill value is in X! ldy #1 - lda (sp),y + lda (spc),y sta ptr1+1 ; save high byte of ptr dey ; Y = 0 - lda (sp),y ; Get ptr + lda (spc),y ; Get ptr sta ptr1 lsr ptr3+1 ; divide number of diff --git a/libsrc/common/printf.s b/libsrc/common/printf.s index 8d645dfa2..1ad909eff 100644 --- a/libsrc/common/printf.s +++ b/libsrc/common/printf.s @@ -6,7 +6,7 @@ .export _printf .import _stdout, pushax, addysp, _vfprintf - .importzp sp, ptr1 + .importzp spc, ptr1 .macpack generic @@ -43,8 +43,8 @@ _printf: ; Now calculate the va_list pointer, which does points to Format - lda sp - ldx sp+1 + lda spc + ldx spc+1 add ParamSize bcc @L1 inx diff --git a/libsrc/common/realloc.s b/libsrc/common/realloc.s index 176871dd5..eca1d3d0e 100644 --- a/libsrc/common/realloc.s +++ b/libsrc/common/realloc.s @@ -4,7 +4,7 @@ ; void* __fastcall__ realloc (void* block, register size_t size) ; - .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4, sp + .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4, spc .import _malloc, _memcpy, _free .import pushax, popptr1, return0 .import incsp2, decsp2 diff --git a/libsrc/common/scanf.s b/libsrc/common/scanf.s index dd6c16ad1..a5f3937a8 100644 --- a/libsrc/common/scanf.s +++ b/libsrc/common/scanf.s @@ -8,7 +8,7 @@ .export _scanf .import _stdin, pushax, addysp, _vfscanf - .import sp:zp, ptr1:zp + .import spc:zp, ptr1:zp .macpack generic @@ -34,8 +34,8 @@ _scanf: ; Now, calculate the va_list pointer, which does point to Format. - lda sp - ldx sp+1 + lda spc + ldx spc+1 add ArgSize bcc @L1 inx diff --git a/libsrc/common/setjmp.s b/libsrc/common/setjmp.s index 886853368..d32200c3d 100644 --- a/libsrc/common/setjmp.s +++ b/libsrc/common/setjmp.s @@ -8,7 +8,7 @@ .export ___setjmp .import return0 - .importzp sp, ptr1 + .importzp spc, ptr1 ___setjmp: sta ptr1 ; Save buf @@ -17,10 +17,10 @@ ___setjmp: ; The parameter stack is now empty, put it into buf - lda sp + lda spc sta (ptr1),y iny - lda sp+1 + lda spc+1 sta (ptr1),y iny diff --git a/libsrc/common/snprintf.s b/libsrc/common/snprintf.s index 33afb434d..f924453df 100644 --- a/libsrc/common/snprintf.s +++ b/libsrc/common/snprintf.s @@ -6,7 +6,7 @@ .export _snprintf .import pushax, addysp, decsp6, _vsnprintf - .importzp sp, ptr1 + .importzp spc, ptr1 .macpack generic @@ -38,9 +38,9 @@ _snprintf: ; Calculate a pointer to the Format argument lda ParamSize - add sp + add spc sta ptr1 - ldx sp+1 + ldx spc+1 bcc @L1 inx @L1: stx ptr1+1 @@ -49,7 +49,7 @@ _snprintf: ldy #6-1 @L2: lda (ptr1),y - sta (sp),y + sta (spc),y dey bpl @L2 diff --git a/libsrc/common/sprintf.s b/libsrc/common/sprintf.s index d502d8638..feec141e5 100644 --- a/libsrc/common/sprintf.s +++ b/libsrc/common/sprintf.s @@ -6,7 +6,7 @@ .export _sprintf .import pushax, addysp, decsp4, _vsprintf - .importzp sp, ptr1 + .importzp spc, ptr1 .macpack generic @@ -38,9 +38,9 @@ _sprintf: ; Calculate a pointer to the Format argument lda ParamSize - add sp + add spc sta ptr1 - ldx sp+1 + ldx spc+1 bcc @L1 inx @L1: stx ptr1+1 @@ -49,7 +49,7 @@ _sprintf: ldy #4-1 @L2: lda (ptr1),y - sta (sp),y + sta (spc),y dey bpl @L2 diff --git a/libsrc/common/sscanf.s b/libsrc/common/sscanf.s index 941f54e92..6542116ae 100644 --- a/libsrc/common/sscanf.s +++ b/libsrc/common/sscanf.s @@ -6,7 +6,7 @@ .export _sscanf .import addysp, decsp4, _vsscanf - .importzp sp, ptr1 + .importzp spc, ptr1 .macpack generic @@ -51,9 +51,9 @@ _sscanf: ; Calculate a pointer to the fixed parameters lda ParamSize - add sp + add spc sta ptr1 - ldx sp+1 + ldx spc+1 bcc @L1 inx @L1: stx ptr1+1 @@ -62,7 +62,7 @@ _sscanf: ldy #4-1 @L2: lda (ptr1),y - sta (sp),y + sta (spc),y dey bpl @L2 diff --git a/libsrc/common/vfprintf.s b/libsrc/common/vfprintf.s index 1225bcc47..4b941af9b 100644 --- a/libsrc/common/vfprintf.s +++ b/libsrc/common/vfprintf.s @@ -8,7 +8,7 @@ .export _vfprintf .import push1, pushwysp, incsp6 .import _fwrite, __printf - .importzp sp, ptr1 + .importzp spc, ptr1 .macpack generic @@ -121,15 +121,15 @@ _vfprintf: ; exactly as _printf expects it. Parameters will get dropped by _printf. ldy #2 - lda (sp),y ; Low byte of f + lda (spc),y ; Low byte of f sta ptr lda #<outdesc - sta (sp),y + sta (spc),y iny - lda (sp),y ; High byte of f + lda (spc),y ; High byte of f sta ptr+1 lda #>outdesc - sta (sp),y + sta (spc),y ; Restore low byte of ap and call _printf diff --git a/libsrc/common/vfscanf.s b/libsrc/common/vfscanf.s index c7d6e5564..2324f30a4 100644 --- a/libsrc/common/vfscanf.s +++ b/libsrc/common/vfscanf.s @@ -61,16 +61,16 @@ _vfscanf: ; Swap f against &d on the stack, placing f into d.data ldy #2 ; Offset of f on the stack - lda (sp),y + lda (spc),y sta d + SCANFDATA::DATA lda #<d - sta (sp),y + sta (spc),y iny ; High byte - lda (sp),y + lda (spc),y sta d + SCANFDATA::DATA + 1 lda #>d - sta (sp),y + sta (spc),y ; Restore the low byte of ap, and call the _scanf function diff --git a/libsrc/common/vprintf.s b/libsrc/common/vprintf.s index 0958b1038..fbfeb9951 100644 --- a/libsrc/common/vprintf.s +++ b/libsrc/common/vprintf.s @@ -7,7 +7,7 @@ .export _vprintf .import _vfprintf, _stdout .import decsp2 - .importzp sp + .importzp spc .proc _vprintf @@ -23,20 +23,20 @@ ; Move the format parameter down and store stdout in it's place ldy #2 - lda (sp),y + lda (spc),y ldy #0 - sta (sp),y + sta (spc),y ldy #3 - lda (sp),y + lda (spc),y ldy #1 - sta (sp),y + sta (spc),y iny lda _stdout - sta (sp),y + sta (spc),y iny lda _stdout+1 - sta (sp),y + sta (spc),y ; Restore A diff --git a/libsrc/common/vscanf.s b/libsrc/common/vscanf.s index 94afe527f..f6a34c34d 100644 --- a/libsrc/common/vscanf.s +++ b/libsrc/common/vscanf.s @@ -31,22 +31,22 @@ _vscanf: ; Move the format down ldy #2 - lda (sp),y ; Load byte of format + lda (spc),y ; Load byte of format ldy #0 - sta (sp),y + sta (spc),y ldy #3 - lda (sp),y + lda (spc),y ldy #1 - sta (sp),y + sta (spc),y ; Store stdin into the stack frame iny lda _stdin - sta (sp),y + sta (spc),y iny lda _stdin+1 - sta (sp),y + sta (spc),y ; Restore the low byte of ap and jump to vfscanf, which will cleanup the stack diff --git a/libsrc/common/vsnprintf.s b/libsrc/common/vsnprintf.s index 048a756c3..e1bd1e80d 100644 --- a/libsrc/common/vsnprintf.s +++ b/libsrc/common/vsnprintf.s @@ -8,7 +8,7 @@ .export _vsnprintf, vsnprintf .import ldaxysp, popax, incsp2, incsp6 .import _memcpy, __printf - .importzp sp, ptr1 + .importzp spc, ptr1 .include "errno.inc" @@ -55,19 +55,19 @@ vsnprintf: ; be formatted and counted. ldy #2 - lda (sp),y + lda (spc),y sta ptr1 lda #<outdesc - sta (sp),y + sta (spc),y iny - lda (sp),y + lda (spc),y bmi L9 ; More than $7FFF sta ptr1+1 lda #>outdesc - sta (sp),y + sta (spc),y ; Write size-1 to outdesc.uns. It will be -1 if there is no buffer. @@ -178,12 +178,12 @@ out: clc adc ccount+0 ldy #4 - sta (sp),y + sta (spc),y lda bufptr+1 adc ccount+1 iny - sta (sp),y + sta (spc),y ; Get Count from stack diff --git a/libsrc/common/vsscanf.s b/libsrc/common/vsscanf.s index 335712b20..9e261389c 100644 --- a/libsrc/common/vsscanf.s +++ b/libsrc/common/vsscanf.s @@ -9,7 +9,7 @@ .export _vsscanf .import popax, __scanf - .importzp sp, ptr1, ptr2 + .importzp spc, ptr1, ptr2 .macpack generic @@ -165,15 +165,15 @@ d: .addr get ; to d ldy #2 ; Stack offset of str - lda (sp),y + lda (spc),y sta sd + SSCANFDATA::STR lda #<d - sta (sp),y + sta (spc),y iny - lda (sp),y + lda (spc),y sta sd + SSCANFDATA::STR+1 lda #>d - sta (sp),y + sta (spc),y lda #$00 sta sd + SSCANFDATA::INDEX diff --git a/libsrc/conio/cprintf.s b/libsrc/conio/cprintf.s index 01bd0bbc6..64bdf9d3c 100644 --- a/libsrc/conio/cprintf.s +++ b/libsrc/conio/cprintf.s @@ -6,7 +6,7 @@ .export _cprintf .import pushax, addysp, _vcprintf - .importzp sp, ptr1 + .importzp spc, ptr1 .macpack generic @@ -31,9 +31,9 @@ _cprintf: dey dey ; Sub size of Format tya - add sp + add spc sta ptr1 - ldx sp+1 + ldx spc+1 bcc @L1 inx @L1: stx ptr1+1 diff --git a/libsrc/conio/cscanf.s b/libsrc/conio/cscanf.s index 7e54a844f..5d575185e 100644 --- a/libsrc/conio/cscanf.s +++ b/libsrc/conio/cscanf.s @@ -23,8 +23,8 @@ _cscanf: ; Now, calculate the va_list pointer -- which points to format. - ldx sp+1 - add sp + ldx spc+1 + add spc bcc @L1 inx @L1: sta ptr1 diff --git a/libsrc/conio/vcprintf.s b/libsrc/conio/vcprintf.s index 595a2d2c5..677a9f5fd 100644 --- a/libsrc/conio/vcprintf.s +++ b/libsrc/conio/vcprintf.s @@ -7,7 +7,7 @@ .export _vcprintf .import pushax, popax, popptr1 .import __printf, _cputc - .importzp sp, ptr1, ptr2, ptr3, tmp1 + .importzp spc, ptr1, ptr2, ptr3, tmp1 .macpack generic .macpack cpu @@ -138,10 +138,10 @@ _vcprintf: ; Get the format parameter and push it again ldy #1 - lda (sp),y + lda (spc),y tax dey - lda (sp),y + lda (spc),y jsr pushax ; Replace the passed format parameter on the stack by &d - this creates @@ -150,10 +150,10 @@ _vcprintf: ldy #2 ; Low byte of d lda #<outdesc - sta (sp),y + sta (spc),y iny lda #>outdesc - sta (sp),y + sta (spc),y ; Restore ap and call _printf diff --git a/libsrc/creativision/crt0.s b/libsrc/creativision/crt0.s index 5185ff237..dd6213b45 100644 --- a/libsrc/creativision/crt0.s +++ b/libsrc/creativision/crt0.s @@ -40,8 +40,8 @@ entry: ; Setup the argument stack ptr lda #<(__ZP_LAST__ + __STACKSIZE__) ldx #>(__ZP_LAST__ + __STACKSIZE__) - sta sp - stx sp+1 + sta spc + stx spc+1 ; Call module constructors jsr initlib diff --git a/libsrc/cx16/crt0.s b/libsrc/cx16/crt0.s index e37a64a7c..ab16a95d8 100644 --- a/libsrc/cx16/crt0.s +++ b/libsrc/cx16/crt0.s @@ -80,8 +80,8 @@ init: lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta spc + stx spc+1 ; Set argument stack ptr ; Switch to the lower/UPPER PetSCII charset. diff --git a/libsrc/cx16/mou/cx16-std.s b/libsrc/cx16/mou/cx16-std.s index f211815de..78b87e1aa 100644 --- a/libsrc/cx16/mou/cx16-std.s +++ b/libsrc/cx16/mou/cx16-std.s @@ -238,11 +238,11 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (spc),y sta XPos+1 tax dey - lda (sp),y + lda (spc),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/dbg/dbgdump.s b/libsrc/dbg/dbgdump.s index bc6a4bd40..a0ed097cc 100644 --- a/libsrc/dbg/dbgdump.s +++ b/libsrc/dbg/dbgdump.s @@ -7,23 +7,23 @@ .export _DbgMemDump .import addysp1 .import __hextab - .importzp sp, tmp2, tmp3, tmp4, ptr3, ptr4 + .importzp spc, tmp2, tmp3, tmp4, ptr3, ptr4 _DbgMemDump: ldy #0 - lda (sp),y ; Get length + lda (spc),y ; Get length sta tmp4 iny - lda (sp),y ; Get the string buffer + lda (spc),y ; Get the string buffer sta ptr3 iny - lda (sp),y + lda (spc),y sta ptr3+1 iny - lda (sp),y ; Get the address + lda (spc),y ; Get the address sta ptr4 iny - lda (sp),y + lda (spc),y sta ptr4+1 jsr addysp1 ; Drop the parameters diff --git a/libsrc/dbg/dbgsupp.s b/libsrc/dbg/dbgsupp.s index b1f122013..02e8a0d90 100644 --- a/libsrc/dbg/dbgsupp.s +++ b/libsrc/dbg/dbgsupp.s @@ -36,9 +36,9 @@ DbgBreak: jsr DbgSwapZP ; Swap stuff lda #<DbgStack ; Set new stack - sta sp + sta spc lda #>DbgStack - sta sp+1 + sta spc+1 jsr ResetDbgBreaks ; Reset temporary breakpoints jsr _DbgEntry ; Call C code jsr SetDbgBreaks ; Set temporary breakpoints @@ -61,7 +61,7 @@ DbgStack: ; Swap space for the C temporaries CTemp: -_DbgCS: .res 2 ; sp +_DbgCS: .res 2 ; spc _DbgHI: .res 2 ; sreg .res (zpsavespace-4) ; Other stuff @@ -78,7 +78,7 @@ Swap1: ldx CTemp,y lda <__ZP_START__,y sta CTemp,y txa - sta sp,y + sta spc,y dey bpl Swap1 rts diff --git a/libsrc/gamate/crt0.s b/libsrc/gamate/crt0.s index 5a5bb3aa0..be0281e8e 100644 --- a/libsrc/gamate/crt0.s +++ b/libsrc/gamate/crt0.s @@ -34,8 +34,8 @@ Start: ; Set up the stack lda #<(__RAM_START__+__RAM_SIZE__) ldx #>(__RAM_START__+__RAM_SIZE__) - sta sp - stx sp + 1 + sta spc + stx spc + 1 ; Call module constructors jsr initlib diff --git a/libsrc/geos-common/drivers/geos-stdmou.s b/libsrc/geos-common/drivers/geos-stdmou.s index 88bbc7df9..9b04d549a 100644 --- a/libsrc/geos-common/drivers/geos-stdmou.s +++ b/libsrc/geos-common/drivers/geos-stdmou.s @@ -13,7 +13,7 @@ .export _mouse_move, _mouse_buttons .import popsreg, addysp1 - .importzp sp, sreg, ptr1 + .importzp spc, sreg, ptr1 .include "const.inc" .include "jumptab.inc" @@ -87,22 +87,22 @@ _mouse_box: sta mouseBottom - lda (sp),y + lda (spc),y sta mouseRight iny - lda (sp),y + lda (spc),y sta mouseRight+1 ; maxx iny - lda (sp),y + lda (spc),y sta mouseTop iny ; Skip high byte iny - lda (sp),y + lda (spc),y sta mouseLeft iny - lda (sp),y + lda (spc),y sta mouseLeft+1 ; minx jmp addysp1 ; Drop params, return diff --git a/libsrc/geos-common/system/crt0.s b/libsrc/geos-common/system/crt0.s index 47cec74f2..47918a022 100644 --- a/libsrc/geos-common/system/crt0.s +++ b/libsrc/geos-common/system/crt0.s @@ -11,7 +11,7 @@ .import initlib, donelib .import callmain .import zerobss - .importzp sp + .importzp spc .include "jumptab.inc" .include "geossym.inc" @@ -48,8 +48,8 @@ lda #<(__STACKADDR__ + __STACKSIZE__) ldx #>(__STACKADDR__ + __STACKSIZE__) - sta sp - stx sp+1 + sta spc + stx spc+1 ; Call the module constructors. diff --git a/libsrc/kim1/crt0.s b/libsrc/kim1/crt0.s index 906b3b980..3bd6e3e76 100644 --- a/libsrc/kim1/crt0.s +++ b/libsrc/kim1/crt0.s @@ -26,9 +26,9 @@ _init: cld ; Clear decimal mode ; Set cc65 argument stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) - sta sp + sta spc lda #>(__RAM_START__ + __RAM_SIZE__) - sta sp+1 + sta spc+1 ; Initialize memory storage diff --git a/libsrc/lynx/crt0.s b/libsrc/lynx/crt0.s index 030f523e9..8187c1f05 100644 --- a/libsrc/lynx/crt0.s +++ b/libsrc/lynx/crt0.s @@ -80,8 +80,8 @@ MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$2 lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 + sta spc + stx spc+1 ; Init Mickey. diff --git a/libsrc/lynx/lseek.s b/libsrc/lynx/lseek.s index 04d816945..8b3184a04 100644 --- a/libsrc/lynx/lseek.s +++ b/libsrc/lynx/lseek.s @@ -11,7 +11,7 @@ ; ; off_t __fastcall__ lseek(int fd, off_t offset, int whence); - .importzp sp, sreg, regsave, regbank, tmp1, ptr1, ptr2 + .importzp spc, sreg, regsave, regbank, tmp1, ptr1, ptr2 .macpack longbranch .export _lseek .import addysp, stax0sp, tosand0ax, pusheax, asreax2 diff --git a/libsrc/nes/crt0.s b/libsrc/nes/crt0.s index 19e97bb12..edf9248af 100644 --- a/libsrc/nes/crt0.s +++ b/libsrc/nes/crt0.s @@ -107,8 +107,8 @@ start: lda #<(__SRAM_START__ + __SRAM_SIZE__) ldx #>(__SRAM_START__ + __SRAM_SIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta spc + stx spc+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/none/crt0.s b/libsrc/none/crt0.s index 596fbcd46..bc6fb65c5 100644 --- a/libsrc/none/crt0.s +++ b/libsrc/none/crt0.s @@ -10,8 +10,8 @@ lda #<__STACKSTART__ ldx #>__STACKSTART__ - sta sp - stx sp+1 + sta spc + stx spc+1 jsr zerobss jsr initlib jsr _main diff --git a/libsrc/osic1p/crt0.s b/libsrc/osic1p/crt0.s index 56abb7cdb..b85113902 100644 --- a/libsrc/osic1p/crt0.s +++ b/libsrc/osic1p/crt0.s @@ -34,8 +34,8 @@ _init: ldx #$FF ; Initialize stack pointer to $01FF lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 + sta spc + stx spc+1 ; --------------------------------------------------------------------------- ; Initialize memory storage diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s index e1d2a1cf4..8e2f7758f 100644 --- a/libsrc/pce/_printf.s +++ b/libsrc/pce/_printf.s @@ -329,22 +329,22 @@ MainLoop: jsr decsp6 ; 3 args ldy #5 lda OutData+1 - sta (sp),y + sta (spc),y dey lda OutData - sta (sp),y + sta (spc),y dey lda FSave+1 - sta (sp),y + sta (spc),y dey lda FSave - sta (sp),y + sta (spc),y dey lda FCount+1 - sta (sp),y + sta (spc),y dey lda FCount - sta (sp),y + sta (spc),y jsr CallOutFunc ; Call the output function ; We're back from out(), or we didn't call it. Check for end of string. diff --git a/libsrc/pce/crt0.s b/libsrc/pce/crt0.s index d6dee3ef4..2bd13253b 100644 --- a/libsrc/pce/crt0.s +++ b/libsrc/pce/crt0.s @@ -13,7 +13,7 @@ .import initlib, donelib .import push0, _main .import IRQStub, __nmi - .importzp sp + .importzp spc ; Linker-generated .import __CARTSIZE__ @@ -86,8 +86,8 @@ start: sei ; Set up the stack lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 + sta spc + stx spc+1 ; Call the module constructors. jsr initlib diff --git a/libsrc/pce/memcpy.s b/libsrc/pce/memcpy.s index 98db6a964..184250bcb 100644 --- a/libsrc/pce/memcpy.s +++ b/libsrc/pce/memcpy.s @@ -18,7 +18,7 @@ .export memcpy_increment, memcpy_transfer, memcpy_getparams .import incsp2, popax, popptr1 - .importzp sp, ptr1, ptr2, ptr3 + .importzp spc, ptr1, ptr2, ptr3 ; The structure of the transfer instructions @@ -86,9 +86,9 @@ memcpy_getparams: ; (Direct stack access is six cycles faster [total cycle count].) iny ; (Y=0 by popptr1, need '1' here) save dest - lda (sp),y ; get high byte + lda (spc),y ; get high byte tax - lda (sp) ; get low byte + lda (spc) ; get low byte sta ptr2 stx ptr2+1 rts ; return dest address (for memmove) diff --git a/libsrc/pet/crt0.s b/libsrc/pet/crt0.s index e56a7eca4..3732eba3c 100644 --- a/libsrc/pet/crt0.s +++ b/libsrc/pet/crt0.s @@ -23,7 +23,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda sp,x +L1: lda spc,x sta zpsave,x dex bpl L1 @@ -52,9 +52,9 @@ L1: lda sp,x stx spsave ; Save the system stack ptr lda MEMSIZE - sta sp + sta spc lda MEMSIZE+1 - sta sp+1 ; Set argument stack ptr + sta spc+1 ; Set argument stack ptr ; Call the module constructors. @@ -73,7 +73,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta spc,x dex bpl L2 diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index 6b44a2b7e..50f7740fa 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -34,7 +34,7 @@ Start: sei ; No interrupts since we're banking out the ROM sta ENABLE_RAM ldx #zpspace-1 -L1: lda sp,x +L1: lda spc,x sta zpsave,x dex bpl L1 @@ -54,8 +54,8 @@ L1: lda sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 + sta spc + stx spc+1 ; Set up the IRQ vector in the banked RAM; and, switch off the ROM. @@ -99,7 +99,7 @@ _exit: pha ; Save the return code ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta spc,x dex bpl L2 diff --git a/libsrc/rp6502/crt0.s b/libsrc/rp6502/crt0.s index 165ecf0a2..45c24eb9e 100644 --- a/libsrc/rp6502/crt0.s +++ b/libsrc/rp6502/crt0.s @@ -24,9 +24,9 @@ _init: ; Set cc65 argument stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) - sta sp + sta spc lda #>(__RAM_START__ + __RAM_SIZE__) - sta sp+1 + sta spc+1 ; Initialize memory storage jsr zerobss ; Clear BSS segment diff --git a/libsrc/rp6502/ria.s b/libsrc/rp6502/ria.s index a1b53efb1..e23177344 100644 --- a/libsrc/rp6502/ria.s +++ b/libsrc/rp6502/ria.s @@ -11,7 +11,7 @@ .export _ria_call_int, _ria_call_long .export _ria_call_int_errno, _ria_call_long_errno -.importzp sp, sreg +.importzp spc, sreg .import ___mappederrno, incsp1 .code diff --git a/libsrc/rp6502/xreg.s b/libsrc/rp6502/xreg.s index 40d4a6705..8d5fb9402 100644 --- a/libsrc/rp6502/xreg.s +++ b/libsrc/rp6502/xreg.s @@ -5,7 +5,7 @@ ; int __cdecl__ xreg(char device, char channel, unsigned char address, ...); .export _xreg -.importzp sp +.importzp spc .import addysp, _ria_call_int_errno .include "rp6502.inc" @@ -20,12 +20,12 @@ @copy: ; copy stack dey - lda (sp),y + lda (spc),y sta RIA_XSTACK tya bne @copy - ; recover variadic size and move sp + ; recover variadic size and move spc txa tay jsr addysp diff --git a/libsrc/runtime/add.s b/libsrc/runtime/add.s index a4658cc13..8d48b30a5 100644 --- a/libsrc/runtime/add.s +++ b/libsrc/runtime/add.s @@ -9,7 +9,7 @@ ; called a lot! .export tosadda0, tosaddax - .importzp sp, tmp1 + .importzp spc, tmp1 .macpack cpu @@ -20,34 +20,34 @@ tosaddax: .if (.cpu .bitand ::CPU_ISET_65SC02) - adc (sp) ; (7) + adc (spc) ; (7) tay ; (9) - inc sp ; (14) + inc spc ; (14) bne hiadd ; (17) - inc sp+1 ; (-1+5) + inc spc+1 ; (-1+5) hiadd: txa ; (19) - adc (sp) ; (24) + adc (spc) ; (24) tax ; (26) - inc sp ; (31) + inc spc ; (31) bne done ; (34) - inc sp+1 ; (-1+5) + inc spc+1 ; (-1+5) done: tya ; (36) .else ldy #0 ; (4) - adc (sp),y ; (9) lo byte + adc (spc),y ; (9) lo byte iny ; (11) sta tmp1 ; (14) save it txa ; (16) - adc (sp),y ; (21) hi byte + adc (spc),y ; (21) hi byte tax ; (23) clc ; (25) - lda sp ; (28) + lda spc ; (28) adc #2 ; (30) - sta sp ; (33) + sta spc ; (33) bcc L1 ; (36) - inc sp+1 ; (-1+5) + inc spc+1 ; (-1+5) L1: lda tmp1 ; (39) restore low byte .endif diff --git a/libsrc/runtime/addeqsp.s b/libsrc/runtime/addeqsp.s index 5112d2790..d042e0e8b 100644 --- a/libsrc/runtime/addeqsp.s +++ b/libsrc/runtime/addeqsp.s @@ -5,19 +5,19 @@ ; .export addeq0sp, addeqysp - .importzp sp + .importzp spc addeq0sp: ldy #0 addeqysp: clc - adc (sp),y - sta (sp),y + adc (spc),y + sta (spc),y pha iny txa - adc (sp),y - sta (sp),y + adc (spc),y + sta (spc),y tax pla rts diff --git a/libsrc/runtime/addysp.s b/libsrc/runtime/addysp.s index e0e7db1ce..246b0f4c9 100644 --- a/libsrc/runtime/addysp.s +++ b/libsrc/runtime/addysp.s @@ -5,17 +5,17 @@ ; .export addysp1, addysp - .importzp sp + .importzp spc addysp1: iny addysp: pha ; Save A clc tya ; Get the value - adc sp ; Add low byte - sta sp ; Put it back + adc spc ; Add low byte + sta spc ; Put it back bcc @L1 ; If no carry, we're done - inc sp+1 ; Inc high byte + inc spc+1 ; Inc high byte @L1: pla ; Restore A rts diff --git a/libsrc/runtime/and.s b/libsrc/runtime/and.s index 8c180b580..7ad593b5c 100644 --- a/libsrc/runtime/and.s +++ b/libsrc/runtime/and.s @@ -6,7 +6,7 @@ .export tosanda0, tosandax .import addysp1 - .importzp sp, ptr4 + .importzp spc, ptr4 .macpack cpu @@ -14,16 +14,16 @@ tosanda0: ldx #$00 tosandax: .if (.cpu .bitand CPU_ISET_65SC02) - and (sp) ; 65SC02 version, saves 2 cycles and 1 byte + and (spc) ; 65SC02 version, saves 2 cycles and 1 byte ldy #1 .else ldy #0 - and (sp),y + and (spc),y iny .endif pha txa - and (sp),y + and (spc),y tax pla jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/bpushbsp.s b/libsrc/runtime/bpushbsp.s index 1c6add4a9..6f94aa322 100644 --- a/libsrc/runtime/bpushbsp.s +++ b/libsrc/runtime/bpushbsp.s @@ -6,12 +6,12 @@ .export bpushbsp, bpushbysp .import pusha - .importzp sp + .importzp spc bpushbsp: ldy #0 bpushbysp: - lda (sp),y + lda (spc),y jmp pusha diff --git a/libsrc/runtime/decsp1.s b/libsrc/runtime/decsp1.s index 3c673664a..73b03f5db 100644 --- a/libsrc/runtime/decsp1.s +++ b/libsrc/runtime/decsp1.s @@ -5,14 +5,14 @@ ; .export decsp1 - .importzp sp + .importzp spc .proc decsp1 - ldy sp + ldy spc bne @L1 - dec sp+1 -@L1: dec sp + dec spc+1 +@L1: dec spc rts .endproc diff --git a/libsrc/runtime/decsp2.s b/libsrc/runtime/decsp2.s index a3793e778..8d4e38477 100644 --- a/libsrc/runtime/decsp2.s +++ b/libsrc/runtime/decsp2.s @@ -5,18 +5,18 @@ ; .export decsp2 - .importzp sp + .importzp spc .proc decsp2 - lda sp + lda spc sec sbc #2 - sta sp + sta spc bcc @L1 rts -@L1: dec sp+1 +@L1: dec spc+1 rts .endproc diff --git a/libsrc/runtime/decsp3.s b/libsrc/runtime/decsp3.s index a3ad7777e..cd4cb4798 100644 --- a/libsrc/runtime/decsp3.s +++ b/libsrc/runtime/decsp3.s @@ -5,18 +5,18 @@ ; .export decsp3 - .importzp sp + .importzp spc .proc decsp3 - lda sp + lda spc sec sbc #3 - sta sp + sta spc bcc @L1 rts -@L1: dec sp+1 +@L1: dec spc+1 rts .endproc diff --git a/libsrc/runtime/decsp4.s b/libsrc/runtime/decsp4.s index 5c7e94943..739bc43f1 100644 --- a/libsrc/runtime/decsp4.s +++ b/libsrc/runtime/decsp4.s @@ -5,18 +5,18 @@ ; .export decsp4 - .importzp sp + .importzp spc .proc decsp4 - lda sp + lda spc sec sbc #4 - sta sp + sta spc bcc @L1 rts -@L1: dec sp+1 +@L1: dec spc+1 rts .endproc diff --git a/libsrc/runtime/decsp5.s b/libsrc/runtime/decsp5.s index 7ff4605cf..6d63cd290 100644 --- a/libsrc/runtime/decsp5.s +++ b/libsrc/runtime/decsp5.s @@ -5,18 +5,18 @@ ; .export decsp5 - .importzp sp + .importzp spc .proc decsp5 - lda sp + lda spc sec sbc #5 - sta sp + sta spc bcc @L1 rts -@L1: dec sp+1 +@L1: dec spc+1 rts .endproc diff --git a/libsrc/runtime/decsp6.s b/libsrc/runtime/decsp6.s index 6e55e664d..06f1bee2f 100644 --- a/libsrc/runtime/decsp6.s +++ b/libsrc/runtime/decsp6.s @@ -5,18 +5,18 @@ ; .export decsp6 - .importzp sp + .importzp spc .proc decsp6 - lda sp + lda spc sec sbc #6 - sta sp + sta spc bcc @L1 rts -@L1: dec sp+1 +@L1: dec spc+1 rts .endproc diff --git a/libsrc/runtime/decsp7.s b/libsrc/runtime/decsp7.s index ee82232f6..341ce4dff 100644 --- a/libsrc/runtime/decsp7.s +++ b/libsrc/runtime/decsp7.s @@ -5,18 +5,18 @@ ; .export decsp7 - .importzp sp + .importzp spc .proc decsp7 - lda sp + lda spc sec sbc #7 - sta sp + sta spc bcc @L1 rts -@L1: dec sp+1 +@L1: dec spc+1 rts .endproc diff --git a/libsrc/runtime/decsp8.s b/libsrc/runtime/decsp8.s index 47d44593e..68bb08d17 100644 --- a/libsrc/runtime/decsp8.s +++ b/libsrc/runtime/decsp8.s @@ -5,18 +5,18 @@ ; .export decsp8 - .importzp sp + .importzp spc .proc decsp8 - lda sp + lda spc sec sbc #8 - sta sp + sta spc bcc @L1 rts -@L1: dec sp+1 +@L1: dec spc+1 rts .endproc diff --git a/libsrc/runtime/enter.s b/libsrc/runtime/enter.s index c51b4f7bb..b9091b0eb 100644 --- a/libsrc/runtime/enter.s +++ b/libsrc/runtime/enter.s @@ -5,14 +5,14 @@ ; .export enter - .importzp sp + .importzp spc enter: tya ; get arg size - ldy sp + ldy spc bne L1 - dec sp+1 -L1: dec sp + dec spc+1 +L1: dec spc ldy #0 - sta (sp),y ; Store the arg count + sta (spc),y ; Store the arg count rts diff --git a/libsrc/runtime/eq.s b/libsrc/runtime/eq.s index c2a537a35..073232e34 100644 --- a/libsrc/runtime/eq.s +++ b/libsrc/runtime/eq.s @@ -6,7 +6,7 @@ .export toseq00, toseqa0, toseqax .import tosicmp, booleq - .importzp sp, tmp1 + .importzp spc, tmp1 toseq00: lda #$00 diff --git a/libsrc/runtime/icmp.s b/libsrc/runtime/icmp.s index 05c73bd01..5c91d2c5a 100644 --- a/libsrc/runtime/icmp.s +++ b/libsrc/runtime/icmp.s @@ -6,7 +6,7 @@ ; .export tosicmp, tosicmp0 - .importzp sp, sreg + .importzp spc, sreg tosicmp0: @@ -17,16 +17,16 @@ tosicmp: stx sreg+1 ; Save ax ldy #$00 - lda (sp),y ; Get low byte + lda (spc),y ; Get low byte tax - inc sp ; 5 + inc spc ; 5 bne @L1 ; 3 - inc sp+1 ; (5) + inc spc+1 ; (5) @L1: - lda (sp),y ; Get high byte - inc sp ; 5 + lda (spc),y ; Get high byte + inc spc ; 5 bne @L2 ; 3 - inc sp+1 ; (5) + inc spc+1 ; (5) ; Do the compare. diff --git a/libsrc/runtime/incsp1.s b/libsrc/runtime/incsp1.s index 2272e200f..d19412a7d 100644 --- a/libsrc/runtime/incsp1.s +++ b/libsrc/runtime/incsp1.s @@ -5,13 +5,13 @@ ; .export incsp1 - .importzp sp + .importzp spc .proc incsp1 - inc sp + inc spc bne @L1 - inc sp+1 + inc spc+1 @L1: rts .endproc diff --git a/libsrc/runtime/incsp2.s b/libsrc/runtime/incsp2.s index 0ed0ffcdf..f7a0937e8 100644 --- a/libsrc/runtime/incsp2.s +++ b/libsrc/runtime/incsp2.s @@ -5,7 +5,7 @@ ; this module also contains the popax function. .export popax, incsp2 - .importzp sp + .importzp spc .macpack cpu @@ -14,13 +14,13 @@ .proc popax ldy #1 - lda (sp),y ; get hi byte + lda (spc),y ; get hi byte tax ; into x .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) ; get lo byte + lda (spc) ; get lo byte .else dey - lda (sp),y ; get lo byte + lda (spc),y ; get lo byte .endif .endproc @@ -29,14 +29,14 @@ .proc incsp2 - inc sp ; 5 + inc spc ; 5 beq @L1 ; 2 - inc sp ; 5 + inc spc ; 5 beq @L2 ; 2 rts -@L1: inc sp ; 5 -@L2: inc sp+1 ; 5 +@L1: inc spc ; 5 +@L2: inc spc+1 ; 5 rts .endproc diff --git a/libsrc/runtime/ladd.s b/libsrc/runtime/ladd.s index 23b3436c0..3e9b546d7 100644 --- a/libsrc/runtime/ladd.s +++ b/libsrc/runtime/ladd.s @@ -6,7 +6,7 @@ .export tosadd0ax, tosaddeax .import addysp1 - .importzp sp, sreg, tmp1 + .importzp spc, sreg, tmp1 .macpack cpu @@ -20,24 +20,24 @@ tosadd0ax: tosaddeax: clc .if (.cpu .bitand CPU_ISET_65SC02) - adc (sp) ; 65SC02 version - saves 2 cycles + adc (spc) ; 65SC02 version - saves 2 cycles ldy #1 .else ldy #0 - adc (sp),y ; lo byte + adc (spc),y ; lo byte iny .endif sta tmp1 ; use as temp storage txa - adc (sp),y ; byte 1 + adc (spc),y ; byte 1 tax iny lda sreg - adc (sp),y ; byte 2 + adc (spc),y ; byte 2 sta sreg iny lda sreg+1 - adc (sp),y ; byte 3 + adc (spc),y ; byte 3 sta sreg+1 lda tmp1 ; load byte 0 jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/laddeqsp.s b/libsrc/runtime/laddeqsp.s index 46c3c1f29..21c41e8d9 100644 --- a/libsrc/runtime/laddeqsp.s +++ b/libsrc/runtime/laddeqsp.s @@ -5,29 +5,29 @@ ; .export laddeq0sp, laddeqysp - .importzp sp, sreg + .importzp spc, sreg laddeq0sp: ldy #0 laddeqysp: clc - adc (sp),y - sta (sp),y + adc (spc),y + sta (spc),y pha iny txa - adc (sp),y - sta (sp),y + adc (spc),y + sta (spc),y tax iny lda sreg - adc (sp),y - sta (sp),y + adc (spc),y + sta (spc),y sta sreg iny lda sreg+1 - adc (sp),y - sta (sp),y + adc (spc),y + sta (spc),y sta sreg+1 pla rts diff --git a/libsrc/runtime/land.s b/libsrc/runtime/land.s index 8e21ebb60..c14de06f3 100644 --- a/libsrc/runtime/land.s +++ b/libsrc/runtime/land.s @@ -7,7 +7,7 @@ .export tosand0ax, tosandeax .import addysp1 - .importzp sp, sreg, tmp1 + .importzp spc, sreg, tmp1 .macpack cpu @@ -23,24 +23,24 @@ tosand0ax: tosandeax: .if (.cpu .bitand ::CPU_ISET_65SC02) - and (sp) ; byte 0 + and (spc) ; byte 0 ldy #1 .else ldy #0 - and (sp),y ; byte 0 + and (spc),y ; byte 0 iny .endif sta tmp1 txa - and (sp),y ; byte 1 + and (spc),y ; byte 1 tax iny lda sreg - and (sp),y ; byte 2 + and (spc),y ; byte 2 sta sreg iny lda sreg+1 - and (sp),y ; byte 3 + and (spc),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/lcmp.s b/libsrc/runtime/lcmp.s index d0ba4d81f..a8633578f 100644 --- a/libsrc/runtime/lcmp.s +++ b/libsrc/runtime/lcmp.s @@ -7,7 +7,7 @@ .export toslcmp .import incsp4 - .importzp sp, sreg, ptr1 + .importzp spc, sreg, ptr1 toslcmp: @@ -15,23 +15,23 @@ toslcmp: stx ptr1+1 ; EAX now in sreg:ptr1 ldy #$03 - lda (sp),y + lda (spc),y sec sbc sreg+1 bne L4 dey - lda (sp),y + lda (spc),y cmp sreg bne L1 dey - lda (sp),y + lda (spc),y cmp ptr1+1 bne L1 dey - lda (sp),y + lda (spc),y cmp ptr1 L1: php ; Save flags diff --git a/libsrc/runtime/ldau0sp.s b/libsrc/runtime/ldau0sp.s index a986d52da..88834a698 100644 --- a/libsrc/runtime/ldau0sp.s +++ b/libsrc/runtime/ldau0sp.s @@ -5,17 +5,17 @@ ; .export ldau00sp, ldau0ysp - .importzp sp, ptr1 + .importzp spc, ptr1 .macpack cpu ldau00sp: ldy #1 ldau0ysp: - lda (sp),y + lda (spc),y sta ptr1+1 dey - lda (sp),y + lda (spc),y sta ptr1 ldx #0 .if (.cpu .bitand CPU_ISET_65SC02) diff --git a/libsrc/runtime/ldauisp.s b/libsrc/runtime/ldauisp.s index 54f4d1bd1..0019a1f68 100644 --- a/libsrc/runtime/ldauisp.s +++ b/libsrc/runtime/ldauisp.s @@ -5,15 +5,15 @@ ; .export ldaui0sp, ldauiysp - .importzp sp, ptr1 + .importzp spc, ptr1 ldaui0sp: ldy #1 ldauiysp: - lda (sp),y + lda (spc),y sta ptr1+1 dey - lda (sp),y + lda (spc),y sta ptr1 txa tay diff --git a/libsrc/runtime/ldaxsp.s b/libsrc/runtime/ldaxsp.s index aa94b43cd..085c0cd36 100644 --- a/libsrc/runtime/ldaxsp.s +++ b/libsrc/runtime/ldaxsp.s @@ -5,16 +5,16 @@ ; .export ldax0sp, ldaxysp - .importzp sp + .importzp spc ; Beware: The optimizer knows about the value in Y after return! ldax0sp: ldy #1 ldaxysp: - lda (sp),y ; get high byte + lda (spc),y ; get high byte tax ; and save it dey ; point to lo byte - lda (sp),y ; load low byte + lda (spc),y ; load low byte rts diff --git a/libsrc/runtime/ldeaxysp.s b/libsrc/runtime/ldeaxysp.s index 1d65e9c38..566925265 100644 --- a/libsrc/runtime/ldeaxysp.s +++ b/libsrc/runtime/ldeaxysp.s @@ -9,20 +9,20 @@ .export ldeax0sp, ldeaxysp - .importzp sreg, sp + .importzp sreg, spc ldeax0sp: ldy #3 ldeaxysp: - lda (sp),y + lda (spc),y sta sreg+1 dey - lda (sp),y + lda (spc),y sta sreg dey - lda (sp),y + lda (spc),y tax dey - lda (sp),y + lda (spc),y rts diff --git a/libsrc/runtime/leaaxsp.s b/libsrc/runtime/leaaxsp.s index 0741170ca..09f2bfccc 100644 --- a/libsrc/runtime/leaaxsp.s +++ b/libsrc/runtime/leaaxsp.s @@ -5,16 +5,16 @@ ; .export leaaxsp, leaa0sp - .importzp sp + .importzp spc leaa0sp: ldx #$00 leaaxsp: clc - adc sp + adc spc pha txa - adc sp+1 + adc spc+1 tax pla rts diff --git a/libsrc/runtime/leave.s b/libsrc/runtime/leave.s index 95dcdec9d..0dfd79556 100644 --- a/libsrc/runtime/leave.s +++ b/libsrc/runtime/leave.s @@ -12,7 +12,7 @@ .export leave00, leave0, leavey00, leavey0, leavey .export leave .import addysp - .importzp sp + .importzp spc .macpack cpu @@ -31,24 +31,24 @@ leavey: .if (.cpu .bitand ::CPU_ISET_65SC02) leave: tay ; save A a sec - lda (sp) ; that's the pushed arg size + lda (spc) ; that's the pushed arg size sec ; Count the byte, the count's stored in - adc sp - sta sp + adc spc + sta spc bcc L1 - inc sp+1 + inc spc+1 L1: tya ; Get return value back .else leave: pha ; save A a sec ldy #0 - lda (sp),y ; that's the pushed arg size + lda (spc),y ; that's the pushed arg size sec ; Count the byte, the count's stored in - adc sp - sta sp + adc spc + sta spc bcc L1 - inc sp+1 + inc spc+1 L1: pla ; Get return value back .endif diff --git a/libsrc/runtime/lmul.s b/libsrc/runtime/lmul.s index 90d5f1e97..2c337e143 100644 --- a/libsrc/runtime/lmul.s +++ b/libsrc/runtime/lmul.s @@ -7,7 +7,7 @@ .export tosumul0ax, tosumuleax, tosmul0ax, tosmuleax .import addysp1 - .importzp sp, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 + .importzp spc, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 .macpack cpu @@ -27,21 +27,21 @@ tosumuleax: mul32: sta ptr1 stx ptr1+1 ; op2 now in ptr1/sreg .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (spc) ldy #1 .else ldy #0 - lda (sp),y + lda (spc),y iny .endif sta ptr3 - lda (sp),y + lda (spc),y sta ptr3+1 iny - lda (sp),y + lda (spc),y sta ptr4 iny - lda (sp),y + lda (spc),y sta ptr4+1 ; op1 in pre3/ptr4 jsr addysp1 ; Drop TOS diff --git a/libsrc/runtime/lor.s b/libsrc/runtime/lor.s index f2204b981..521f53e07 100644 --- a/libsrc/runtime/lor.s +++ b/libsrc/runtime/lor.s @@ -7,7 +7,7 @@ .export tosor0ax, tosoreax .import addysp1 - .importzp sp, sreg, tmp1 + .importzp spc, sreg, tmp1 .macpack cpu @@ -23,24 +23,24 @@ tosor0ax: tosoreax: .if (.cpu .bitand ::CPU_ISET_65SC02) - ora (sp) + ora (spc) ldy #1 .else ldy #0 - ora (sp),y ; byte 0 + ora (spc),y ; byte 0 iny .endif sta tmp1 txa - ora (sp),y ; byte 1 + ora (spc),y ; byte 1 tax iny lda sreg - ora (sp),y ; byte 2 + ora (spc),y ; byte 2 sta sreg iny lda sreg+1 - ora (sp),y ; byte 3 + ora (spc),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/lpop.s b/libsrc/runtime/lpop.s index a90ea5fcb..3c57e5b15 100644 --- a/libsrc/runtime/lpop.s +++ b/libsrc/runtime/lpop.s @@ -7,24 +7,24 @@ .export popeax .import incsp4 - .importzp sp, sreg + .importzp spc, sreg .macpack cpu popeax: ldy #3 - lda (sp),y + lda (spc),y sta sreg+1 dey - lda (sp),y + lda (spc),y sta sreg dey - lda (sp),y + lda (spc),y tax .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (spc) .else dey - lda (sp),y + lda (spc),y .endif jmp incsp4 diff --git a/libsrc/runtime/lpush.s b/libsrc/runtime/lpush.s index 0bc67b523..7a101af13 100644 --- a/libsrc/runtime/lpush.s +++ b/libsrc/runtime/lpush.s @@ -10,7 +10,7 @@ ; .export pushl0, push0ax, pusheax .import decsp4 - .importzp sp, sreg + .importzp spc, sreg .macpack cpu @@ -31,19 +31,19 @@ pusheax: jsr decsp4 ldy #3 lda sreg+1 - sta (sp),y + sta (spc),y dey lda sreg - sta (sp),y + sta (spc),y dey txa - sta (sp),y + sta (spc),y pla .if (.cpu .bitand ::CPU_ISET_65SC02) - sta (sp) + sta (spc) .else dey - sta (sp),y + sta (spc),y .endif rts diff --git a/libsrc/runtime/lrsub.s b/libsrc/runtime/lrsub.s index 5e8d0b543..bf7e3ee50 100644 --- a/libsrc/runtime/lrsub.s +++ b/libsrc/runtime/lrsub.s @@ -10,7 +10,7 @@ ; .export tosrsub0ax, tosrsubeax .import addysp1 - .importzp sp, sreg, tmp1 + .importzp spc, sreg, tmp1 .macpack cpu @@ -27,24 +27,24 @@ tosrsub0ax: tosrsubeax: sec .if (.cpu .bitand ::CPU_ISET_65SC02) - sbc (sp) + sbc (spc) ldy #1 .else ldy #0 - sbc (sp),y ; byte 0 + sbc (spc),y ; byte 0 iny .endif sta tmp1 ; use as temp storage txa - sbc (sp),y ; byte 1 + sbc (spc),y ; byte 1 tax iny lda sreg - sbc (sp),y ; byte 2 + sbc (spc),y ; byte 2 sta sreg iny lda sreg+1 - sbc (sp),y ; byte 3 + sbc (spc),y ; byte 3 sta sreg+1 lda tmp1 jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/lsub.s b/libsrc/runtime/lsub.s index 4c50ded14..559d0362f 100644 --- a/libsrc/runtime/lsub.s +++ b/libsrc/runtime/lsub.s @@ -9,7 +9,7 @@ ; .export tossub0ax, tossubeax .import addysp1 - .importzp sp, sreg + .importzp spc, sreg .macpack cpu @@ -27,24 +27,24 @@ tossubeax: sec eor #$FF .if (.cpu .bitand ::CPU_ISET_65SC02) - adc (sp) ; 65SC02 version - saves 2 cycles + adc (spc) ; 65SC02 version - saves 2 cycles ldy #1 .else ldy #0 - adc (sp),y ; lo byte + adc (spc),y ; lo byte iny .endif pha ; Save low byte txa eor #$FF - adc (sp),y ; byte 1 + adc (spc),y ; byte 1 tax iny - lda (sp),y + lda (spc),y sbc sreg ; byte 2 sta sreg iny - lda (sp),y + lda (spc),y sbc sreg+1 ; byte 3 sta sreg+1 pla ; Restore byte 0 diff --git a/libsrc/runtime/lsubeqsp.s b/libsrc/runtime/lsubeqsp.s index f32930c69..af2a38cc4 100644 --- a/libsrc/runtime/lsubeqsp.s +++ b/libsrc/runtime/lsubeqsp.s @@ -5,31 +5,31 @@ ; .export lsubeq0sp, lsubeqysp - .importzp sp, sreg + .importzp spc, sreg lsubeq0sp: ldy #0 lsubeqysp: sec eor #$FF - adc (sp),y - sta (sp),y + adc (spc),y + sta (spc),y pha ; Save low byte iny txa eor #$FF - adc (sp),y - sta (sp),y + adc (spc),y + sta (spc),y tax iny - lda (sp),y + lda (spc),y sbc sreg - sta (sp),y + sta (spc),y sta sreg iny - lda (sp),y + lda (spc),y sbc sreg+1 - sta (sp),y + sta (spc),y sta sreg+1 pla rts diff --git a/libsrc/runtime/ludiv.s b/libsrc/runtime/ludiv.s index 77335d8f5..695fac4f3 100644 --- a/libsrc/runtime/ludiv.s +++ b/libsrc/runtime/ludiv.s @@ -7,7 +7,7 @@ .export tosudiv0ax, tosudiveax, getlop, udiv32 .import addysp1 - .importzp sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 + .importzp spc, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 .macpack cpu @@ -39,21 +39,21 @@ getlop: sta ptr3 ; Put right operand in place sta ptr4+1 .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (spc) ldy #1 .else ldy #0 ; Put left operand in place - lda (sp),y + lda (spc),y iny .endif sta ptr1 - lda (sp),y + lda (spc),y sta ptr1+1 iny - lda (sp),y + lda (spc),y sta sreg iny - lda (sp),y + lda (spc),y sta sreg+1 jmp addysp1 ; Drop parameters diff --git a/libsrc/runtime/lxor.s b/libsrc/runtime/lxor.s index a92a59959..fa012118d 100644 --- a/libsrc/runtime/lxor.s +++ b/libsrc/runtime/lxor.s @@ -7,7 +7,7 @@ .export tosxor0ax, tosxoreax .import addysp1 - .importzp sp, sreg, tmp1 + .importzp spc, sreg, tmp1 .macpack cpu @@ -23,24 +23,24 @@ tosxor0ax: tosxoreax: .if (.cpu .bitand ::CPU_ISET_65SC02) - eor (sp) ; byte 0 + eor (spc) ; byte 0 ldy #1 .else ldy #0 - eor (sp),y ; byte 0 + eor (spc),y ; byte 0 iny .endif sta tmp1 txa - eor (sp),y ; byte 1 + eor (spc),y ; byte 1 tax iny lda sreg - eor (sp),y ; byte 2 + eor (spc),y ; byte 2 sta sreg iny lda sreg+1 - eor (sp),y ; byte 3 + eor (spc),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/or.s b/libsrc/runtime/or.s index 735f30f61..dc06c92ed 100644 --- a/libsrc/runtime/or.s +++ b/libsrc/runtime/or.s @@ -7,7 +7,7 @@ .export tosora0, tosorax .import addysp1 - .importzp sp, tmp1 + .importzp spc, tmp1 .macpack cpu @@ -15,16 +15,16 @@ tosora0: ldx #$00 tosorax: .if (.cpu .bitand ::CPU_ISET_65SC02) - ora (sp) + ora (spc) ldy #1 .else ldy #0 - ora (sp),y + ora (spc),y iny .endif sta tmp1 txa - ora (sp),y + ora (spc),y tax lda tmp1 jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/popa.s b/libsrc/runtime/popa.s index bb74df0ca..d24391293 100644 --- a/libsrc/runtime/popa.s +++ b/libsrc/runtime/popa.s @@ -5,23 +5,23 @@ ; .export popa - .importzp sp + .importzp spc .macpack cpu .proc popa .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (spc) .else ldy #0 ; (2) - lda (sp),y ; (7) Read byte + lda (spc),y ; (7) Read byte .endif - inc sp ; (12) + inc spc ; (12) beq @L1 ; (14) rts ; (20) -@L1: inc sp+1 +@L1: inc spc+1 rts .endproc diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index b54bb9eb3..5c52b5d34 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -6,19 +6,19 @@ .export popptr1 .import incsp2 - .importzp sp, ptr1 + .importzp spc, ptr1 .macpack cpu .proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) ldy #1 - lda (sp),y ; get hi byte + lda (spc),y ; get hi byte sta ptr1+1 ; into ptr hi dey ; dey even for for 65C02 here to have Y=0 at exit! .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) ; get lo byte + lda (spc) ; get lo byte .else - lda (sp),y ; get lo byte + lda (spc),y ; get lo byte .endif sta ptr1 ; to ptr lo jmp incsp2 diff --git a/libsrc/runtime/popsreg.s b/libsrc/runtime/popsreg.s index 47d67503a..2f2236813 100644 --- a/libsrc/runtime/popsreg.s +++ b/libsrc/runtime/popsreg.s @@ -6,20 +6,20 @@ .export popsreg .import incsp2 - .importzp sp, sreg + .importzp spc, sreg .macpack cpu popsreg: pha ; save A ldy #1 - lda (sp),y ; get hi byte + lda (spc),y ; get hi byte sta sreg+1 ; store it .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) ; get lo byte + lda (spc) ; get lo byte .else dey - lda (sp),y ; get lo byte + lda (spc),y ; get lo byte .endif sta sreg ; store it pla ; get A back diff --git a/libsrc/runtime/pusha.s b/libsrc/runtime/pusha.s index 04233282e..f7c65f35d 100644 --- a/libsrc/runtime/pusha.s +++ b/libsrc/runtime/pusha.s @@ -5,7 +5,7 @@ ; .export pusha0sp, pushaysp, pusha - .importzp sp + .importzp spc .macpack cpu @@ -14,16 +14,16 @@ pusha0sp: ldy #$00 pushaysp: - lda (sp),y -pusha: ldy sp ; (3) + lda (spc),y +pusha: ldy spc ; (3) beq @L1 ; (6) - dec sp ; (11) + dec spc ; (11) ldy #0 ; (13) - sta (sp),y ; (19) + sta (spc),y ; (19) rts ; (25) -@L1: dec sp+1 ; (11) - dec sp ; (16) - sta (sp),y ; (22) +@L1: dec spc+1 ; (11) + dec spc ; (16) + sta (spc),y ; (22) rts ; (28) diff --git a/libsrc/runtime/pushax.s b/libsrc/runtime/pushax.s index 27ddf641d..06e7d4942 100644 --- a/libsrc/runtime/pushax.s +++ b/libsrc/runtime/pushax.s @@ -5,7 +5,7 @@ ; .export push0, pusha0, pushax - .importzp sp + .importzp spc .macpack cpu @@ -20,21 +20,21 @@ pusha0: ldx #0 .proc pushax pha ; (3) - lda sp ; (6) + lda spc ; (6) sec ; (8) sbc #2 ; (10) - sta sp ; (13) + sta spc ; (13) bcs @L1 ; (17) - dec sp+1 ; (+5) + dec spc+1 ; (+5) @L1: ldy #1 ; (19) txa ; (21) - sta (sp),y ; (27) + sta (spc),y ; (27) pla ; (31) dey ; (33) .if (.cpu .bitand ::CPU_ISET_65SC02) - sta (sp) ; (37) + sta (spc) ; (37) .else - sta (sp),y ; (38) + sta (spc),y ; (38) .endif rts ; (44/43) diff --git a/libsrc/runtime/pushbsp.s b/libsrc/runtime/pushbsp.s index 0b5cbe854..abbaf7589 100644 --- a/libsrc/runtime/pushbsp.s +++ b/libsrc/runtime/pushbsp.s @@ -6,12 +6,12 @@ .export pushbsp, pushbysp .import pusha0 - .importzp sp + .importzp spc pushbsp: ldy #0 pushbysp: - lda (sp),y ; get lo byte + lda (spc),y ; get lo byte jmp pusha0 ; promote to unsigned and push diff --git a/libsrc/runtime/pushlysp.s b/libsrc/runtime/pushlysp.s index ca1834265..c64c90d7d 100644 --- a/libsrc/runtime/pushlysp.s +++ b/libsrc/runtime/pushlysp.s @@ -7,23 +7,23 @@ .export pushlysp .import pusheax - .importzp sreg, sp + .importzp sreg, spc .proc pushlysp iny iny - lda (sp),y + lda (spc),y iny sta sreg - lda (sp),y + lda (spc),y sta sreg+1 dey dey - lda (sp),y + lda (spc),y dey tax - lda (sp),y + lda (spc),y jmp pusheax .endproc diff --git a/libsrc/runtime/pushwsp.s b/libsrc/runtime/pushwsp.s index f5ebe0d7e..de005d08c 100644 --- a/libsrc/runtime/pushwsp.s +++ b/libsrc/runtime/pushwsp.s @@ -5,27 +5,27 @@ ; .export pushwysp, pushw0sp - .importzp sp + .importzp spc .macpack generic pushw0sp: ldy #3 pushwysp: - lda sp ; 3 + lda spc ; 3 sub #2 ; 4 - sta sp ; 3 + sta spc ; 3 bcs @L1 ; 3(+1) - dec sp+1 ; (5) -@L1: lda (sp),y ; 5 =16 + dec spc+1 ; (5) +@L1: lda (spc),y ; 5 =16 tax ; 2 dey ; 2 - lda (sp),y ; 5 + lda (spc),y ; 5 ldy #$00 ; 2 - sta (sp),y ; 5 + sta (spc),y ; 5 iny ; 2 txa ; 2 - sta (sp),y ; 5 + sta (spc),y ; 5 rts diff --git a/libsrc/runtime/regswap.s b/libsrc/runtime/regswap.s index 689d8d12a..0185b0503 100644 --- a/libsrc/runtime/regswap.s +++ b/libsrc/runtime/regswap.s @@ -5,17 +5,17 @@ ; .export regswap - .importzp sp, regbank, tmp1 + .importzp spc, regbank, tmp1 .proc regswap sta tmp1 ; Store count @L1: lda regbank,x ; Get old value pha ; Save it - lda (sp),y ; Get stack loc + lda (spc),y ; Get stack loc sta regbank,x ; Store new value pla - sta (sp),y ; Store old value + sta (spc),y ; Store old value inx iny dec tmp1 diff --git a/libsrc/runtime/regswap1.s b/libsrc/runtime/regswap1.s index 753020acb..28e069562 100644 --- a/libsrc/runtime/regswap1.s +++ b/libsrc/runtime/regswap1.s @@ -5,16 +5,16 @@ ; .export regswap1 - .importzp sp, regbank + .importzp spc, regbank .proc regswap1 lda regbank,x ; Get old value pha ; Save it - lda (sp),y ; Get stack loc + lda (spc),y ; Get stack loc sta regbank,x ; Store new value pla - sta (sp),y ; Store old value + sta (spc),y ; Store old value rts .endproc diff --git a/libsrc/runtime/regswap2.s b/libsrc/runtime/regswap2.s index df5109dc6..205458fa2 100644 --- a/libsrc/runtime/regswap2.s +++ b/libsrc/runtime/regswap2.s @@ -5,7 +5,7 @@ ; .export regswap2 - .importzp sp, regbank + .importzp spc, regbank .proc regswap2 @@ -13,20 +13,20 @@ lda regbank,x ; Get old value pha ; Save it - lda (sp),y ; Get stack loc + lda (spc),y ; Get stack loc sta regbank,x ; Store new value pla - sta (sp),y ; Store old value + sta (spc),y ; Store old value ; Second byte iny lda regbank+1,x ; Get old value pha ; Save it - lda (sp),y ; Get stack loc + lda (spc),y ; Get stack loc sta regbank+1,x ; Store new value pla - sta (sp),y ; Store old value + sta (spc),y ; Store old value rts diff --git a/libsrc/runtime/rsub.s b/libsrc/runtime/rsub.s index 69ee6da22..afee1f7c3 100644 --- a/libsrc/runtime/rsub.s +++ b/libsrc/runtime/rsub.s @@ -7,7 +7,7 @@ .export tosrsuba0, tosrsubax .import addysp1 - .importzp sp, tmp1 + .importzp spc, tmp1 .macpack cpu @@ -20,16 +20,16 @@ tosrsuba0: tosrsubax: sec .if (.cpu .bitand CPU_ISET_65SC02) - sbc (sp) + sbc (spc) ldy #1 .else ldy #0 - sbc (sp),y ; lo byte + sbc (spc),y ; lo byte iny .endif sta tmp1 ; save lo byte txa - sbc (sp),y ; hi byte + sbc (spc),y ; hi byte tax lda tmp1 jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/staspidx.s b/libsrc/runtime/staspidx.s index c8d42f34c..c1018b0d2 100644 --- a/libsrc/runtime/staspidx.s +++ b/libsrc/runtime/staspidx.s @@ -6,17 +6,17 @@ .export staspidx .import incsp2 - .importzp sp, tmp1, ptr1 + .importzp spc, tmp1, ptr1 .proc staspidx pha sty tmp1 ; Save Index ldy #1 - lda (sp),y + lda (spc),y sta ptr1+1 dey - lda (sp),y + lda (spc),y sta ptr1 ; Pointer now in ptr1 ldy tmp1 ; Restore offset pla ; Restore value diff --git a/libsrc/runtime/staxsp.s b/libsrc/runtime/staxsp.s index 599e92a32..bacadcddc 100644 --- a/libsrc/runtime/staxsp.s +++ b/libsrc/runtime/staxsp.s @@ -1,20 +1,20 @@ ; ; Ullrich von Bassewitz, 31.08.1998 ; -; CC65 runtime: Store ax at (sp),y +; CC65 runtime: Store ax at (spc),y ; .export staxysp, stax0sp - .importzp sp + .importzp spc stax0sp: ldy #0 staxysp: - sta (sp),y + sta (spc),y iny pha txa - sta (sp),y + sta (spc),y pla rts diff --git a/libsrc/runtime/staxspi.s b/libsrc/runtime/staxspi.s index 3114f449c..44fee6789 100644 --- a/libsrc/runtime/staxspi.s +++ b/libsrc/runtime/staxspi.s @@ -7,7 +7,7 @@ .export staxspidx .import incsp2 - .importzp sp, tmp1, ptr1 + .importzp spc, tmp1, ptr1 .macpack cpu @@ -16,13 +16,13 @@ sty tmp1 ; Save Y pha ; Save A ldy #1 - lda (sp),y + lda (spc),y sta ptr1+1 .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (spc) .else dey - lda (sp),y + lda (spc),y .endif sta ptr1 ; Address now in ptr1 ldy tmp1 ; Restore Y diff --git a/libsrc/runtime/steaxsp.s b/libsrc/runtime/steaxsp.s index 6ac3891c9..89d013fe7 100644 --- a/libsrc/runtime/steaxsp.s +++ b/libsrc/runtime/steaxsp.s @@ -1,26 +1,26 @@ ; ; Ullrich von Bassewitz, 31.08.1998 ; -; CC65 runtime: Store eax at (sp),y +; CC65 runtime: Store eax at (spc),y ; .export steaxysp, steax0sp - .importzp sp, sreg + .importzp spc, sreg steax0sp: ldy #0 steaxysp: - sta (sp),y + sta (spc),y iny pha txa - sta (sp),y + sta (spc),y iny lda sreg - sta (sp),y + sta (spc),y iny lda sreg+1 - sta (sp),y + sta (spc),y pla rts diff --git a/libsrc/runtime/stkchk.s b/libsrc/runtime/stkchk.s index ceab4c703..6125ae442 100644 --- a/libsrc/runtime/stkchk.s +++ b/libsrc/runtime/stkchk.s @@ -17,7 +17,7 @@ .constructor initstkchk, 25 .import __STACKSIZE__ ; Linker defined .import pusha0, _exit - .importzp sp + .importzp spc ; Use macros for better readability .macpack generic @@ -32,11 +32,11 @@ .proc initstkchk - lda sp + lda spc sta initialsp sub #<__STACKSIZE__ sta lowwater - lda sp+1 + lda spc+1 sta initialsp+1 sbc #>__STACKSIZE__ .if (.cpu .bitand ::CPU_ISET_65SC02) @@ -70,7 +70,7 @@ cstkchk: ; Check the high byte of the software stack @L0: lda lowwater+1 - cmp sp+1 + cmp spc+1 bcs @L1 rts @@ -78,7 +78,7 @@ cstkchk: @L1: bne CStackOverflow lda lowwater - cmp sp + cmp spc bcs CStackOverflow Done: rts @@ -87,9 +87,9 @@ Done: rts CStackOverflow: lda initialsp - sta sp + sta spc lda initialsp+1 - sta sp+1 + sta spc+1 ; Generic abort entry. We should output a diagnostic here, but this is ; difficult, since we're operating at a lower level here. diff --git a/libsrc/runtime/sub.s b/libsrc/runtime/sub.s index b41df3d91..4134987e0 100644 --- a/libsrc/runtime/sub.s +++ b/libsrc/runtime/sub.s @@ -6,7 +6,7 @@ .export tossuba0, tossubax .import addysp1 - .importzp sp + .importzp spc .macpack cpu @@ -18,17 +18,17 @@ tossubax: sec eor #$FF .if (.cpu .bitand CPU_ISET_65SC02) - adc (sp) + adc (spc) ldy #1 .else ldy #0 - adc (sp),y ; Subtract low byte + adc (spc),y ; Subtract low byte iny .endif pha ; Save high byte txa eor #$FF - adc (sp),y ; Subtract high byte + adc (spc),y ; Subtract high byte tax ; High byte into X pla ; Restore low byte jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/subeqsp.s b/libsrc/runtime/subeqsp.s index 24080d97d..568b73df9 100644 --- a/libsrc/runtime/subeqsp.s +++ b/libsrc/runtime/subeqsp.s @@ -5,21 +5,21 @@ ; .export subeq0sp, subeqysp - .importzp sp + .importzp spc subeq0sp: ldy #0 subeqysp: sec eor #$FF - adc (sp),y - sta (sp),y + adc (spc),y + sta (spc),y pha ; Save low byte iny txa eor #$FF - adc (sp),y - sta (sp),y + adc (spc),y + sta (spc),y tax pla ; Restore low byte rts diff --git a/libsrc/runtime/subysp.s b/libsrc/runtime/subysp.s index 9fae44222..3fe03bc53 100644 --- a/libsrc/runtime/subysp.s +++ b/libsrc/runtime/subysp.s @@ -6,17 +6,17 @@ ; .export subysp - .importzp sp + .importzp spc .proc subysp tya eor #$ff sec - adc sp - sta sp + adc spc + sta spc bcs @L1 - dec sp+1 + dec spc+1 @L1: rts .endproc diff --git a/libsrc/runtime/swap.s b/libsrc/runtime/swap.s index 5358e08d3..fd4e8154d 100644 --- a/libsrc/runtime/swap.s +++ b/libsrc/runtime/swap.s @@ -6,7 +6,7 @@ ; .export swapstk - .importzp sp, ptr4 + .importzp spc, ptr4 .macpack cpu @@ -14,22 +14,22 @@ swapstk: sta ptr4 stx ptr4+1 ldy #1 ; index - lda (sp),y + lda (spc),y tax lda ptr4+1 - sta (sp),y + sta (spc),y .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (spc) tay lda ptr4 - sta (sp) + sta (spc) tya .else dey - lda (sp),y + lda (spc),y pha lda ptr4 - sta (sp),y + sta (spc),y pla .endif rts ; whew! diff --git a/libsrc/runtime/tosint.s b/libsrc/runtime/tosint.s index ed32298bd..80341050d 100644 --- a/libsrc/runtime/tosint.s +++ b/libsrc/runtime/tosint.s @@ -6,7 +6,7 @@ .export tosint .import incsp2 - .importzp sp + .importzp spc .macpack cpu @@ -16,17 +16,17 @@ pha .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (spc) .else ldy #0 - lda (sp),y ; sp+1 + lda (spc),y ; spc+1 .endif ldy #2 - sta (sp),y + sta (spc),y dey - lda (sp),y + lda (spc),y ldy #3 - sta (sp),y + sta (spc),y pla jmp incsp2 ; Drop 16 bit diff --git a/libsrc/runtime/toslong.s b/libsrc/runtime/toslong.s index 9065d3e6c..7df441383 100644 --- a/libsrc/runtime/toslong.s +++ b/libsrc/runtime/toslong.s @@ -6,7 +6,7 @@ .export tosulong, toslong .import decsp2 - .importzp sp + .importzp spc .macpack cpu @@ -16,25 +16,25 @@ tosulong: pha jsr decsp2 ; Make room ldy #2 - lda (sp),y + lda (spc),y .if (.cpu .bitand CPU_ISET_65SC02) - sta (sp) ; 65C02 version + sta (spc) ; 65C02 version iny ; Y = 3 .else ldy #0 - sta (sp),y + sta (spc),y ldy #3 .endif - lda (sp),y + lda (spc),y toslong1: ldy #1 - sta (sp),y + sta (spc),y lda #0 ; Zero extend toslong2: iny - sta (sp),y + sta (spc),y iny - sta (sp),y + sta (spc),y pla rts @@ -42,19 +42,19 @@ toslong: pha jsr decsp2 ; Make room ldy #2 - lda (sp),y + lda (spc),y .if (.cpu .bitand CPU_ISET_65SC02) - sta (sp) ; 65C02 version + sta (spc) ; 65C02 version iny ; Y = 3 .else ldy #0 - sta (sp),y + sta (spc),y ldy #3 .endif - lda (sp),y + lda (spc),y bpl toslong1 ; Jump if positive, high word is zero ldy #1 - sta (sp),y + sta (spc),y lda #$FF bne toslong2 ; Branch always diff --git a/libsrc/runtime/xor.s b/libsrc/runtime/xor.s index e03922926..38c127a90 100644 --- a/libsrc/runtime/xor.s +++ b/libsrc/runtime/xor.s @@ -7,7 +7,7 @@ .export tosxora0, tosxorax .import addysp1 - .importzp sp, tmp1 + .importzp spc, tmp1 .macpack cpu @@ -15,16 +15,16 @@ tosxora0: ldx #$00 tosxorax: .if (.cpu .bitand CPU_ISET_65SC02) - eor (sp) + eor (spc) ldy #1 .else ldy #0 - eor (sp),y + eor (spc),y iny .endif sta tmp1 txa - eor (sp),y + eor (spc),y tax lda tmp1 jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/zeropage.s b/libsrc/runtime/zeropage.s index 2bbe7ceee..2b95a2899 100644 --- a/libsrc/runtime/zeropage.s +++ b/libsrc/runtime/zeropage.s @@ -10,7 +10,7 @@ .zeropage -sp: .res 2 ; Stack pointer +spc: .res 2 ; Stack pointer sreg: .res 2 ; Secondary register/high 16 bit for longs regsave: .res 4 ; Slot to save/restore (E)AX into ptr1: .res 2 diff --git a/libsrc/sim6502/crt0.s b/libsrc/sim6502/crt0.s index c04a2b8a6..a2d4e7e97 100644 --- a/libsrc/sim6502/crt0.s +++ b/libsrc/sim6502/crt0.s @@ -22,8 +22,8 @@ startup:cld txs lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 + sta spc + stx spc+1 jsr zerobss jsr initlib jsr callmain diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s index 6487e5b0c..7eb1c1c74 100644 --- a/libsrc/sim6502/exehdr.s +++ b/libsrc/sim6502/exehdr.s @@ -5,7 +5,7 @@ ; .export __EXEHDR__ : absolute = 1 ; Linker referenced - .importzp sp + .importzp spc .import __MAIN_START__ .import startup @@ -24,6 +24,6 @@ .else .error Unknown CPU type. .endif - .byte sp ; sp address + .byte spc ; spc address .addr __MAIN_START__ ; load address .addr startup ; reset address diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index fbae1fc46..8a3f59c66 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -33,8 +33,8 @@ reset: lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) ldx #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta spc + stx spc+1 ; Set argument stack ptr jsr initlib jsr _main _exit: jsr donelib diff --git a/libsrc/sym1/crt0.s b/libsrc/sym1/crt0.s index 5d4e0449b..4ce070c9c 100644 --- a/libsrc/sym1/crt0.s +++ b/libsrc/sym1/crt0.s @@ -33,9 +33,9 @@ _init: jsr ACCESS ; Unlock System RAM ; Set cc65 argument stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) - sta sp + sta spc lda #>(__RAM_START__ + __RAM_SIZE__) - sta sp+1 + sta spc+1 ; Initialize memory storage diff --git a/libsrc/telestrat/crt0.s b/libsrc/telestrat/crt0.s index df75520ce..f6796487d 100644 --- a/libsrc/telestrat/crt0.s +++ b/libsrc/telestrat/crt0.s @@ -47,7 +47,7 @@ _exit: jsr donelib ldx #zpspace - 1 L2: lda zpsave,x - sta sp,x + sta spc,x dex bpl L2 @@ -64,7 +64,7 @@ L2: lda zpsave,x ; Save the zero-page area that we're about to use. init: ldx #zpspace - 1 -L1: lda sp,x +L1: lda spc,x sta zpsave,x dex bpl L1 @@ -74,8 +74,8 @@ L1: lda sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta spc + stx spc+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/telestrat/open.s b/libsrc/telestrat/open.s index f59d3d31a..c53a01b53 100644 --- a/libsrc/telestrat/open.s +++ b/libsrc/telestrat/open.s @@ -2,7 +2,7 @@ .import addysp,popax - .importzp sp,tmp2,tmp3,tmp1 + .importzp spc,tmp2,tmp3,tmp1 .include "telestrat.inc" diff --git a/libsrc/telestrat/wherex.s b/libsrc/telestrat/wherex.s index 8616003c8..835a57c0e 100644 --- a/libsrc/telestrat/wherex.s +++ b/libsrc/telestrat/wherex.s @@ -3,7 +3,7 @@ ; .export _wherex - .importzp sp + .importzp spc .include "telestrat.inc" diff --git a/libsrc/tgi/tgi_outtextxy.s b/libsrc/tgi/tgi_outtextxy.s index 3934df871..ea0f3d098 100644 --- a/libsrc/tgi/tgi_outtextxy.s +++ b/libsrc/tgi/tgi_outtextxy.s @@ -8,7 +8,7 @@ .include "tgi-kernel.inc" .import addysp1 - .importzp sp + .importzp spc .proc _tgi_outtextxy @@ -17,16 +17,16 @@ pha ; ldy #0 - lda (sp),y + lda (spc),y sta _tgi_cury iny - lda (sp),y + lda (spc),y sta _tgi_cury+1 iny - lda (sp),y + lda (spc),y sta _tgi_curx iny - lda (sp),y + lda (spc),y sta _tgi_curx+1 pla jsr addysp1 ; Drop arguments from stack diff --git a/libsrc/vic20/crt0.s b/libsrc/vic20/crt0.s index c5486063b..9e07f832d 100644 --- a/libsrc/vic20/crt0.s +++ b/libsrc/vic20/crt0.s @@ -24,7 +24,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda sp,x +L1: lda spc,x sta zpsave,x dex bpl L1 @@ -45,8 +45,8 @@ L1: lda sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta spc + stx spc+1 ; Set argument stack ptr ; Call the module constructors. @@ -65,7 +65,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta spc,x dex bpl L2 diff --git a/libsrc/zlib/inflatemem.s b/libsrc/zlib/inflatemem.s index 80c19f223..35d0532b3 100644 --- a/libsrc/zlib/inflatemem.s +++ b/libsrc/zlib/inflatemem.s @@ -12,7 +12,7 @@ .export _inflatemem .import incsp2 - .importzp sp, sreg, ptr1, ptr2, ptr3, ptr4 + .importzp spc, sreg, ptr1, ptr2, ptr3, ptr4 ; -------------------------------------------------------------------------- ; @@ -79,10 +79,10 @@ _inflatemem: stx inputPointer+1 ; outputPointer = dest ldy #1 - lda (sp),y + lda (spc),y sta outputPointer+1 dey - lda (sp),y + lda (spc),y sta outputPointer ; ldy #0 @@ -129,11 +129,11 @@ inflate_nextBlock: lda outputPointer ; ldy #0 ; sec - sbc (sp),y + sbc (spc),y iny pha lda outputPointer+1 - sbc (sp),y + sbc (spc),y tax pla ; pop dest diff --git a/samples/getsp.s b/samples/getsp.s index 9f169dc0b..6f0d4bdde 100644 --- a/samples/getsp.s +++ b/samples/getsp.s @@ -1,11 +1,11 @@ .export _getsp - .importzp sp + .importzp spc .proc _getsp - ldx sp+1 - lda sp + ldx spc+1 + lda spc rts .endproc diff --git a/samples/tinyshell.c b/samples/tinyshell.c index 71e9b56e3..300ad6e91 100644 --- a/samples/tinyshell.c +++ b/samples/tinyshell.c @@ -112,17 +112,17 @@ static void get_command(void) #ifdef CHECK_SP static char firstcall = 1; static unsigned int good_sp; - unsigned int sp; + unsigned int spc; if (firstcall) - sp = good_sp = getsp(); + spc = good_sp = getsp(); else - sp = getsp(); + spc = getsp(); - if (sp != good_sp) { - printf("SP: 0x%04X ***MISMATCH*** 0x%04X\n", sp, good_sp); + if (spc != good_sp) { + printf("SP: 0x%04X ***MISMATCH*** 0x%04X\n", spc, good_sp); } else if (verbose) - printf("SP: 0x%04X\n", sp); + printf("SP: 0x%04X\n", spc); #endif arg1 = arg2 = arg3 = NULL; diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index e55a318d6..a986b4244 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -218,7 +218,7 @@ void g_preamble (void) AddTextLine ("\t.debuginfo\t%s", (DebugInfo != 0)? "on" : "off"); /* Import zero page variables */ - AddTextLine ("\t.importzp\tsp, sreg, regsave, regbank"); + AddTextLine ("\t.importzp\tspc, sreg, regsave, regbank"); AddTextLine ("\t.importzp\ttmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4"); /* Define long branch macros */ @@ -569,11 +569,11 @@ void g_swap_regvars (int StackOffs, int RegOffs, unsigned Bytes) AddCodeLine ("ldx #$%02X", RegOffs & 0xFF); AddCodeLine ("jsr regswap1"); } else { - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("ldx regbank%+d", RegOffs); AddCodeLine ("sta regbank%+d", RegOffs); AddCodeLine ("txa"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); } } else if (Bytes == 2) { @@ -615,7 +615,7 @@ void g_save_regvars (int RegOffs, unsigned Bytes) AddCodeLine ("ldx #$%02X", (unsigned char) Bytes); g_defcodelabel (Label); AddCodeLine ("lda regbank%+d,x", RegOffs-1); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); AddCodeLine ("dey"); AddCodeLine ("dex"); AddCodeLine ("bne %s", LocalLabelName (Label)); @@ -639,28 +639,28 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) if (Bytes == 1) { AddCodeLine ("ldy #$%02X", StackOffs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta regbank%+d", RegOffs); } else if (Bytes == 2) { AddCodeLine ("ldy #$%02X", StackOffs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta regbank%+d", RegOffs); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta regbank%+d", RegOffs+1); } else if (Bytes == 3 && IS_Get (&CodeSizeFactor) >= 133) { AddCodeLine ("ldy #$%02X", StackOffs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta regbank%+d", RegOffs); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta regbank%+d", RegOffs+1); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta regbank%+d", RegOffs+2); } else if (StackOffs <= RegOffs) { @@ -672,7 +672,7 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) unsigned Label = GetLocalLabel (); AddCodeLine ("ldy #$%02X", StackOffs); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta regbank%+d,y", RegOffs - StackOffs); AddCodeLine ("iny"); AddCodeLine ("cpy #$%02X", StackOffs + Bytes); @@ -688,7 +688,7 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) AddCodeLine ("ldy #$%02X", (unsigned char) (StackOffs + Bytes - 1)); AddCodeLine ("ldx #$%02X", (unsigned char) (Bytes - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta regbank%+d,x", RegOffs); AddCodeLine ("dey"); AddCodeLine ("dex"); @@ -834,11 +834,11 @@ void g_getlocal (unsigned Flags, int Offs) CheckLocalOffs (Offs); if ((Flags & CF_FORCECHAR) || (Flags & CF_TEST)) { AddCodeLine ("ldy #$%02X", Offs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); } else { AddCodeLine ("ldy #$%02X", Offs); AddCodeLine ("ldx #$00"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); if ((Flags & CF_UNSIGNED) == 0) { unsigned L = GetLocalLabel(); AddCodeLine ("bpl %s", LocalLabelName (L)); @@ -852,9 +852,9 @@ void g_getlocal (unsigned Flags, int Offs) CheckLocalOffs (Offs + 1); AddCodeLine ("ldy #$%02X", (unsigned char) (Offs+1)); if (Flags & CF_TEST) { - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("dey"); - AddCodeLine ("ora (sp),y"); + AddCodeLine ("ora (spc),y"); } else { AddCodeLine ("jsr ldaxysp"); } @@ -935,7 +935,7 @@ void g_leasp (int Offs) { unsigned char Lo, Hi; - /* Calculate the offset relative to sp */ + /* Calculate the offset relative to spc */ Offs -= StackPtr; /* Get low and high byte */ @@ -945,17 +945,17 @@ void g_leasp (int Offs) /* Generate code */ if (Lo == 0) { if (Hi <= 3) { - AddCodeLine ("lda sp"); - AddCodeLine ("ldx sp+1"); + AddCodeLine ("lda spc"); + AddCodeLine ("ldx spc+1"); while (Hi--) { AddCodeLine ("inx"); } } else { - AddCodeLine ("lda sp+1"); + AddCodeLine ("lda spc+1"); AddCodeLine ("clc"); AddCodeLine ("adc #$%02X", Hi); AddCodeLine ("tax"); - AddCodeLine ("lda sp"); + AddCodeLine ("lda spc"); } } else if (Hi == 0) { /* 8 bit offset */ @@ -966,8 +966,8 @@ void g_leasp (int Offs) } else { /* 8 bit offset inlined */ unsigned L = GetLocalLabel (); - AddCodeLine ("lda sp"); - AddCodeLine ("ldx sp+1"); + AddCodeLine ("lda spc"); + AddCodeLine ("ldx spc+1"); AddCodeLine ("clc"); AddCodeLine ("adc #$%02X", Lo); AddCodeLine ("bcc %s", LocalLabelName (L)); @@ -981,11 +981,11 @@ void g_leasp (int Offs) AddCodeLine ("jsr leaaxsp"); } else { /* Full 16 bit offset inlined */ - AddCodeLine ("lda sp"); + AddCodeLine ("lda spc"); AddCodeLine ("clc"); AddCodeLine ("adc #$%02X", Lo); AddCodeLine ("pha"); - AddCodeLine ("lda sp+1"); + AddCodeLine ("lda spc+1"); AddCodeLine ("adc #$%02X", Hi); AddCodeLine ("tax"); AddCodeLine ("pla"); @@ -1001,10 +1001,10 @@ void g_leavariadic (int Offs) { unsigned ArgSizeOffs; - /* Calculate the offset relative to sp */ + /* Calculate the offset relative to spc */ Offs -= StackPtr; - /* Get the offset of the parameter which is stored at sp+0 on function + /* Get the offset of the parameter which is stored at spc+0 on function ** entry and check if this offset is reachable with a byte offset. */ CHECK (StackPtr <= 0); @@ -1013,14 +1013,14 @@ void g_leavariadic (int Offs) /* Get the size of all parameters. */ AddCodeLine ("ldy #$%02X", ArgSizeOffs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); /* Add the value of the stackpointer */ if (IS_Get (&CodeSizeFactor) > 250) { unsigned L = GetLocalLabel(); - AddCodeLine ("ldx sp+1"); + AddCodeLine ("ldx spc+1"); AddCodeLine ("clc"); - AddCodeLine ("adc sp"); + AddCodeLine ("adc spc"); AddCodeLine ("bcc %s", LocalLabelName (L)); AddCodeLine ("inx"); g_defcodelabel (L); @@ -1092,14 +1092,14 @@ void g_putlocal (unsigned Flags, int Offs, long Val) AddCodeLine ("lda #$%02X", (unsigned char) Val); } AddCodeLine ("ldy #$%02X", Offs); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); break; case CF_INT: if (Flags & CF_CONST) { AddCodeLine ("ldy #$%02X", Offs+1); AddCodeLine ("lda #$%02X", (unsigned char) (Val >> 8)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); if ((Flags & CF_NOKEEP) == 0) { /* Place high byte into X */ AddCodeLine ("tax"); @@ -1112,16 +1112,16 @@ void g_putlocal (unsigned Flags, int Offs, long Val) AddCodeLine ("dey"); AddCodeLine ("lda #$%02X", (unsigned char) Val); } - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); } else { AddCodeLine ("ldy #$%02X", Offs); if ((Flags & CF_NOKEEP) == 0 || IS_Get (&CodeSizeFactor) < 160) { AddCodeLine ("jsr staxysp"); } else { - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); AddCodeLine ("iny"); AddCodeLine ("txa"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); } } break; @@ -1161,12 +1161,12 @@ void g_putind (unsigned Flags, unsigned Offs) AddCodeLine ("pha"); } AddCodeLine ("lda #$%02X", Offs & 0xFF); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (spc),y"); + AddCodeLine ("sta (spc),y"); AddCodeLine ("iny"); AddCodeLine ("lda #$%02X", (Offs >> 8) & 0xFF); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (spc),y"); + AddCodeLine ("sta (spc),y"); if ((Flags & CF_NOKEEP) == 0) { AddCodeLine ("pla"); } @@ -1183,8 +1183,8 @@ void g_putind (unsigned Flags, unsigned Offs) AddCodeLine ("pha"); } AddCodeLine ("lda #$%02X", (Offs >> 8) & 0xFF); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (spc),y"); + AddCodeLine ("sta (spc),y"); if ((Flags & CF_NOKEEP) == 0) { AddCodeLine ("pla"); } @@ -1618,7 +1618,7 @@ void g_addlocal (unsigned flags, int offs) L = GetLocalLabel(); AddCodeLine ("ldy #$%02X", NewOff & 0xFF); AddCodeLine ("clc"); - AddCodeLine ("adc (sp),y"); + AddCodeLine ("adc (spc),y"); AddCodeLine ("bcc %s", LocalLabelName (L)); AddCodeLine ("inx"); g_defcodelabel (L); @@ -1627,11 +1627,11 @@ void g_addlocal (unsigned flags, int offs) case CF_INT: AddCodeLine ("ldy #$%02X", NewOff & 0xFF); AddCodeLine ("clc"); - AddCodeLine ("adc (sp),y"); + AddCodeLine ("adc (spc),y"); AddCodeLine ("pha"); AddCodeLine ("txa"); AddCodeLine ("iny"); - AddCodeLine ("adc (sp),y"); + AddCodeLine ("adc (spc),y"); AddCodeLine ("tax"); AddCodeLine ("pla"); break; @@ -1839,12 +1839,12 @@ void g_addeqlocal (unsigned flags, int Offs, unsigned long val) if (flags & CF_CONST) { AddCodeLine ("clc"); AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (spc),y"); + AddCodeLine ("sta (spc),y"); } else { AddCodeLine ("clc"); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (spc),y"); + AddCodeLine ("sta (spc),y"); } if ((flags & CF_UNSIGNED) == 0) { unsigned L = GetLocalLabel(); @@ -1862,16 +1862,16 @@ void g_addeqlocal (unsigned flags, int Offs, unsigned long val) if (IS_Get (&CodeSizeFactor) >= 400) { AddCodeLine ("clc"); AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (spc),y"); + AddCodeLine ("sta (spc),y"); AddCodeLine ("iny"); AddCodeLine ("lda #$%02X", (int) ((val >> 8) & 0xFF)); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (spc),y"); + AddCodeLine ("sta (spc),y"); if ((flags & CF_NOKEEP) == 0) { AddCodeLine ("tax"); AddCodeLine ("dey"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); } } else { g_getimmed (flags, val, 0); @@ -1923,7 +1923,7 @@ void g_addeqind (unsigned flags, unsigned offs, unsigned long val) case CF_INT: case CF_LONG: AddCodeLine ("jsr pushax"); /* Push the address */ - push (CF_PTR); /* Correct the internal sp */ + push (CF_PTR); /* Correct the internal spc */ g_getind (flags, offs); /* Fetch the value */ g_inc (flags, val); /* Increment value in primary */ g_putind (flags, offs); /* Store the value back */ @@ -2089,15 +2089,15 @@ void g_subeqlocal (unsigned flags, int Offs, unsigned long val) AddCodeLine ("ldy #$%02X", Offs); AddCodeLine ("ldx #$00"); if (flags & CF_CONST) { - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sec"); AddCodeLine ("sbc #$%02X", (unsigned char)val); } else { AddCodeLine ("eor #$FF"); AddCodeLine ("sec"); - AddCodeLine ("adc (sp),y"); + AddCodeLine ("adc (spc),y"); } - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); if ((flags & CF_UNSIGNED) == 0) { unsigned L = GetLocalLabel(); AddCodeLine ("bpl %s", LocalLabelName (L)); @@ -2157,7 +2157,7 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val) case CF_INT: case CF_LONG: AddCodeLine ("jsr pushax"); /* Push the address */ - push (CF_PTR); /* Correct the internal sp */ + push (CF_PTR); /* Correct the internal spc */ g_getind (flags, offs); /* Fetch the value */ g_dec (flags, val); /* Increment value in primary */ g_putind (flags, offs); /* Store the value back */ @@ -2208,10 +2208,10 @@ void g_addaddr_local (unsigned flags attribute ((unused)), int offs) /* Label was used above */ g_defcodelabel (L); } - AddCodeLine ("adc sp"); + AddCodeLine ("adc spc"); AddCodeLine ("tay"); AddCodeLine ("txa"); - AddCodeLine ("adc sp+1"); + AddCodeLine ("adc spc+1"); AddCodeLine ("tax"); AddCodeLine ("tya"); } @@ -2512,10 +2512,10 @@ void g_callind (unsigned Flags, unsigned ArgSize, int Offs) CheckLocalOffs (Offs); AddCodeLine ("pha"); AddCodeLine ("ldy #$%02X", Offs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta jmpvec+1"); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta jmpvec+2"); AddCodeLine ("pla"); AddCodeLine ("jsr jmpvec"); @@ -2573,11 +2573,11 @@ void g_lateadjustSP (unsigned label) AddCodeLine ("pha"); AddCodeLine ("lda %s", LocalDataLabelName (label)); AddCodeLine ("clc"); - AddCodeLine ("adc sp"); - AddCodeLine ("sta sp"); + AddCodeLine ("adc spc"); + AddCodeLine ("sta spc"); AddCodeLine ("lda %s+1", LocalDataLabelName (label)); - AddCodeLine ("adc sp+1"); - AddCodeLine ("sta sp+1"); + AddCodeLine ("adc spc+1"); + AddCodeLine ("sta spc+1"); AddCodeLine ("pla"); } @@ -2591,11 +2591,11 @@ void g_drop (unsigned Space) AddCodeLine ("pha"); AddCodeLine ("lda #$%02X", (unsigned char) Space); AddCodeLine ("clc"); - AddCodeLine ("adc sp"); - AddCodeLine ("sta sp"); + AddCodeLine ("adc spc"); + AddCodeLine ("sta spc"); AddCodeLine ("lda #$%02X", (unsigned char) (Space >> 8)); - AddCodeLine ("adc sp+1"); - AddCodeLine ("sta sp+1"); + AddCodeLine ("adc spc+1"); + AddCodeLine ("sta spc+1"); AddCodeLine ("pla"); } else if (Space > 8) { AddCodeLine ("ldy #$%02X", Space); @@ -2618,13 +2618,13 @@ void g_space (int Space) ** overhead. */ AddCodeLine ("pha"); - AddCodeLine ("lda sp"); + AddCodeLine ("lda spc"); AddCodeLine ("sec"); AddCodeLine ("sbc #$%02X", (unsigned char) Space); - AddCodeLine ("sta sp"); - AddCodeLine ("lda sp+1"); + AddCodeLine ("sta spc"); + AddCodeLine ("lda spc+1"); AddCodeLine ("sbc #$%02X", (unsigned char) (Space >> 8)); - AddCodeLine ("sta sp+1"); + AddCodeLine ("sta spc+1"); AddCodeLine ("pla"); } else if (Space > 8) { AddCodeLine ("ldy #$%02X", Space); @@ -4584,14 +4584,14 @@ void g_initauto (unsigned Label, unsigned Size) AddCodeLine ("ldy #$%02X", Size-1); g_defcodelabel (CodeLabel); AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, Label, 0)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (CodeLabel)); } else if (Size <= 256) { AddCodeLine ("ldy #$00"); g_defcodelabel (CodeLabel); AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, Label, 0)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Size); AddCodeLine ("bne %s", LocalLabelName (CodeLabel)); diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 435794613..5be8a38e2 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -390,8 +390,8 @@ static const ZPInfo ZPInfoTable[] = { { 7, "regbank", 6, REG_NONE, REG_NONE }, { 0, "regsave", 4, REG_SAVE_LO, REG_SAVE }, { 0, "regsave+1", 3, REG_SAVE_HI, REG_SAVE }, - { 0, "sp", 2, REG_SP_LO, REG_SP }, - { 0, "sp+1", 1, REG_SP_HI, REG_SP }, + { 0, "spc", 2, REG_SP_LO, REG_SP }, + { 0, "spc+1", 1, REG_SP_HI, REG_SP }, { 0, "sreg", 2, REG_SREG_LO, REG_SREG }, { 0, "sreg+1", 1, REG_SREG_HI, REG_SREG }, { 0, "tmp1", 1, REG_TMP1, REG_TMP1 }, diff --git a/src/cc65/codeinfo.h b/src/cc65/codeinfo.h index c57908dad..01cf345c5 100644 --- a/src/cc65/codeinfo.h +++ b/src/cc65/codeinfo.h @@ -75,8 +75,8 @@ struct RegContents; #define REG_SP_HI 0x2000U /* Defines for some special register usage */ -#define SLV_IND 0x00010000U /* Accesses (sp),y */ -#define SLV_TOP 0x00020000U /* Accesses (sp),0 */ +#define SLV_IND 0x00010000U /* Accesses (spc),y */ +#define SLV_TOP 0x00020000U /* Accesses (spc),0 */ #define SLV_SP65 0x00200000U /* Accesses 6502 stack pointer */ #define SLV_PH65 0x00400000U /* Pushes onto 6502 stack */ #define SLV_PL65 0x00800000U /* Pops from 6502 stack */ diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index a716ad431..3a896a9c1 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -810,7 +810,7 @@ static unsigned RunOptGroup5 (CodeSeg* S) static unsigned RunOptGroup6 (CodeSeg* S) -/* This one is quite special. It tries to replace "lda (sp),y" by "lda (sp,x)". +/* This one is quite special. It tries to replace "lda (spc),y" by "lda (spc,x)". ** The latter is ony cycle slower, but if we're able to remove the necessary ** load of the Y register, because X is zero anyway, we gain 1 cycle and ** shorten the code by one (transfer) or two bytes (load). So what we do is diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 43b1dee22..2335a283a 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -333,14 +333,14 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) */ if (E->AM == AM65_ABS || E->AM == AM65_ZP || - (E->AM == AM65_ZP_INDY && strcmp (E->ArgBase, "sp") == 0) + (E->AM == AM65_ZP_INDY && strcmp (E->ArgBase, "spc") == 0) ) { if ((LRI->Flags & LI_CHECK_ARG) != 0) { if (AE == 0 || (AE->AM != AM65_ABS && AE->AM != AM65_ZP && (AE->AM != AM65_ZP_INDY || - strcmp (AE->ArgBase, "sp") != 0)) || + strcmp (AE->ArgBase, "spc") != 0)) || (AE->ArgOff == E->ArgOff && strcmp (AE->ArgBase, E->ArgBase) == 0)) { @@ -445,7 +445,7 @@ void PrepairLoadRegInfoForArgCheck (CodeSeg* S, LoadRegInfo* LRI, CodeEntry* E) /* These insns are replaceable only if they are not modified later */ LRI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; } else if ((E->AM == AM65_ZP_INDY) && - strcmp (E->Arg, "sp") == 0) { + strcmp (E->Arg, "spc") == 0) { /* A load from the stack with known offset is also ok, but in this ** case we must reload the index register later. Please note that ** a load indirect via other zero page locations is not ok, since @@ -556,7 +556,7 @@ unsigned int TrackLoads (LoadInfo* LI, CodeSeg* S, int I) /* These insns are replaceable only if they are not modified later */ LRI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; } else if (E->AM == AM65_ZP_INDY && - strcmp (E->Arg, "sp") == 0) { + strcmp (E->Arg, "spc") == 0) { /* A load from the stack with known offset is also ok, but in this ** case we must reload the index register later. Please note that ** a load indirect via other zero page locations is not ok, since @@ -839,7 +839,7 @@ void AdjustStackOffset (StackOpData* D, unsigned Offs) if (E->OPC != OP65_JSR) { /* Check against some things that should not happen */ CHECK (E->AM == AM65_ZP_INDY && E->RI->In.RegY >= (short) Offs); - CHECK (strcmp (E->Arg, "sp") == 0); + CHECK (strcmp (E->Arg, "spc") == 0); /* We need to correct this one */ Correction = 2; @@ -1056,8 +1056,8 @@ void AddOpLow (StackOpData* D, opc_t OPC, LoadInfo* LI) InsertEntry (D, X, D->IP++); if (LI->A.LoadEntry->OPC == OP65_JSR) { - /* opc (sp),y */ - X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); + /* opc (spc),y */ + X = NewCodeEntry (OPC, AM65_ZP_INDY, "spc", 0, D->OpEntry->LI); } else { /* opc src,y */ X = NewCodeEntry (OPC, LI->A.LoadEntry->AM, LI->A.LoadEntry->Arg, 0, D->OpEntry->LI); @@ -1119,8 +1119,8 @@ void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) InsertEntry (D, X, D->IP++); if (LI->X.LoadEntry->OPC == OP65_JSR) { - /* opc (sp),y */ - X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); + /* opc (spc),y */ + X = NewCodeEntry (OPC, AM65_ZP_INDY, "spc", 0, D->OpEntry->LI); } else { /* opc src,y */ X = NewCodeEntry (OPC, LI->X.LoadEntry->AM, LI->X.LoadEntry->Arg, 0, D->OpEntry->LI); @@ -1310,10 +1310,10 @@ const char* GetZPName (unsigned ZPLoc) return "save+1"; } if ((ZPLoc & REG_SP_LO) != 0) { - return "sp"; + return "spc"; } if ((ZPLoc & REG_SP_HI) != 0) { - return "sp+1"; + return "spc+1"; } return 0; diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index bc67f7a74..5af9c1079 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -62,15 +62,15 @@ unsigned OptAdd1 (CodeSeg* S) ** and replace it by: ** ** ldy #xx-1 -** lda (sp),y +** lda (spc),y ** ldy #yy-3 ** clc -** adc (sp),y +** adc (spc),y ** pha ** ldy #xx -** lda (sp),y +** lda (spc),y ** ldy #yy-2 -** adc (sp),y +** adc (spc),y ** tax ** pla */ @@ -104,8 +104,8 @@ unsigned OptAdd1 (CodeSeg* S) /* Correct the stack of the first Y register load */ CE_SetNumArg (L[0], L[0]->Num - 1); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* lda (spc),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); CS_InsertEntry (S, X, I+1); /* ldy #yy-3 */ @@ -117,8 +117,8 @@ unsigned OptAdd1 (CodeSeg* S) X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[5]->LI); CS_InsertEntry (S, X, I+3); - /* adc (sp),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[5]->LI); + /* adc (spc),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "spc", 0, L[5]->LI); CS_InsertEntry (S, X, I+4); /* pha */ @@ -130,8 +130,8 @@ unsigned OptAdd1 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); CS_InsertEntry (S, X, I+6); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* lda (spc),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); CS_InsertEntry (S, X, I+7); /* ldy #yy-2 */ @@ -139,8 +139,8 @@ unsigned OptAdd1 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[4]->LI); CS_InsertEntry (S, X, I+8); - /* adc (sp),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[5]->LI); + /* adc (spc),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "spc", 0, L[5]->LI); CS_InsertEntry (S, X, I+9); /* tax */ @@ -181,16 +181,16 @@ unsigned OptAdd2 (CodeSeg* S) ** and replace it by: ** ** ldy #xx-1 -** lda (sp),y +** lda (spc),y ** ldy #yy ** clc -** adc (sp),y -** sta (sp),y +** adc (spc),y +** sta (spc),y ** ldy #xx -** lda (sp),y +** lda (spc),y ** ldy #yy+1 -** adc (sp),y -** sta (sp),y +** adc (spc),y +** sta (spc),y ** ** provided that a/x is not used later. */ @@ -226,8 +226,8 @@ unsigned OptAdd2 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+4); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* lda (spc),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); CS_InsertEntry (S, X, I+5); /* ldy #yy */ @@ -238,20 +238,20 @@ unsigned OptAdd2 (CodeSeg* S) X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[3]->LI); CS_InsertEntry (S, X, I+7); - /* adc (sp),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[3]->LI); + /* adc (spc),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "spc", 0, L[3]->LI); CS_InsertEntry (S, X, I+8); - /* sta (sp),y */ - X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, L[3]->LI); + /* sta (spc),y */ + X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "spc", 0, L[3]->LI); CS_InsertEntry (S, X, I+9); /* ldy #xx */ X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+10); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* lda (spc),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); CS_InsertEntry (S, X, I+11); /* ldy #yy+1 */ @@ -259,12 +259,12 @@ unsigned OptAdd2 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[2]->LI); CS_InsertEntry (S, X, I+12); - /* adc (sp),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[3]->LI); + /* adc (spc),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "spc", 0, L[3]->LI); CS_InsertEntry (S, X, I+13); - /* sta (sp),y */ - X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, L[3]->LI); + /* sta (spc),y */ + X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "spc", 0, L[3]->LI); CS_InsertEntry (S, X, I+14); /* Delete the old code */ diff --git a/src/cc65/coptadd.h b/src/cc65/coptadd.h index e4df3b304..2598f726d 100644 --- a/src/cc65/coptadd.h +++ b/src/cc65/coptadd.h @@ -55,14 +55,14 @@ unsigned OptAdd1 (CodeSeg* S); ** jsr pushax ** ldy xxx ** ldx #$00 -** lda (sp),y +** lda (spc),y ** jsr tosaddax ** ** and replace it by: ** ** ldy xxx-2 ** clc -** adc (sp),y +** adc (spc),y ** bcc L ** inx ** L: @@ -72,26 +72,26 @@ unsigned OptAdd2 (CodeSeg* S); /* Search for the sequence ** ** ldy #xx -** lda (sp),y +** lda (spc),y ** tax ** dey -** lda (sp),y +** lda (spc),y ** ldy #$yy ** jsr addeqysp ** ** and replace it by: ** ** ldy #xx-1 -** lda (sp),y +** lda (spc),y ** ldy #yy ** clc -** adc (sp),y -** sta (sp),y +** adc (spc),y +** sta (spc),y ** ldy #xx -** lda (sp),y +** lda (spc),y ** ldy #yy+1 -** adc (sp),y -** sta (sp),y +** adc (spc),y +** sta (spc),y ** ** provided that a/x is not used later. */ diff --git a/src/cc65/coptbool.c b/src/cc65/coptbool.c index 3a3b3fa7c..c5a54f9be 100644 --- a/src/cc65/coptbool.c +++ b/src/cc65/coptbool.c @@ -743,9 +743,9 @@ unsigned OptBNegAX2 (CodeSeg* S) ** and replace it by ** ** ldy #xx -** lda (sp),y +** lda (spc),y ** dey -** ora (sp),y +** ora (spc),y ** jeq/jne ... */ { @@ -772,16 +772,16 @@ unsigned OptBNegAX2 (CodeSeg* S) CodeEntry* X; - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* lda (spc),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); CS_InsertEntry (S, X, I+1); /* dey */ X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[1]->LI); CS_InsertEntry (S, X, I+2); - /* ora (sp),y */ - X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* ora (spc),y */ + X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "spc", 0, L[1]->LI); CS_InsertEntry (S, X, I+3); /* Invert the branch */ diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index 2970b363b..0148e87f9 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -431,22 +431,22 @@ unsigned OptCmp5 (CodeSeg* S) /* The value is zero, we may use the simple code version: ** ldy #o-1 - ** lda (sp),y + ** lda (spc),y ** ldy #o - ** ora (sp),y + ** ora (spc),y ** jne/jeq ... */ sprintf (Buf, "$%02X", (int)(L[0]->Num-1)); X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI); CS_InsertEntry (S, X, I+1); - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); CS_InsertEntry (S, X, I+2); X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+3); - X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "spc", 0, L[1]->LI); CS_InsertEntry (S, X, I+4); CS_DelEntries (S, I+5, 3); /* cpx/bne/cmp */ @@ -461,18 +461,18 @@ unsigned OptCmp5 (CodeSeg* S) ** of the low byte after the first branch if possible: ** ** ldy #o - ** lda (sp),y + ** lda (spc),y ** cmp #a ** bne L1 ** ldy #o-1 - ** lda (sp),y + ** lda (spc),y ** cmp #b ** jne/jeq ... */ X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+3); - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); CS_InsertEntry (S, X, I+4); X = NewCodeEntry (OP65_CMP, L[2]->AM, L[2]->Arg, 0, L[2]->LI); @@ -482,7 +482,7 @@ unsigned OptCmp5 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI); CS_InsertEntry (S, X, I+7); - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); CS_InsertEntry (S, X, I+8); CS_DelEntries (S, I, 3); /* ldy/jsr/cpx */ diff --git a/src/cc65/coptcmp.h b/src/cc65/coptcmp.h index dd188f7fc..222892679 100644 --- a/src/cc65/coptcmp.h +++ b/src/cc65/coptcmp.h @@ -113,10 +113,10 @@ unsigned OptCmp5 (CodeSeg* S); /* Optimize compares of local variables: ** ** ldy #o -** lda (sp),y +** lda (spc),y ** tax ** dey -** lda (sp),y +** lda (spc),y ** cpx #a ** bne L1 ** cmp #b diff --git a/src/cc65/coptmisc.c b/src/cc65/coptmisc.c index e48d469a1..323e0e7bc 100644 --- a/src/cc65/coptmisc.c +++ b/src/cc65/coptmisc.c @@ -492,9 +492,9 @@ unsigned OptGotoSPAdj (CodeSeg* S) L[1]->AM == AM65_ABS && L[2]->OPC == OP65_CLC && L[3]->OPC == OP65_ADC && - strcmp (L[3]->Arg, "sp") == 0 && + strcmp (L[3]->Arg, "spc") == 0 && L[6]->OPC == OP65_ADC && - strcmp (L[6]->Arg, "sp+1") == 0 && + strcmp (L[6]->Arg, "spc+1") == 0 && L[9]->OPC == OP65_JMP) { adjustment = FindSPAdjustment (L[1]->Arg); @@ -617,7 +617,7 @@ unsigned OptLoad1 (CodeSeg* S) CS_InsertEntry (S, X, I+1); /* Load from stack */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, E->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, E->LI); CS_InsertEntry (S, X, I+2); /* Now remove the call to the subroutine */ @@ -673,8 +673,8 @@ unsigned OptLoad2 (CodeSeg* S) ** later */ - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); + /* lda (spc),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[0]->LI); CS_InsertEntry (S, X, I+3); /* sta abs */ @@ -685,8 +685,8 @@ unsigned OptLoad2 (CodeSeg* S) X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[0]->LI); CS_InsertEntry (S, X, I+5); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); + /* lda (spc),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[0]->LI); CS_InsertEntry (S, X, I+6); /* sta abs */ @@ -700,8 +700,8 @@ unsigned OptLoad2 (CodeSeg* S) /* Standard replacement */ - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); + /* lda (spc),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[0]->LI); CS_InsertEntry (S, X, I+1); /* tax */ @@ -712,8 +712,8 @@ unsigned OptLoad2 (CodeSeg* S) X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[0]->LI); CS_InsertEntry (S, X, I+3); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); + /* lda (spc),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[0]->LI); CS_InsertEntry (S, X, I+4); /* Now remove the call to the subroutine */ diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index 046e65d79..26aa37a2e 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -359,7 +359,7 @@ unsigned OptPtrLoad4 (CodeSeg* S) ** ldx #>(label+0) ** ldy #$xx ** clc -** adc (sp),y +** adc (spc),y ** bcc L ** inx ** L: ldy #$00 @@ -368,7 +368,7 @@ unsigned OptPtrLoad4 (CodeSeg* S) ** and replace it by: ** ** ldy #$xx -** lda (sp),y +** lda (spc),y ** tay ** ldx #$00 ** lda label,y @@ -553,7 +553,7 @@ unsigned OptPtrLoad6 (CodeSeg* S) ** jsr pushax ** ldy #xxx ** ldx #$00 -** lda (sp),y +** lda (spc),y ** jsr tosaddax ** ldy #$00 ** jsr ldauidx @@ -563,7 +563,7 @@ unsigned OptPtrLoad6 (CodeSeg* S) ** sta ptr1 ** stx ptr1+1 ** ldy #xxx-2 -** lda (sp),y +** lda (spc),y ** tay ** ldx #$00 ** lda (ptr1),y @@ -613,7 +613,7 @@ unsigned OptPtrLoad6 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); CS_InsertEntry (S, X, I+9); - /* lda (sp),y */ + /* lda (spc),y */ X = NewCodeEntry (OP65_LDA, L[3]->AM, L[3]->Arg, 0, L[3]->LI); CS_InsertEntry (S, X, I+10); diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h index d4e0e2ed4..f8aee9b1a 100644 --- a/src/cc65/coptptrload.h +++ b/src/cc65/coptptrload.h @@ -127,7 +127,7 @@ unsigned OptPtrLoad4 (CodeSeg* S); ** ldx #>(label+0) ** ldy #$xx ** clc -** adc (sp),y +** adc (spc),y ** bcc L ** inx ** L: ldy #$00 @@ -136,7 +136,7 @@ unsigned OptPtrLoad4 (CodeSeg* S); ** and replace it by: ** ** ldy #$xx -** lda (sp),y +** lda (spc),y ** tay ** ldx #$00 ** lda label,y @@ -166,7 +166,7 @@ unsigned OptPtrLoad6 (CodeSeg* S); ** jsr pushax ** ldy xxx ** ldx #$00 -** lda (sp),y +** lda (spc),y ** jsr tosaddax ** ldy #$00 ** jsr ldauidx @@ -176,7 +176,7 @@ unsigned OptPtrLoad6 (CodeSeg* S); ** sta ptr1 ** stx ptr1+1 ** ldy xxx -** lda (sp),y +** lda (spc),y ** tay ** lda (ptr1),y */ diff --git a/src/cc65/coptptrstore.c b/src/cc65/coptptrstore.c index 11832910f..558c12859 100644 --- a/src/cc65/coptptrstore.c +++ b/src/cc65/coptptrstore.c @@ -396,7 +396,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** L: jsr pushax ** ldy yyy ** ldx #$00 -** lda (sp),y +** lda (spc),y ** ldy #$00 ** jsr staspidx ** @@ -406,7 +406,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** stx ptr1+1 ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (spc),y ** ldy xxx ** sta (ptr1),y ** @@ -414,7 +414,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (spc),y ** ldy xxx ** sta (zp),y ** @@ -422,7 +422,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (spc),y ** ldy xxx ** sta label,y ** @@ -430,7 +430,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (spc),y ** ldy xxx ** sta $xxxx,y ** @@ -468,7 +468,7 @@ unsigned OptPtrStore2 (CodeSeg* S) L[6]->OPC == OP65_LDX && L[7]->OPC == OP65_LDA && L[7]->AM == AM65_ZP_INDY && - strcmp (L[7]->Arg, "sp") == 0 && + strcmp (L[7]->Arg, "spc") == 0 && L[8]->OPC == OP65_LDY && (L[8]->AM == AM65_ABS || L[8]->AM == AM65_ZP || diff --git a/src/cc65/coptptrstore.h b/src/cc65/coptptrstore.h index 3f8fc91f9..77e73649a 100644 --- a/src/cc65/coptptrstore.h +++ b/src/cc65/coptptrstore.h @@ -105,7 +105,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** L: jsr pushax ** ldy yyy ** ldx #$00 -** lda (sp),y +** lda (spc),y ** ldy #$00 ** jsr staspidx ** @@ -115,7 +115,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** stx ptr1+1 ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (spc),y ** ldy xxx ** sta (ptr1),y ** @@ -123,7 +123,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (spc),y ** ldy xxx ** sta (zp),y ** @@ -131,7 +131,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (spc),y ** ldy xxx ** sta label,y ** @@ -139,7 +139,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (spc),y ** ldy xxx ** sta $xxxx,y ** diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 402f16b97..e14e049c6 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1292,10 +1292,10 @@ static unsigned Opt_a_tosicmp (StackOpData* D) } InsertEntry (D, X, D->IP++); - /* cmp src,y OR cmp (sp),y */ + /* cmp src,y OR cmp (spc),y */ if (D->Rhs.A.LoadEntry->OPC == OP65_JSR) { - /* opc (sp),y */ - X = NewCodeEntry (OP65_CMP, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); + /* opc (spc),y */ + X = NewCodeEntry (OP65_CMP, AM65_ZP_INDY, "spc", 0, D->OpEntry->LI); } else { /* opc src,y */ X = NewCodeEntry (OP65_CMP, D->Rhs.A.LoadEntry->AM, D->Rhs.A.LoadEntry->Arg, 0, D->OpEntry->LI); diff --git a/src/cc65/coptstore.c b/src/cc65/coptstore.c index b0dfe3b6d..a3458835b 100644 --- a/src/cc65/coptstore.c +++ b/src/cc65/coptstore.c @@ -48,7 +48,7 @@ static void InsertStore (CodeSeg* S, unsigned* IP, LineInfo* LI) { - CodeEntry* X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, LI); + CodeEntry* X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "spc", 0, LI); CS_InsertEntry (S, X, (*IP)++); } diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 08e41918e..98ba16d3b 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -269,7 +269,7 @@ static void ParseAutoDecl (Declarator* Decl) Sym->V.Offs = F_ReserveLocalSpace (CurrentFunc, Size); /* Next, allocate the space on the stack. This means that the - ** variable is now located at offset 0 from the current sp. + ** variable is now located at offset 0 from the current spc. */ F_AllocLocalSpace (CurrentFunc); diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 2889a176e..f22bb314e 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -370,7 +370,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); g_defcodelabel (Label); AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); } else { @@ -378,7 +378,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); g_defcodelabel (Label); AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); AddCodeLine ("dey"); AddCodeLine ("dex"); AddCodeLine ("bpl %s", LocalLabelName (Label)); @@ -390,7 +390,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); @@ -399,7 +399,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); AddCodeLine ("iny"); AddCodeLine ("inx"); AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal); @@ -447,7 +447,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Offs == 0) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); @@ -455,7 +455,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldx #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); AddCodeLine ("dey"); AddCodeLine ("dex"); @@ -467,7 +467,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Offs == 0 || AllowOneIndex) { AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs)); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); @@ -476,7 +476,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldx #$00"); AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); AddCodeLine ("iny"); AddCodeLine ("inx"); @@ -511,14 +511,14 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Arg3.Expr.IVal <= 129) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta (ptr1),y"); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); } else { AddCodeLine ("ldy #$00"); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta (ptr1),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); @@ -702,7 +702,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) Offs); AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); g_defcodelabel (Label); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); @@ -856,7 +856,7 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Generate code */ AddCodeLine ("ldy #$%02X", Offs); AddCodeLine ("ldx #$00"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); } else if (IsArray && ED_IsLocConst (&Arg1.Expr)) { /* Drop the generated code */ RemoveCode (&Arg1.Load); @@ -1089,14 +1089,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Offs == 0 || AllowOneIndex) { g_defcodelabel (L1); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs)); } else { AddCodeLine ("ldx #$FF"); g_defcodelabel (L1); AddCodeLine ("iny"); AddCodeLine ("inx"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); } AddCodeLine ("bne %s", LocalLabelName (L1)); @@ -1137,14 +1137,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) g_defcodelabel (L1); AddCodeLine ("iny"); AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); } else { AddCodeLine ("ldx #$FF"); g_defcodelabel (L1); AddCodeLine ("iny"); AddCodeLine ("inx"); AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (spc),y"); } AddCodeLine ("bne %s", LocalLabelName (L1)); @@ -1284,7 +1284,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) g_defcodelabel (L); AddCodeLine ("inx"); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (spc),y"); AddCodeLine ("bne %s", LocalLabelName (L)); AddCodeLine ("txa"); AddCodeLine ("ldx #$00"); diff --git a/src/dbginfo/dbgsh.c b/src/dbginfo/dbgsh.c index 6a95db2af..23a943c3b 100644 --- a/src/dbginfo/dbgsh.c +++ b/src/dbginfo/dbgsh.c @@ -458,7 +458,7 @@ static unsigned FindIdType (const char* TypeName) { "segment", SegmentId }, { "source", SourceId }, { "src", SourceId }, - { "sp", SpanId }, + { "spc", SpanId }, { "span", SpanId }, { "sym", SymbolId }, { "symbol", SymbolId }, diff --git a/src/sim65/main.c b/src/sim65/main.c index 828ea498e..98b33dacb 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -230,7 +230,7 @@ static unsigned char ReadProgramFile (void) } } - /* Get the address of sp from the file header */ + /* Get the address of spc from the file header */ if ((Val = fgetc(F)) != EOF) { SPAddr = Val; } diff --git a/targettest/atari/mem.c b/targettest/atari/mem.c index b15b215ed..b72866ee9 100644 --- a/targettest/atari/mem.c +++ b/targettest/atari/mem.c @@ -41,7 +41,7 @@ int main(void) printf(" data: $%04X (data)\n", &data); printf(" _dos_type: $%04X (bss)\n", &_dos_type); printf(" allocmem: $%04X (dyn. data)\n", allocmem); - printf(" sp: $%04X (stack ptr)\n", getsp()); + printf(" spc: $%04X (stack ptr)\n", getsp()); if (allocmem) free(allocmem); if (doesclrscrafterexit()) cgetc(); diff --git a/targettest/ft.c b/targettest/ft.c index 3dfa0e37b..ecaf72519 100644 --- a/targettest/ft.c +++ b/targettest/ft.c @@ -10,7 +10,7 @@ ** got one from argv). I then opens the file, ** reads the first 16 bytes and displays them ** (as hex values). -** The values of sp (cc65 runtime stack pointer) +** The values of spc (cc65 runtime stack pointer) ** are displayed at some places. The displayed ** value should always be the same. */ @@ -64,16 +64,16 @@ int main(int argc,char **argv) } printf("using filename \"%s\"\n",filename); csp = getsp(); - printf("now opening file... sp = %d\n",csp); + printf("now opening file... spc = %d\n",csp); fd = open(filename,O_RDONLY); csp = getsp(); if (fd == -1) { char x1 = _oserror; - printf("open failed: os: %d,\n\terrno: %d, sp = %d\n",x1,errno,csp); + printf("open failed: os: %d,\n\terrno: %d, spc = %d\n",x1,errno,csp); cgetc(); return(0); } - printf("open success -- handle = $%x, sp = %d\n",fd,csp); + printf("open success -- handle = $%x, spc = %d\n",fd,csp); #ifdef __ATARI__ printf("fd_index:\n "); for (i=0; i<12; i++) printf("%02X ",__fd_index[i]); @@ -88,7 +88,7 @@ int main(int argc,char **argv) lr = read(fd,buf,16); /* read first 16 bytes */ csp = getsp(); if (lr == -1) { - printf("read failed: %d (sp = %d)\n",errno,csp); + printf("read failed: %d (spc = %d)\n",errno,csp); cgetc(); return(0); } @@ -99,7 +99,7 @@ int main(int argc,char **argv) return(0); } csp = getsp(); - printf("\n\nThe data read: (%d bytes, sp = %d)\n",lr,csp); + printf("\n\nThe data read: (%d bytes, spc = %d)\n",lr,csp); for (i=0; i<lr; i++) { printf("%02X ",buf[i]); if (!((i+1) & 7)) printf("\n"); diff --git a/targettest/getsp.s b/targettest/getsp.s index 9f169dc0b..6f0d4bdde 100644 --- a/targettest/getsp.s +++ b/targettest/getsp.s @@ -1,11 +1,11 @@ .export _getsp - .importzp sp + .importzp spc .proc _getsp - ldx sp+1 - lda sp + ldx spc+1 + lda spc rts .endproc diff --git a/test/asm/opcodes/m740-opcodes.s b/test/asm/opcodes/m740-opcodes.s index df6d71488..1cdafc9c8 100644 --- a/test/asm/opcodes/m740-opcodes.s +++ b/test/asm/opcodes/m740-opcodes.s @@ -36,7 +36,7 @@ bbr1 $12,*+122 ; clb 0,zp jsr $3456 and ($12,x) - .byte $22,$00,$00 ; jsr sp + .byte $22,$00,$00 ; jsr spc .byte $23,$00,$00 ; bbs 1,a bit $12 and $12 diff --git a/test/val/bug1652-optimizer.c b/test/val/bug1652-optimizer.c index 7926ef770..9ddb9c25c 100644 --- a/test/val/bug1652-optimizer.c +++ b/test/val/bug1652-optimizer.c @@ -10,9 +10,9 @@ before: jsr pusha ldy #$01 ldx #$00 - lda (sp),y + lda (spc),y beq L0005 - lda (sp,x) + lda (spc,x) beq L0005 txa jmp incsp2 ; <-- @@ -24,9 +24,9 @@ after: jsr pusha ldy #$01 ldx #$00 - lda (sp),y + lda (spc),y beq L0004 - lda (sp,x) + lda (spc,x) beq L0004 txa jmp L0001 ; <-- diff --git a/test/val/cq85.c b/test/val/cq85.c index 81a99c960..566dbaeb1 100644 --- a/test/val/cq85.c +++ b/test/val/cq85.c @@ -62,7 +62,7 @@ int s85(struct defs *pd0){ struct tnode *right; }; - struct tnode s1, s2, *sp; + struct tnode s1, s2, *spc; struct{ char cdummy; From dd2f19260c7affa49a5d818204ed8c9f12d27b61 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Wed, 4 Jun 2025 03:03:18 +0000 Subject: [PATCH 458/707] added information to Makefile output --- Makefile | 10 ++++++++++ doc/Makefile | 10 ++++++++++ libsrc/Makefile | 10 ++++++++++ samples/Makefile | 10 ++++++++++ samples/apple2/Makefile | 10 ++++++++++ samples/atari2600/Makefile | 10 ++++++++++ samples/atari5200/Makefile | 10 ++++++++++ samples/cbm/Makefile | 10 ++++++++++ samples/disasm/Makefile | 10 ++++++++++ samples/gamate/Makefile | 10 ++++++++++ samples/geos/Makefile | 10 ++++++++++ samples/geos/grc/Makefile | 10 ++++++++++ samples/kim1/Makefile | 10 ++++++++++ samples/lynx/Makefile | 10 ++++++++++ samples/sim65/Makefile | 10 ++++++++++ samples/supervision/Makefile | 10 ++++++++++ samples/sym1/Makefile | 10 ++++++++++ samples/tutorial/Makefile | 10 ++++++++++ src/Makefile | 10 ++++++++++ targettest/Makefile | 10 ++++++++++ targettest/accelerator/Makefile | 10 ++++++++++ targettest/atari/Makefile | 10 ++++++++++ targettest/cbm/Makefile | 10 ++++++++++ targettest/gamate/Makefile | 10 ++++++++++ targettest/pce/Makefile | 10 ++++++++++ test/Makefile | 10 ++++++++++ test/asm/Makefile | 10 ++++++++++ test/asm/cpudetect/Makefile | 10 ++++++++++ test/asm/err/Makefile | 10 ++++++++++ test/asm/listing/Makefile | 10 ++++++++++ test/asm/misc/Makefile | 10 ++++++++++ test/asm/opcodes/Makefile | 10 ++++++++++ test/asm/val/Makefile | 10 ++++++++++ test/dasm/Makefile | 10 ++++++++++ test/err/Makefile | 10 ++++++++++ test/misc/Makefile | 10 ++++++++++ test/ref/Makefile | 10 ++++++++++ test/standard/Makefile | 10 ++++++++++ test/standard_err/Makefile | 10 ++++++++++ test/todo/Makefile | 10 ++++++++++ test/val/Makefile | 10 ++++++++++ util/Makefile | 10 ++++++++++ util/atari/Makefile | 10 ++++++++++ util/gamate/Makefile | 10 ++++++++++ util/zlib/Makefile | 10 ++++++++++ 45 files changed, 450 insertions(+) diff --git a/Makefile b/Makefile index 29fcbbf96..91c1d78df 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + .PHONY: all mostlyclean clean install zip avail unavail bin lib doc html info samples test util checkstyle check .SUFFIXES: diff --git a/doc/Makefile b/doc/Makefile index bfdf0cce3..cbb41132d 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + ifneq ($(shell echo),) CMD_EXE = 1 endif diff --git a/libsrc/Makefile b/libsrc/Makefile index 8a4f11414..c3651e069 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + ifneq ($(shell echo),) CMD_EXE = 1 endif diff --git a/samples/Makefile b/samples/Makefile index 3680f542c..194bd3244 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # # Makefile for cc65 samples # diff --git a/samples/apple2/Makefile b/samples/apple2/Makefile index 55e84aed6..2bf9ca257 100644 --- a/samples/apple2/Makefile +++ b/samples/apple2/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/atari2600/Makefile b/samples/atari2600/Makefile index bd2ebc41a..8224b8784 100644 --- a/samples/atari2600/Makefile +++ b/samples/atari2600/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/atari5200/Makefile b/samples/atari5200/Makefile index 2fbda11d9..838966782 100644 --- a/samples/atari5200/Makefile +++ b/samples/atari5200/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/cbm/Makefile b/samples/cbm/Makefile index 4b89722d2..fbd0248be 100644 --- a/samples/cbm/Makefile +++ b/samples/cbm/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/disasm/Makefile b/samples/disasm/Makefile index f1d93f5da..818742e5c 100644 --- a/samples/disasm/Makefile +++ b/samples/disasm/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Sample makefile using a preprocessor against info files # and the --sync-lines option diff --git a/samples/gamate/Makefile b/samples/gamate/Makefile index cfb8505cc..629b5a584 100644 --- a/samples/gamate/Makefile +++ b/samples/gamate/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/geos/Makefile b/samples/geos/Makefile index 578927760..9d7a98d3f 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index ef30a6e03..f3343a4bb 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/kim1/Makefile b/samples/kim1/Makefile index 08bb2a780..96a64cbcf 100644 --- a/samples/kim1/Makefile +++ b/samples/kim1/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/lynx/Makefile b/samples/lynx/Makefile index b4ef64af0..44e6cec71 100644 --- a/samples/lynx/Makefile +++ b/samples/lynx/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/sim65/Makefile b/samples/sim65/Makefile index 865594736..0cf9778c6 100644 --- a/samples/sim65/Makefile +++ b/samples/sim65/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/supervision/Makefile b/samples/supervision/Makefile index 097329384..9dd201f6a 100644 --- a/samples/supervision/Makefile +++ b/samples/supervision/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/sym1/Makefile b/samples/sym1/Makefile index 281b5bcd0..e81cc7c33 100644 --- a/samples/sym1/Makefile +++ b/samples/sym1/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile index eb8627c29..eeb37f72d 100644 --- a/samples/tutorial/Makefile +++ b/samples/tutorial/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/src/Makefile b/src/Makefile index 034a2230f..8d335d52c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + ifneq ($(shell echo),) CMD_EXE = 1 endif diff --git a/targettest/Makefile b/targettest/Makefile index f78e22461..19d141a12 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # # Makefile for cc65 testcode # diff --git a/targettest/accelerator/Makefile b/targettest/accelerator/Makefile index dd5011459..2cc67d4fe 100644 --- a/targettest/accelerator/Makefile +++ b/targettest/accelerator/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. SYS ?= c64 diff --git a/targettest/atari/Makefile b/targettest/atari/Makefile index d5b4d9593..2f1856ffd 100644 --- a/targettest/atari/Makefile +++ b/targettest/atari/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/targettest/cbm/Makefile b/targettest/cbm/Makefile index c3171b13e..8944d72c6 100644 --- a/targettest/cbm/Makefile +++ b/targettest/cbm/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. SYS ?= c64 diff --git a/targettest/gamate/Makefile b/targettest/gamate/Makefile index e2b060406..674ccf85f 100644 --- a/targettest/gamate/Makefile +++ b/targettest/gamate/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/targettest/pce/Makefile b/targettest/pce/Makefile index 89abca6b6..9a97027f3 100644 --- a/targettest/pce/Makefile +++ b/targettest/pce/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/test/Makefile b/test/Makefile index 495082fa4..21d0623e2 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # top-level Makefile for the regression tests ifneq ($(shell echo),) diff --git a/test/asm/Makefile b/test/asm/Makefile index 5b3bff3f8..c69bbb725 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # top-level Makefile for the regression tests ifneq ($(shell echo),) diff --git a/test/asm/cpudetect/Makefile b/test/asm/cpudetect/Makefile index ffddb1ad8..cd755bd13 100644 --- a/test/asm/cpudetect/Makefile +++ b/test/asm/cpudetect/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the assembler regression tests ifneq ($(shell echo),) diff --git a/test/asm/err/Makefile b/test/asm/err/Makefile index 6d2430d34..0f37a2b9a 100644 --- a/test/asm/err/Makefile +++ b/test/asm/err/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the tests that MUST NOT compile ifneq ($(shell echo),) diff --git a/test/asm/listing/Makefile b/test/asm/listing/Makefile index 23aa3969c..88940c769 100644 --- a/test/asm/listing/Makefile +++ b/test/asm/listing/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the assembler regression tests ifneq ($(shell echo),) diff --git a/test/asm/misc/Makefile b/test/asm/misc/Makefile index 5a9d4f3ef..3605504b1 100644 --- a/test/asm/misc/Makefile +++ b/test/asm/misc/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the remaining asm tests that need special care in one way or another ifneq ($(shell echo),) diff --git a/test/asm/opcodes/Makefile b/test/asm/opcodes/Makefile index 00be96d91..d0115ae05 100644 --- a/test/asm/opcodes/Makefile +++ b/test/asm/opcodes/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the assembler regression tests ifneq ($(shell echo),) diff --git a/test/asm/val/Makefile b/test/asm/val/Makefile index 54b1100ec..34111cfed 100644 --- a/test/asm/val/Makefile +++ b/test/asm/val/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the regression tests that return an error code on failure ifneq ($(shell echo),) diff --git a/test/dasm/Makefile b/test/dasm/Makefile index e84560ad2..240503191 100644 --- a/test/dasm/Makefile +++ b/test/dasm/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the disassembler regression tests ifneq ($(shell echo),) diff --git a/test/err/Makefile b/test/err/Makefile index 1273bbb2c..238e57e35 100644 --- a/test/err/Makefile +++ b/test/err/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the tests that MUST NOT compile ifneq ($(shell echo),) diff --git a/test/misc/Makefile b/test/misc/Makefile index 48293e504..dcda6e7b4 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the remaining tests that need special care in one way or another ifneq ($(shell echo),) diff --git a/test/ref/Makefile b/test/ref/Makefile index e82c6de37..213512640 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the regression tests that generate output which has to be # compared with reference output diff --git a/test/standard/Makefile b/test/standard/Makefile index bf513c84e..d710ab443 100644 --- a/test/standard/Makefile +++ b/test/standard/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the regression tests that return an error code on failure ifneq ($(shell echo),) diff --git a/test/standard_err/Makefile b/test/standard_err/Makefile index 700a52eea..c99108cca 100644 --- a/test/standard_err/Makefile +++ b/test/standard_err/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the tests that MUST NOT compile ifneq ($(shell echo),) diff --git a/test/todo/Makefile b/test/todo/Makefile index 062b899ce..cb341ff80 100644 --- a/test/todo/Makefile +++ b/test/todo/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the currently failing regression tests that return an error code on failure ifneq ($(shell echo),) diff --git a/test/val/Makefile b/test/val/Makefile index 56d8e5ff9..75a0755e8 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + # Makefile for the regression tests that return an error code on failure ifneq ($(shell echo),) diff --git a/util/Makefile b/util/Makefile index 6d960abf6..b4c1d900c 100644 --- a/util/Makefile +++ b/util/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + .PHONY: atari gamate zlib diff --git a/util/atari/Makefile b/util/atari/Makefile index e53c837aa..3fbde98c2 100644 --- a/util/atari/Makefile +++ b/util/atari/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + CC = $(CROSS_COMPILE)gcc diff --git a/util/gamate/Makefile b/util/gamate/Makefile index 54fa74191..cbd6c68d9 100644 --- a/util/gamate/Makefile +++ b/util/gamate/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + CC = $(CROSS_COMPILE)gcc diff --git a/util/zlib/Makefile b/util/zlib/Makefile index f276ddaf2..b0f274539 100644 --- a/util/zlib/Makefile +++ b/util/zlib/Makefile @@ -1,3 +1,13 @@ +# ---- Display info during parsing phase ---- +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) +$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) +ifeq ($(MAKECMDGOALS),) + $(info ~~~ Invoked target: (default)) +else + $(info ~~~ Invoked target: $(MAKECMDGOALS)) +endif +$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) + CC = $(CROSS_COMPILE)gcc From b6f42f9ab260d0974281aae15aa74166edddac1d Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Wed, 4 Jun 2025 06:37:59 +0000 Subject: [PATCH 459/707] changed "spc" to "c_sp" --- asminc/zeropage.inc | 2 +- doc/atari.sgml | 2 +- doc/ca65.sgml | 6 +- doc/cc65-intern.sgml | 12 +- doc/customizing.sgml | 4 +- doc/sim65.sgml | 2 +- libsrc/apple2/callmain.s | 2 +- libsrc/apple2/crt0.s | 6 +- libsrc/apple2/exec.s | 4 +- libsrc/apple2/filename.s | 14 +- libsrc/apple2/mli_file_info_direct.s | 4 +- libsrc/apple2/mou/a2.stdmou.s | 4 +- libsrc/apple2/open.s | 4 +- libsrc/apple2/syschdir.s | 4 +- libsrc/apple2/sysmkdir.s | 4 +- libsrc/apple2/sysremove.s | 4 +- libsrc/apple2/sysrename.s | 8 +- libsrc/atari/crt0.s | 8 +- libsrc/atari/diopncls.s | 8 +- libsrc/atari/fdtable.s | 4 +- libsrc/atari/mcbpm.s | 14 +- libsrc/atari/mou/atrjoy.s | 4 +- libsrc/atari/mou/atrst.s | 4 +- libsrc/atari/mou/atrtt.s | 4 +- libsrc/atari/sysrename.s | 22 ++-- libsrc/atari/ucase_fn.s | 12 +- libsrc/atari2600/crt0.s | 4 +- libsrc/atari5200/crt0.s | 4 +- libsrc/atari7800/crt0.s | 4 +- libsrc/atari7800/mono_setcursor.s | 2 +- libsrc/atari7800/setcursor.s | 2 +- libsrc/atmos/crt0.s | 8 +- libsrc/c128/crt0.s | 8 +- libsrc/c128/mou/c128-1351.s | 4 +- libsrc/c128/mou/c128-inkwell.s | 4 +- libsrc/c128/mou/c128-joy.s | 4 +- libsrc/c128/mou/c128-pot.s | 4 +- libsrc/c16/crt0.s | 8 +- libsrc/c64/crt0.s | 8 +- libsrc/c64/mou/c64-1351.s | 4 +- libsrc/c64/mou/c64-inkwell.s | 4 +- libsrc/c64/mou/c64-joy.s | 4 +- libsrc/c64/mou/c64-pot.s | 4 +- libsrc/cbm/dir.s | 8 +- libsrc/cbm/open.s | 2 +- libsrc/cbm/write.s | 2 +- libsrc/cbm510/crt0.s | 12 +- libsrc/cbm510/mou/cbm510-inkwl.s | 4 +- libsrc/cbm510/mou/cbm510-joy.s | 4 +- libsrc/cbm610/crt0.s | 12 +- libsrc/common/_fopen.s | 10 +- libsrc/common/_heap.s | 6 +- libsrc/common/_idiv32by16r16.s | 8 +- libsrc/common/_printf.s | 14 +- libsrc/common/_udiv32by16r16.s | 8 +- libsrc/common/fprintf.s | 8 +- libsrc/common/fread.s | 14 +- libsrc/common/fscanf.s | 8 +- libsrc/common/interrupt.s | 4 +- libsrc/common/itoa.s | 10 +- libsrc/common/longjmp.s | 6 +- libsrc/common/lz4.s | 2 +- libsrc/common/memcpy.s | 6 +- libsrc/common/memset.s | 6 +- libsrc/common/printf.s | 6 +- libsrc/common/realloc.s | 2 +- libsrc/common/scanf.s | 6 +- libsrc/common/setjmp.s | 6 +- libsrc/common/snprintf.s | 8 +- libsrc/common/sprintf.s | 8 +- libsrc/common/sscanf.s | 8 +- libsrc/common/vfprintf.s | 10 +- libsrc/common/vfscanf.s | 8 +- libsrc/common/vprintf.s | 14 +- libsrc/common/vscanf.s | 12 +- libsrc/common/vsnprintf.s | 14 +- libsrc/common/vsscanf.s | 10 +- libsrc/conio/cprintf.s | 6 +- libsrc/conio/cscanf.s | 4 +- libsrc/conio/vcprintf.s | 10 +- libsrc/creativision/crt0.s | 4 +- libsrc/cx16/crt0.s | 4 +- libsrc/cx16/mou/cx16-std.s | 4 +- libsrc/dbg/dbgdump.s | 12 +- libsrc/dbg/dbgsupp.s | 8 +- libsrc/gamate/crt0.s | 4 +- libsrc/geos-common/drivers/geos-stdmou.s | 12 +- libsrc/geos-common/system/crt0.s | 6 +- libsrc/kim1/crt0.s | 4 +- libsrc/lynx/crt0.s | 4 +- libsrc/lynx/lseek.s | 2 +- libsrc/nes/crt0.s | 4 +- libsrc/none/crt0.s | 4 +- libsrc/osic1p/crt0.s | 4 +- libsrc/pce/_printf.s | 12 +- libsrc/pce/crt0.s | 6 +- libsrc/pce/memcpy.s | 6 +- libsrc/pet/crt0.s | 8 +- libsrc/plus4/crt0.s | 8 +- libsrc/rp6502/crt0.s | 4 +- libsrc/rp6502/ria.s | 2 +- libsrc/rp6502/xreg.s | 6 +- libsrc/runtime/add.s | 24 ++-- libsrc/runtime/addeqsp.s | 10 +- libsrc/runtime/addysp.s | 8 +- libsrc/runtime/and.s | 8 +- libsrc/runtime/bpushbsp.s | 4 +- libsrc/runtime/decsp1.s | 8 +- libsrc/runtime/decsp2.s | 8 +- libsrc/runtime/decsp3.s | 8 +- libsrc/runtime/decsp4.s | 8 +- libsrc/runtime/decsp5.s | 8 +- libsrc/runtime/decsp6.s | 8 +- libsrc/runtime/decsp7.s | 8 +- libsrc/runtime/decsp8.s | 8 +- libsrc/runtime/enter.s | 10 +- libsrc/runtime/eq.s | 2 +- libsrc/runtime/icmp.s | 14 +- libsrc/runtime/incsp1.s | 6 +- libsrc/runtime/incsp2.s | 16 +-- libsrc/runtime/ladd.s | 12 +- libsrc/runtime/laddeqsp.s | 18 +-- libsrc/runtime/land.s | 12 +- libsrc/runtime/lcmp.s | 10 +- libsrc/runtime/ldau0sp.s | 6 +- libsrc/runtime/ldauisp.s | 6 +- libsrc/runtime/ldaxsp.s | 6 +- libsrc/runtime/ldeaxysp.s | 10 +- libsrc/runtime/leaaxsp.s | 6 +- libsrc/runtime/leave.s | 18 +-- libsrc/runtime/lmul.s | 12 +- libsrc/runtime/lor.s | 12 +- libsrc/runtime/lpop.s | 12 +- libsrc/runtime/lpush.s | 12 +- libsrc/runtime/lrsub.s | 12 +- libsrc/runtime/lsub.s | 12 +- libsrc/runtime/lsubeqsp.s | 18 +-- libsrc/runtime/ludiv.s | 12 +- libsrc/runtime/lxor.s | 12 +- libsrc/runtime/or.s | 8 +- libsrc/runtime/popa.s | 10 +- libsrc/runtime/popptr1.s | 8 +- libsrc/runtime/popsreg.s | 8 +- libsrc/runtime/pusha.s | 16 +-- libsrc/runtime/pushax.s | 14 +- libsrc/runtime/pushbsp.s | 4 +- libsrc/runtime/pushlysp.s | 10 +- libsrc/runtime/pushwsp.s | 16 +-- libsrc/runtime/regswap.s | 6 +- libsrc/runtime/regswap1.s | 6 +- libsrc/runtime/regswap2.s | 10 +- libsrc/runtime/rsub.s | 8 +- libsrc/runtime/staspidx.s | 6 +- libsrc/runtime/staxsp.s | 8 +- libsrc/runtime/staxspi.s | 8 +- libsrc/runtime/steaxsp.s | 12 +- libsrc/runtime/stkchk.s | 14 +- libsrc/runtime/sub.s | 8 +- libsrc/runtime/subeqsp.s | 10 +- libsrc/runtime/subysp.s | 8 +- libsrc/runtime/swap.s | 14 +- libsrc/runtime/tosint.s | 12 +- libsrc/runtime/toslong.s | 26 ++-- libsrc/runtime/xor.s | 8 +- libsrc/runtime/zeropage.s | 2 +- libsrc/sim6502/crt0.s | 4 +- libsrc/sim6502/exehdr.s | 4 +- libsrc/supervision/crt0.s | 4 +- libsrc/sym1/crt0.s | 4 +- libsrc/telestrat/crt0.s | 8 +- libsrc/telestrat/open.s | 2 +- libsrc/telestrat/wherex.s | 2 +- libsrc/tgi/tgi_outtextxy.s | 10 +- libsrc/vic20/crt0.s | 8 +- libsrc/zlib/inflatemem.s | 10 +- samples/getsp.s | 6 +- samples/tinyshell.c | 12 +- src/cc65/codegen.c | 155 ++++++++++++----------- src/cc65/codeinfo.c | 5 +- src/cc65/codeinfo.h | 6 +- src/cc65/codeopt.c | 2 +- src/cc65/codeoptutil.c | 22 ++-- src/cc65/coptadd.c | 60 ++++----- src/cc65/coptadd.h | 20 +-- src/cc65/coptbool.c | 12 +- src/cc65/coptcmp.c | 16 +-- src/cc65/coptcmp.h | 4 +- src/cc65/coptmisc.c | 22 ++-- src/cc65/coptptrload.c | 10 +- src/cc65/coptptrload.h | 8 +- src/cc65/coptptrstore.c | 12 +- src/cc65/coptptrstore.h | 10 +- src/cc65/coptstop.c | 6 +- src/cc65/coptstore.c | 2 +- src/cc65/locals.c | 2 +- src/cc65/stdfunc.c | 34 ++--- src/dbginfo/dbgsh.c | 2 +- src/sim65/main.c | 2 +- targettest/atari/mem.c | 2 +- targettest/ft.c | 12 +- targettest/getsp.s | 6 +- test/asm/opcodes/m740-opcodes.s | 2 +- test/val/bug1652-optimizer.c | 8 +- test/val/cq85.c | 2 +- 204 files changed, 913 insertions(+), 909 deletions(-) diff --git a/asminc/zeropage.inc b/asminc/zeropage.inc index 75e498b39..5285779ba 100644 --- a/asminc/zeropage.inc +++ b/asminc/zeropage.inc @@ -8,7 +8,7 @@ ; by the compiler, ready for usage in asm code. - .globalzp spc, sreg, regsave + .globalzp c_sp, sreg, regsave .globalzp ptr1, ptr2, ptr3, ptr4 .globalzp tmp1, tmp2, tmp3, tmp4 .globalzp regbank diff --git a/doc/atari.sgml b/doc/atari.sgml index 96948f791..1a83d74fb 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -1121,7 +1121,7 @@ If BSS and/or the stack shouldn't stay at the end of the program, some parts of the cc65 runtime lib need to be replaced/modified. common/_heap.s defines the location of the heap and atari/crt0.s -defines the location of the stack by initializing spc. +defines the location of the stack by initializing c_sp. <sect1>Upgrading from an older cc65 version<p> diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 20684c283..ba4355f9f 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4788,17 +4788,17 @@ bit. Using <tscreen><verb> .if (.cpu .bitand CPU_ISET_65SC02) - lda (spc) + lda (c_sp) .else ldy #$00 - lda (spc),y + lda (c_sp),y .endif </verb></tscreen> it is possible to determine if the <tscreen><verb> - lda (spc) + lda (c_sp) </verb></tscreen> instruction is supported, which is the case for the 65SC02, 65C02 and 65816 diff --git a/doc/cc65-intern.sgml b/doc/cc65-intern.sgml index 3f1c99008..9c59cd79a 100644 --- a/doc/cc65-intern.sgml +++ b/doc/cc65-intern.sgml @@ -131,7 +131,7 @@ All other parameters will be pushed to the C-stack from left to right. The rightmost parameter will have the lowest address on the stack, and multi-byte parameters will have their least significant byte at the lower address. -The <tt/spc/ pseudo-register is a zeropage pointer to the base of the C-stack. +The <tt/c_sp/ pseudo-register is a zeropage pointer to the base of the C-stack. If the function is variadic, the <tt/Y/ register will contain the number of bytes pushed to the stack for this function. @@ -153,10 +153,10 @@ void cdecl foo(unsigned bar, unsigned char baz); ; Example code for accessing bar. The variable is in A/X after this code snippet: ; ldy #2 ; Offset of high byte of bar - lda (spc),y ; High byte now in A + lda (c_sp),y ; High byte now in A tax ; High byte now in X dey ; Offset of low byte of bar - lda (spc),y ; Low byte now in A + lda (c_sp),y ; Low byte now in A </verb></tscreen> <sect1>Epilogue, after the function call<p> @@ -175,12 +175,12 @@ used if the return type is 32-bit. If the function has a void return type, the compiler will not depend on the result of <tt>A/X/sreg</tt>, so these may be clobbered by the function. -The C-stack pointer <tt/spc/ must be restored by the function to its value before the +The C-stack pointer <tt/c_sp/ must be restored by the function to its value before the function call prologue. It may pop all of its parameters from the C-stack (e.g. using the <tt/runtime/ function <tt/popa/), -or it could adjust <tt/spc/ directly. +or it could adjust <tt/c_sp/ directly. If the function is variadic, the <tt/Y/ register contains the number of bytes -pushed to the stack on entry, which may be added to <tt/spc/ to restore its +pushed to the stack on entry, which may be added to <tt/c_sp/ to restore its original state. The internal pseudo-register <tt/regbank/ must not be changed by the function. diff --git a/doc/customizing.sgml b/doc/customizing.sgml index 04af5e7d5..ffca0ce58 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -193,9 +193,9 @@ _init: LDX #$FF ; Initialize stack pointer to $01FF ; Set cc65 argument stack pointer LDA #<(__RAM_START__ + __RAM_SIZE__) - STA spc + STA c_sp LDA #>(__RAM_START__ + __RAM_SIZE__) - STA spc+1 + STA c_sp+1 ; --------------------------------------------------------------------------- ; Initialize memory storage diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 831531533..46ef961cb 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -209,7 +209,7 @@ Internally, the binary program file has a 12 byte header provided by the library <item>1 byte <bf/CPU type/: <tt/0/ = 6502, <tt/1/ = 65C02 -<item>1 byte <bf/spc address/: the zero page address of the C parameter stack pointer <tt/spc/ used by the paravirtualization functions +<item>1 byte <bf/c_sp address/: the zero page address of the C parameter stack pointer <tt/c_sp/ used by the paravirtualization functions <item>1 word <bf/load address/: where to load the data from the file into memory (default: <tt/$0200/) diff --git a/libsrc/apple2/callmain.s b/libsrc/apple2/callmain.s index 687075318..c43e339aa 100644 --- a/libsrc/apple2/callmain.s +++ b/libsrc/apple2/callmain.s @@ -54,7 +54,7 @@ exit: ldx #$02 ; Copy back the zero-page stuff. ldx #zpspace-1 : lda zpsave,x - sta spc,x + sta c_sp,x dex bpl :- diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index 31e868259..005ed6466 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -43,7 +43,7 @@ ; Save the zero-page locations that we need. init: ldx #zpspace-1 -: lda spc,x +: lda c_sp,x sta zpsave,x dex bpl :- @@ -81,8 +81,8 @@ basic: lda HIMEM ldx HIMEM+1 ; Set up the C stack. -: sta spc - stx spc+1 +: sta c_sp + stx c_sp+1 ; ProDOS TechRefMan, chapter 5.3.5: ; "Your system program should place in the RESET vector the diff --git a/libsrc/apple2/exec.s b/libsrc/apple2/exec.s index 5d81f3b60..38f31ee37 100644 --- a/libsrc/apple2/exec.s +++ b/libsrc/apple2/exec.s @@ -42,9 +42,9 @@ _exec: ; binary programs so we should do the same too in any case ; especially as _we_ rely on it in mainargs.s for argv[0] ldy #$00 - lda (spc),y + lda (c_sp),y tay -: lda (spc),y +: lda (c_sp),y sta $0280,y dey bpl :- diff --git a/libsrc/apple2/filename.s b/libsrc/apple2/filename.s index 5a892172f..f4723ee1f 100644 --- a/libsrc/apple2/filename.s +++ b/libsrc/apple2/filename.s @@ -34,8 +34,8 @@ pushname: sta mliparam + MLI::ON_LINE::UNIT_NUM ; Use allocated pathname buffer - lda spc - ldx spc+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::ON_LINE::DATA_BUFFER stx mliparam + MLI::ON_LINE::DATA_BUFFER+1 @@ -46,16 +46,16 @@ pushname: bcs addsp65 ; Get volume name length - lda (spc),y + lda (c_sp),y and #15 ; Max volume name length ; Bracket volume name with slashes to form prefix sta tmp1 lda #'/' - sta (spc),y + sta (c_sp),y ldy tmp1 iny ; Leading slash - sta (spc),y + sta (c_sp),y iny ; Trailing slash ; Adjust source pointer for copy @@ -69,7 +69,7 @@ pushname: ; Copy source to allocated pathname buffer copy: lda (ptr1),y - sta (spc),y + sta (c_sp),y beq setlen iny cpy #FILENAME_MAX @@ -86,7 +86,7 @@ addsp65:ldy #FILENAME_MAX setlen: tya jsr decsp1 ; Preserves A ldy #$00 - sta (spc),y + sta (c_sp),y ; Return success tya diff --git a/libsrc/apple2/mli_file_info_direct.s b/libsrc/apple2/mli_file_info_direct.s index 510457f51..7fdaa9edf 100644 --- a/libsrc/apple2/mli_file_info_direct.s +++ b/libsrc/apple2/mli_file_info_direct.s @@ -11,8 +11,8 @@ ; Returns with carry set on error, and sets errno mli_file_info_direct: ; Set pushed name - lda spc - ldx spc+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::INFO::PATHNAME stx mliparam + MLI::INFO::PATHNAME+1 diff --git a/libsrc/apple2/mou/a2.stdmou.s b/libsrc/apple2/mou/a2.stdmou.s index 40a894035..38cd7c957 100644 --- a/libsrc/apple2/mou/a2.stdmou.s +++ b/libsrc/apple2/mou/a2.stdmou.s @@ -341,10 +341,10 @@ MOVE: ldy #$00 ; Start at top of stack ; Set x - lda (spc),y + lda (c_sp),y iny sta pos1_lo,x - lda (spc),y + lda (c_sp),y sta pos1_hi,x ; Update cursor diff --git a/libsrc/apple2/open.s b/libsrc/apple2/open.s index 29bc20bcc..8f1df26df 100644 --- a/libsrc/apple2/open.s +++ b/libsrc/apple2/open.s @@ -101,8 +101,8 @@ found: tya bne oserr1 ; Set pushed name - lda spc - ldx spc+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::OPEN::PATHNAME stx mliparam + MLI::OPEN::PATHNAME+1 diff --git a/libsrc/apple2/syschdir.s b/libsrc/apple2/syschdir.s index d0fdb5551..be78a91b9 100644 --- a/libsrc/apple2/syschdir.s +++ b/libsrc/apple2/syschdir.s @@ -17,8 +17,8 @@ __syschdir: bne oserr ; Set pushed name - lda spc - ldx spc+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::PREFIX::PATHNAME stx mliparam + MLI::PREFIX::PATHNAME+1 diff --git a/libsrc/apple2/sysmkdir.s b/libsrc/apple2/sysmkdir.s index 2e79d81ac..e59421319 100644 --- a/libsrc/apple2/sysmkdir.s +++ b/libsrc/apple2/sysmkdir.s @@ -23,8 +23,8 @@ __sysmkdir: bne oserr ; Set pushed name - lda spc - ldx spc+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::CREATE::PATHNAME stx mliparam + MLI::CREATE::PATHNAME+1 diff --git a/libsrc/apple2/sysremove.s b/libsrc/apple2/sysremove.s index 864794e3d..088407024 100644 --- a/libsrc/apple2/sysremove.s +++ b/libsrc/apple2/sysremove.s @@ -16,8 +16,8 @@ __sysremove: bne oserr ; Set pushed name - lda spc - ldx spc+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::DESTROY::PATHNAME stx mliparam + MLI::DESTROY::PATHNAME+1 diff --git a/libsrc/apple2/sysrename.s b/libsrc/apple2/sysrename.s index e1ffb1454..3e380548f 100644 --- a/libsrc/apple2/sysrename.s +++ b/libsrc/apple2/sysrename.s @@ -22,8 +22,8 @@ __sysrename: bne oserr1 ; Save pushed oldname - lda spc - ldx spc+1 + lda c_sp + ldx c_sp+1 sta ptr3 stx ptr3+1 @@ -40,8 +40,8 @@ __sysrename: stx mliparam + MLI::RENAME::PATHNAME+1 ; Set pushed newname - lda spc - ldx spc+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::RENAME::NEW_PATHNAME stx mliparam + MLI::RENAME::NEW_PATHNAME+1 diff --git a/libsrc/atari/crt0.s b/libsrc/atari/crt0.s index be49b142f..2ccc7eeb9 100644 --- a/libsrc/atari/crt0.s +++ b/libsrc/atari/crt0.s @@ -59,8 +59,8 @@ start: lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta spc - stx spc+1 + sta c_sp + stx c_sp+1 .else @@ -75,11 +75,11 @@ start: lda MEMTOP sbc #<__RESERVED_MEMORY__ sta APPMHI ; initialize our APPMHI value - sta spc ; set up runtime stack part 1 + sta c_sp ; set up runtime stack part 1 lda MEMTOP+1 sbc #>__RESERVED_MEMORY__ sta APPMHI+1 - sta spc+1 ; set up runtime stack part 2 + sta c_sp+1 ; set up runtime stack part 2 .endif diff --git a/libsrc/atari/diopncls.s b/libsrc/atari/diopncls.s index 9e67829ef..a5c145081 100644 --- a/libsrc/atari/diopncls.s +++ b/libsrc/atari/diopncls.s @@ -16,7 +16,7 @@ .export sectsizetab .import ___oserror, __sio_call, _dio_read .import pushax, addysp, subysp - .importzp ptr2, spc + .importzp ptr2, c_sp .include "atari.inc" @@ -78,10 +78,10 @@ _dio_open: ldy #128 jsr subysp ; allocate buffer on the stack - lda spc + lda c_sp pha - lda spc+1 - pha ; save spc (buffer address) on processor stack + lda c_sp+1 + pha ; save c_sp (buffer address) on processor stack lda ptr2 ldx ptr2+1 diff --git a/libsrc/atari/fdtable.s b/libsrc/atari/fdtable.s index 5556716dd..9323af5d3 100644 --- a/libsrc/atari/fdtable.s +++ b/libsrc/atari/fdtable.s @@ -6,7 +6,7 @@ .include "atari.inc" .include "fd.inc" - .importzp tmp1,tmp2,tmp3,ptr4,spc + .importzp tmp1,tmp2,tmp3,ptr4,c_sp .import fd_table,fd_index .import fdt_to_fdi .export clriocb @@ -229,7 +229,7 @@ freefnd:txa beq l2 l1: ldy #0 - lda (spc),y ; get device + lda (c_sp),y ; get device l2: sta fd_table+ft_dev,x ; set device lda #1 sta fd_table+ft_usa,x ; set usage counter diff --git a/libsrc/atari/mcbpm.s b/libsrc/atari/mcbpm.s index 361af145e..bc36b6f99 100644 --- a/libsrc/atari/mcbpm.s +++ b/libsrc/atari/mcbpm.s @@ -8,7 +8,7 @@ ; .include "atari.inc" - .importzp spc + .importzp c_sp .export _mouse_pm_callbacks .constructor pm_init, 27 .destructor pm_down @@ -193,22 +193,22 @@ pm_init: .else -; use top of memory and lower spc accordingly - sta spc +; use top of memory and lower c_sp accordingly + sta c_sp sta MOUSE_PM_BASE - lda spc+1 + lda c_sp+1 and #7 ; offset within 2K cmp #3 + MOUSE_PM_RAW + 1 ; can we use it? bcc @decr ; no - lda spc+1 + lda c_sp+1 and #$F8 @set: adc #3 + MOUSE_PM_RAW - 1 ; CF is set, so adding MOUSE_PM_RAW + 3 sta MOUSE_PM_BASE+1 - sta spc+1 + sta c_sp+1 bne @cont ; jump always -@decr: lda spc+1 +@decr: lda c_sp+1 and #$F8 sbc #8 - 1 ; CF is clear, subtracts 8 bcs @set ; jump always diff --git a/libsrc/atari/mou/atrjoy.s b/libsrc/atari/mou/atrjoy.s index 425e1176a..f30d72050 100644 --- a/libsrc/atari/mou/atrjoy.s +++ b/libsrc/atari/mou/atrjoy.s @@ -241,11 +241,11 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (spc),y + lda (c_sp),y sta XPos+1 tax dey - lda (spc),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/atari/mou/atrst.s b/libsrc/atari/mou/atrst.s index 4a3b87f5c..7f915cc36 100644 --- a/libsrc/atari/mou/atrst.s +++ b/libsrc/atari/mou/atrst.s @@ -399,12 +399,12 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (spc),y + lda (c_sp),y sta XPos+1 sta XPosWrk+1 tax dey - lda (spc),y + lda (c_sp),y sta XPos ; New X position sta XPosWrk jsr CMOVEX ; Move the cursor diff --git a/libsrc/atari/mou/atrtt.s b/libsrc/atari/mou/atrtt.s index 9870096fe..516565844 100644 --- a/libsrc/atari/mou/atrtt.s +++ b/libsrc/atari/mou/atrtt.s @@ -236,11 +236,11 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (spc),y + lda (c_sp),y sta XPos+1 tax dey - lda (spc),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/atari/sysrename.s b/libsrc/atari/sysrename.s index f71ec5bb5..b410ebcfd 100644 --- a/libsrc/atari/sysrename.s +++ b/libsrc/atari/sysrename.s @@ -6,7 +6,7 @@ .include "atari.inc" .import findfreeiocb - .importzp tmp4, spc, ptr2, ptr3 + .importzp tmp4, c_sp, ptr2, ptr3 .import incsp2, subysp, addysp, popax .ifdef UCASE_FILENAME .importzp tmp3 @@ -118,19 +118,19 @@ L1: jsr subysp ; make room on the stack ; copy old name ldy #0 con: lda (ptr3),y - sta (spc),y + sta (c_sp),y beq copyend iny bne con copyend:lda #$20 ; space - sta (spc),y + sta (c_sp),y iny tya ; get current offset (beyond old name) clc - adc spc + adc c_sp sta ptr3 - lda spc+1 + lda c_sp+1 adc #0 sta ptr3+1 ; ptr3 now contains pointer to space for new filename @@ -143,9 +143,9 @@ cnn: lda (ptr2),y bne cnn copend2:ldx tmp4 - lda spc + lda c_sp sta ICBAL,x - lda spc+1 + lda c_sp+1 sta ICBAH,x lda #RENAME sta ICCOM,x @@ -160,13 +160,13 @@ copend2:ldx tmp4 ; clean up stack - lda spc + lda c_sp clc adc sspc - sta spc - lda spc+1 + sta c_sp + lda c_sp+1 adc sspc+1 - sta spc+1 + sta c_sp+1 ; handle status diff --git a/libsrc/atari/ucase_fn.s b/libsrc/atari/ucase_fn.s index bec17e18e..d67fa36e5 100644 --- a/libsrc/atari/ucase_fn.s +++ b/libsrc/atari/ucase_fn.s @@ -24,7 +24,7 @@ .importzp tmp2 .import __defdev .endif - .importzp tmp3,ptr4,spc + .importzp tmp3,ptr4,c_sp .import subysp,addysp .export ucase_fn @@ -63,13 +63,13 @@ hasdev: ldy #0 loop2: lda (ptr4),y - sta (spc),y + sta (c_sp),y beq copy_end bmi L1 ; Not lowercase (also, invalid, should reject) cmp #'a' bcc L1 ; Not lowercase and #$DF ; make upper case char, assume ASCII chars - sta (spc),y ; store back + sta (c_sp),y ; store back L1: iny bpl loop2 ; bpl: this way we only support a max. length of 127 @@ -93,15 +93,15 @@ copy_end: jsr subysp ; adjust stack pointer dey cpdev: lda __defdev,y - sta (spc),y ; insert device name, number and ':' + sta (c_sp),y ; insert device name, number and ':' dey bpl cpdev hasdev2: .endif ; leave A and X pointing to the modified filename - lda spc - ldx spc+1 + lda c_sp + ldx c_sp+1 clc ; indicate success rts diff --git a/libsrc/atari2600/crt0.s b/libsrc/atari2600/crt0.s index b6ebd5db5..7b5b679b0 100644 --- a/libsrc/atari2600/crt0.s +++ b/libsrc/atari2600/crt0.s @@ -35,8 +35,8 @@ clearLoop: ; Initialize C stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) ldx #>(__RAM_START__ + __RAM_SIZE__) - sta spc - stx spc+1 + sta c_sp + stx c_sp+1 ; Call main jsr _main diff --git a/libsrc/atari5200/crt0.s b/libsrc/atari5200/crt0.s index 6c28874ff..b0b0738a0 100644 --- a/libsrc/atari5200/crt0.s +++ b/libsrc/atari5200/crt0.s @@ -27,8 +27,8 @@ start: lda #<(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__) ldx #>(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__) - sta spc - stx spc+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/atari7800/crt0.s b/libsrc/atari7800/crt0.s index 5a372eb0e..dea351473 100644 --- a/libsrc/atari7800/crt0.s +++ b/libsrc/atari7800/crt0.s @@ -30,9 +30,9 @@ start: ; Set up parameter stack lda #<(__RAM3_START__ + __RAM3_SIZE__) - sta spc + sta c_sp lda #>(__RAM3_START__ + __RAM3_SIZE__) - sta spc+1 + sta c_sp+1 jsr copydata jsr zerobss diff --git a/libsrc/atari7800/mono_setcursor.s b/libsrc/atari7800/mono_setcursor.s index 2136a7440..995f0d661 100644 --- a/libsrc/atari7800/mono_setcursor.s +++ b/libsrc/atari7800/mono_setcursor.s @@ -27,7 +27,7 @@ .constructor mono_init_cursor .interruptor mono_blink_cursor - .importzp spc + .importzp c_sp .import _zonecounter .import _mono_zones .import cursor diff --git a/libsrc/atari7800/setcursor.s b/libsrc/atari7800/setcursor.s index dabb8e984..040732cff 100644 --- a/libsrc/atari7800/setcursor.s +++ b/libsrc/atari7800/setcursor.s @@ -27,7 +27,7 @@ .constructor init_cursor .interruptor blink_cursor - .importzp spc + .importzp c_sp .import _zonecounter .import _zones .import cursor diff --git a/libsrc/atmos/crt0.s b/libsrc/atmos/crt0.s index 332002a3a..05137193c 100644 --- a/libsrc/atmos/crt0.s +++ b/libsrc/atmos/crt0.s @@ -51,7 +51,7 @@ _exit: jsr donelib ldx #zpspace - 1 L2: lda zpsave,x - sta spc,x + sta c_sp,x dex bpl L2 @@ -68,7 +68,7 @@ L2: lda zpsave,x ; Save the zero-page area that we're about to use. init: ldx #zpspace - 1 -L1: lda spc,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -85,8 +85,8 @@ L1: lda spc,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta spc - stx spc+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/c128/crt0.s b/libsrc/c128/crt0.s index 2517d991c..b54533864 100644 --- a/libsrc/c128/crt0.s +++ b/libsrc/c128/crt0.s @@ -39,7 +39,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda spc,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -58,8 +58,8 @@ L1: lda spc,x lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta spc - stx spc+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. @@ -85,7 +85,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta spc,x + sta c_sp,x dex bpl L2 diff --git a/libsrc/c128/mou/c128-1351.s b/libsrc/c128/mou/c128-1351.s index a9237a6cb..f6954c823 100644 --- a/libsrc/c128/mou/c128-1351.s +++ b/libsrc/c128/mou/c128-1351.s @@ -296,11 +296,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (spc),y + lda (c_sp),y sta XPos+1 tax dey - lda (spc),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c128/mou/c128-inkwell.s b/libsrc/c128/mou/c128-inkwell.s index b7cf54490..b86959788 100644 --- a/libsrc/c128/mou/c128-inkwell.s +++ b/libsrc/c128/mou/c128-inkwell.s @@ -323,10 +323,10 @@ MOVE: sei ; No interrupts jsr MoveY ldy #$01 - lda (spc),y + lda (c_sp),y tax dey - lda (spc),y + lda (c_sp),y jsr MoveX ; Move the cursor cli ; Allow interrupts diff --git a/libsrc/c128/mou/c128-joy.s b/libsrc/c128/mou/c128-joy.s index d1e45bc1e..26367f8df 100644 --- a/libsrc/c128/mou/c128-joy.s +++ b/libsrc/c128/mou/c128-joy.s @@ -297,11 +297,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (spc),y + lda (c_sp),y sta XPos+1 tax dey - lda (spc),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c128/mou/c128-pot.s b/libsrc/c128/mou/c128-pot.s index 596ec6041..55de4ac12 100644 --- a/libsrc/c128/mou/c128-pot.s +++ b/libsrc/c128/mou/c128-pot.s @@ -297,11 +297,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (spc),y + lda (c_sp),y sta XPos+1 tax dey - lda (spc),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c16/crt0.s b/libsrc/c16/crt0.s index 2dc73c7e5..491000e52 100644 --- a/libsrc/c16/crt0.s +++ b/libsrc/c16/crt0.s @@ -24,7 +24,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda spc,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -49,8 +49,8 @@ L1: lda spc,x bcc MemOk ldy #$80 ldx #$00 -MemOk: stx spc - sty spc+1 ; set argument stack ptr +MemOk: stx c_sp + sty c_sp+1 ; set argument stack ptr ; Call the module constructors. @@ -69,7 +69,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta spc,x + sta c_sp,x dex bpl L2 diff --git a/libsrc/c64/crt0.s b/libsrc/c64/crt0.s index e8aaaf8c6..9e0162513 100644 --- a/libsrc/c64/crt0.s +++ b/libsrc/c64/crt0.s @@ -55,7 +55,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta spc,x + sta c_sp,x dex bpl L2 @@ -85,7 +85,7 @@ init: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda spc,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -94,8 +94,8 @@ L1: lda spc,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta spc - stx spc+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Switch to the second charset. diff --git a/libsrc/c64/mou/c64-1351.s b/libsrc/c64/mou/c64-1351.s index d49037479..dcf949730 100644 --- a/libsrc/c64/mou/c64-1351.s +++ b/libsrc/c64/mou/c64-1351.s @@ -239,11 +239,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (spc),y + lda (c_sp),y sta XPos+1 tax dey - lda (spc),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c64/mou/c64-inkwell.s b/libsrc/c64/mou/c64-inkwell.s index 4be817db3..68941260c 100644 --- a/libsrc/c64/mou/c64-inkwell.s +++ b/libsrc/c64/mou/c64-inkwell.s @@ -249,10 +249,10 @@ MOVE: sei ; No interrupts jsr MoveY ldy #$01 - lda (spc),y + lda (c_sp),y tax dey - lda (spc),y + lda (c_sp),y jsr MoveX ; Move the cursor cli ; Allow interrupts diff --git a/libsrc/c64/mou/c64-joy.s b/libsrc/c64/mou/c64-joy.s index 558b43c07..901b9c42d 100644 --- a/libsrc/c64/mou/c64-joy.s +++ b/libsrc/c64/mou/c64-joy.s @@ -245,11 +245,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (spc),y + lda (c_sp),y sta XPos+1 tax dey - lda (spc),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c64/mou/c64-pot.s b/libsrc/c64/mou/c64-pot.s index 8147bb333..1728913e1 100644 --- a/libsrc/c64/mou/c64-pot.s +++ b/libsrc/c64/mou/c64-pot.s @@ -230,11 +230,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (spc),y + lda (c_sp),y sta XPos+1 tax dey - lda (spc),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/cbm/dir.s b/libsrc/cbm/dir.s index c8057cf93..a78fc94a5 100644 --- a/libsrc/cbm/dir.s +++ b/libsrc/cbm/dir.s @@ -44,10 +44,10 @@ __dirread: ; Replace dir by dir->fd ldy #2 - lda (spc),y + lda (c_sp),y sta ptr1 iny - lda (spc),y + lda (c_sp),y sta ptr1+1 ldy #DIR::fd+1 lda (ptr1),y @@ -55,10 +55,10 @@ __dirread: dey lda (ptr1),y ldy #2 - sta (spc),y + sta (c_sp),y pla iny - sta (spc),y + sta (c_sp),y ; Get count, save it again, clear the high byte and call read(). By the ; previous actions, the stack frame is as read() needs it, and read() will diff --git a/libsrc/cbm/open.s b/libsrc/cbm/open.s index 16c71e02e..bf937ee0f 100644 --- a/libsrc/cbm/open.s +++ b/libsrc/cbm/open.s @@ -12,7 +12,7 @@ .import opencmdchannel, closecmdchannel, readdiskerror .import fnunit, fnisfile .import _close - .importzp spc, tmp2, tmp3 + .importzp c_sp, tmp2, tmp3 .include "errno.inc" .include "fcntl.inc" diff --git a/libsrc/cbm/write.s b/libsrc/cbm/write.s index a699c691c..43c7582f0 100644 --- a/libsrc/cbm/write.s +++ b/libsrc/cbm/write.s @@ -8,7 +8,7 @@ .constructor initstdout .import rwcommon - .importzp spc, ptr1, ptr2, ptr3 + .importzp c_sp, ptr1, ptr2, ptr3 .include "cbm.inc" .include "errno.inc" diff --git a/libsrc/cbm510/crt0.s b/libsrc/cbm510/crt0.s index 0731673b3..80d587ff5 100644 --- a/libsrc/cbm510/crt0.s +++ b/libsrc/cbm510/crt0.s @@ -117,7 +117,7 @@ entry: php tya sec sbc #7 - sta $1FF ; Save new spc + sta $1FF ; Save new c_sp tay tsx @@ -145,7 +145,7 @@ entry: php iny sta (sysp1),y - ldy $1FF ; Restore spc in bank 15 + ldy $1FF ; Restore c_sp in bank 15 lda #.hibyte(expull-1) sta (sysp1),y @@ -245,7 +245,7 @@ L1: lda extzp,x dex bpl L1 -; Save the old stack pointer from the system bank; and, set up our hw spc. +; Save the old stack pointer from the system bank; and, set up our hw c_sp. tsx txa @@ -279,9 +279,9 @@ L3: lda vectors,x ; Set up the C stack. lda #.lobyte(callbank15::entry) - sta spc + sta c_sp lda #.hibyte(callbank15::entry) - sta spc+1 + sta c_sp+1 ; Set up the subroutine and jump vector table that redirects Kernal calls to ; the system bank. @@ -495,7 +495,7 @@ _exit: pha ; Save the return code on stack ; Set up the welcome code at the stack bottom in the system bank. ldy #$FF - lda (sysp1),y ; Load system bank spc + lda (sysp1),y ; Load system bank c_sp tax iny ; Y = 0 lda #$58 ; CLI opcode diff --git a/libsrc/cbm510/mou/cbm510-inkwl.s b/libsrc/cbm510/mou/cbm510-inkwl.s index e6e239fbd..e5328cf75 100644 --- a/libsrc/cbm510/mou/cbm510-inkwl.s +++ b/libsrc/cbm510/mou/cbm510-inkwl.s @@ -256,10 +256,10 @@ MOVE: sei ; No interrupts jsr MoveY ldy #$01 - lda (spc),y + lda (c_sp),y tax dey - lda (spc),y + lda (c_sp),y jsr MoveX ; Move the cursor cli ; Allow interrupts diff --git a/libsrc/cbm510/mou/cbm510-joy.s b/libsrc/cbm510/mou/cbm510-joy.s index f974c112f..912842be7 100644 --- a/libsrc/cbm510/mou/cbm510-joy.s +++ b/libsrc/cbm510/mou/cbm510-joy.s @@ -225,11 +225,11 @@ MOVE: sei ; No interrupts jsr MoveY ; Set new y position ldy #1 - lda (spc),y + lda (c_sp),y sta XPos+1 tax dey - lda (spc),y + lda (c_sp),y jsr MoveX ; Move the pointer cli ; Allow interrupts diff --git a/libsrc/cbm610/crt0.s b/libsrc/cbm610/crt0.s index 814dbbdac..dc56fa2de 100644 --- a/libsrc/cbm610/crt0.s +++ b/libsrc/cbm610/crt0.s @@ -115,7 +115,7 @@ entry: php tya sec sbc #7 - sta $1FF ; Save new spc + sta $1FF ; Save new c_sp tay tsx @@ -143,7 +143,7 @@ entry: php iny sta (sysp1),y - ldy $1FF ; Restore spc in bank 15 + ldy $1FF ; Restore c_sp in bank 15 lda #.hibyte(expull-1) sta (sysp1),y @@ -243,7 +243,7 @@ L1: lda extzp,x dex bpl L1 -; Save the old stack pointer from the system bank; and, set up our hw spc. +; Save the old stack pointer from the system bank; and, set up our hw c_sp. tsx txa @@ -277,9 +277,9 @@ L3: lda vectors,x ; Set up the C stack. lda #.lobyte(callbank15::entry) - sta spc + sta c_sp lda #.hibyte(callbank15::entry) - sta spc+1 + sta c_sp+1 ; Set up the subroutine and jump vector table that redirects Kernal calls to ; the system bank. @@ -400,7 +400,7 @@ _exit: pha ; Save the return code ; Set up the welcome code at the stack bottom in the system bank. ldy #$FF - lda (sysp1),y ; Load system bank spc + lda (sysp1),y ; Load system bank c_sp tax iny ; Y = 0 lda #$58 ; CLI opcode diff --git a/libsrc/common/_fopen.s b/libsrc/common/_fopen.s index 3959ff1a7..0c234097e 100644 --- a/libsrc/common/_fopen.s +++ b/libsrc/common/_fopen.s @@ -9,7 +9,7 @@ .import _open .import pushax, incsp4, return0 - .importzp spc, ptr1 + .importzp c_sp, ptr1 .include "errno.inc" @@ -28,10 +28,10 @@ ; Get a pointer to the mode string ldy #1 - lda (spc),y + lda (c_sp),y sta ptr1+1 dey - lda (spc),y + lda (c_sp),y sta ptr1 ; Look at the first character in mode @@ -78,10 +78,10 @@ invmode: modeok: ldy #$00 txa ; Mode -> A - sta (spc),y + sta (c_sp),y tya iny - sta (spc),y + sta (c_sp),y ldy #4 ; Size of arguments in bytes jsr _open ; Will cleanup the stack diff --git a/libsrc/common/_heap.s b/libsrc/common/_heap.s index aa609a7a1..e5d71d1be 100644 --- a/libsrc/common/_heap.s +++ b/libsrc/common/_heap.s @@ -6,7 +6,7 @@ .constructor initheap, 24 .import __BSS_RUN__, __BSS_SIZE__, __STACKSIZE__ - .importzp spc + .importzp c_sp .include "_heap.inc" @@ -31,10 +31,10 @@ ___heaplast: initheap: sec - lda spc + lda c_sp sbc #<__STACKSIZE__ sta ___heapend - lda spc+1 + lda c_sp+1 sbc #>__STACKSIZE__ sta ___heapend+1 rts diff --git a/libsrc/common/_idiv32by16r16.s b/libsrc/common/_idiv32by16r16.s index 6884bcf7e..9534f751f 100644 --- a/libsrc/common/_idiv32by16r16.s +++ b/libsrc/common/_idiv32by16r16.s @@ -20,17 +20,17 @@ ; Copy from stack to zeropage. This assumes ptr1 and ptr2 are adjacent. ldy #3 -@L1: lda (spc),y +@L1: lda (c_sp),y sta ptr1,y dey bpl @L1 lda #4 clc - adc spc - sta spc + adc c_sp + sta c_sp bcc @L2 - inc spc+1 + inc c_sp+1 @L2: pla ; Old rhs jmp idiv32by16r16 diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index 3b445f5e7..40ab0bc64 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -338,25 +338,25 @@ MainLoop: jsr decsp6 ; 3 args ldy #5 lda OutData+1 - sta (spc),y + sta (c_sp),y dey lda OutData - sta (spc),y + sta (c_sp),y dey lda FSave+1 - sta (spc),y + sta (c_sp),y dey lda FSave - sta (spc),y + sta (c_sp),y dey lda FCount+1 - sta (spc),y + sta (c_sp),y dey lda FCount .if (.cpu .bitand ::CPU_ISET_65SC02) - sta (spc) + sta (c_sp) .else - sta (spc),y + sta (c_sp),y .endif jsr CallOutFunc ; Call the output function diff --git a/libsrc/common/_udiv32by16r16.s b/libsrc/common/_udiv32by16r16.s index 452fcba50..987390c04 100644 --- a/libsrc/common/_udiv32by16r16.s +++ b/libsrc/common/_udiv32by16r16.s @@ -21,17 +21,17 @@ ; Copy from stack to zeropage. This assumes ptr1 and ptr2 are adjacent. ldy #3 -@L1: lda (spc),y +@L1: lda (c_sp),y sta ptr1,y dey bpl @L1 lda #4 clc - adc spc - sta spc + adc c_sp + sta c_sp bcc @L2 - inc spc+1 + inc c_sp+1 @L2: jmp udiv32by16r16m diff --git a/libsrc/common/fprintf.s b/libsrc/common/fprintf.s index 21e30121e..af9a58ebc 100644 --- a/libsrc/common/fprintf.s +++ b/libsrc/common/fprintf.s @@ -6,7 +6,7 @@ .export _fprintf .import addysp, decsp4, _vfprintf - .importzp spc, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -38,9 +38,9 @@ _fprintf: ; Calculate a pointer to the Format argument lda ParamSize - add spc + add c_sp sta ptr1 - ldx spc+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 @@ -49,7 +49,7 @@ _fprintf: ldy #4-1 @L2: lda (ptr1),y - sta (spc),y + sta (c_sp),y dey bpl @L2 diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index 81c401bf3..2dc9ad936 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -14,7 +14,7 @@ .import pushwysp .import tosumulax, tosudivax - .importzp ptr1, spc + .importzp ptr1, c_sp .include "errno.inc" .include "_file.inc" @@ -136,23 +136,23 @@ ; to read() by one, so read() starts to store data at buf+1. .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (spc) + lda (c_sp) sta ptr1 add #1 - sta (spc) + sta (c_sp) ldy #1 .else ldy #0 - lda (spc),y + lda (c_sp),y sta ptr1 add #1 - sta (spc),y + sta (c_sp),y iny .endif - lda (spc),y + lda (c_sp),y sta ptr1+1 adc #0 - sta (spc),y ; ptr1 = buf++; + sta (c_sp),y ; ptr1 = buf++; ; Get the buffered character and place it as first character into the read ; buffer. diff --git a/libsrc/common/fscanf.s b/libsrc/common/fscanf.s index 1af61c4cb..c687a0624 100644 --- a/libsrc/common/fscanf.s +++ b/libsrc/common/fscanf.s @@ -6,7 +6,7 @@ .export _fscanf .import addysp, decsp4, _vfscanf - .importzp spc, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -50,9 +50,9 @@ _fscanf: ; Calculate a pointer to the Format argument lda ParamSize - add spc + add c_sp sta ptr1 - ldx spc+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 @@ -61,7 +61,7 @@ _fscanf: ldy #4-1 @L2: lda (ptr1),y - sta (spc),y + sta (c_sp),y dey bpl @L2 diff --git a/libsrc/common/interrupt.s b/libsrc/common/interrupt.s index 5a53a2dd8..a67d51fda 100644 --- a/libsrc/common/interrupt.s +++ b/libsrc/common/interrupt.s @@ -93,8 +93,8 @@ zpsave: .res zpsavespace ; Set C level interrupt stack lda irqsp ldx irqsp+1 - sta spc - stx spc+1 + sta c_sp + stx c_sp+1 ; Call C level interrupt request handler jsr irqvec diff --git a/libsrc/common/itoa.s b/libsrc/common/itoa.s index 02e2b8f9e..a1cd53c8b 100644 --- a/libsrc/common/itoa.s +++ b/libsrc/common/itoa.s @@ -8,7 +8,7 @@ .export _itoa, _utoa .import addysp1 .import __hextab - .importzp spc, sreg, ptr2, ptr3, tmp1 + .importzp c_sp, sreg, ptr2, ptr3, tmp1 .rodata specval: @@ -21,18 +21,18 @@ specval: dopop: sta tmp1 ; will lose high byte ldy #0 - lda (spc),y + lda (c_sp),y sta ptr2 sta ptr3 iny - lda (spc),y + lda (c_sp),y sta ptr2+1 sta ptr3+1 iny - lda (spc),y + lda (c_sp),y sta sreg iny - lda (spc),y + lda (c_sp),y sta sreg+1 jmp addysp1 ; Bump stack pointer diff --git a/libsrc/common/longjmp.s b/libsrc/common/longjmp.s index a4508569f..8855286a9 100644 --- a/libsrc/common/longjmp.s +++ b/libsrc/common/longjmp.s @@ -7,7 +7,7 @@ .export _longjmp .import popptr1 - .importzp spc, ptr1, ptr2 + .importzp c_sp, ptr1, ptr2 _longjmp: sta ptr2 ; Save retval @@ -23,10 +23,10 @@ _longjmp: lda (ptr1),y iny - sta spc + sta c_sp lda (ptr1),y iny - sta spc+1 + sta c_sp+1 ; Get the old stack pointer diff --git a/libsrc/common/lz4.s b/libsrc/common/lz4.s index ebedcc1e3..5d26cb56a 100644 --- a/libsrc/common/lz4.s +++ b/libsrc/common/lz4.s @@ -61,7 +61,7 @@ ; } ; } - .importzp spc, sreg, regsave, regbank + .importzp c_sp, sreg, regsave, regbank .importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 .macpack longbranch .import memcpy_upwards,pushax,popax diff --git a/libsrc/common/memcpy.s b/libsrc/common/memcpy.s index 0cbb7d4a5..e9c3f1968 100644 --- a/libsrc/common/memcpy.s +++ b/libsrc/common/memcpy.s @@ -12,7 +12,7 @@ .export _memcpy, memcpy_upwards, memcpy_getparams .import popax, popptr1 - .importzp spc, ptr1, ptr2, ptr3 + .importzp c_sp, ptr1, ptr2, ptr3 ; ---------------------------------------------------------------------- _memcpy: @@ -70,10 +70,10 @@ memcpy_getparams: ; IMPORTANT! Function has to leave with Y=0! iny ; Y=0 guaranteed by popptr1, we need '1' here... ; (direct stack access is three cycles faster ; (total cycle count with return)) - lda (spc),y + lda (c_sp),y tax stx ptr2+1 ; save high byte of ptr2 dey ; Y = 0 - lda (spc),y ; Get ptr2 low + lda (c_sp),y ; Get ptr2 low sta ptr2 rts diff --git a/libsrc/common/memset.s b/libsrc/common/memset.s index 6241d7800..13e8ece9f 100644 --- a/libsrc/common/memset.s +++ b/libsrc/common/memset.s @@ -17,7 +17,7 @@ .export _memset, _bzero, ___bzero .import popax - .importzp spc, ptr1, ptr2, ptr3 + .importzp c_sp, ptr1, ptr2, ptr3 _bzero: ___bzero: @@ -36,10 +36,10 @@ _memset: common: ; Fill value is in X! ldy #1 - lda (spc),y + lda (c_sp),y sta ptr1+1 ; save high byte of ptr dey ; Y = 0 - lda (spc),y ; Get ptr + lda (c_sp),y ; Get ptr sta ptr1 lsr ptr3+1 ; divide number of diff --git a/libsrc/common/printf.s b/libsrc/common/printf.s index 1ad909eff..76e08e584 100644 --- a/libsrc/common/printf.s +++ b/libsrc/common/printf.s @@ -6,7 +6,7 @@ .export _printf .import _stdout, pushax, addysp, _vfprintf - .importzp spc, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -43,8 +43,8 @@ _printf: ; Now calculate the va_list pointer, which does points to Format - lda spc - ldx spc+1 + lda c_sp + ldx c_sp+1 add ParamSize bcc @L1 inx diff --git a/libsrc/common/realloc.s b/libsrc/common/realloc.s index eca1d3d0e..16d5eea41 100644 --- a/libsrc/common/realloc.s +++ b/libsrc/common/realloc.s @@ -4,7 +4,7 @@ ; void* __fastcall__ realloc (void* block, register size_t size) ; - .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4, spc + .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4, c_sp .import _malloc, _memcpy, _free .import pushax, popptr1, return0 .import incsp2, decsp2 diff --git a/libsrc/common/scanf.s b/libsrc/common/scanf.s index a5f3937a8..92460b629 100644 --- a/libsrc/common/scanf.s +++ b/libsrc/common/scanf.s @@ -8,7 +8,7 @@ .export _scanf .import _stdin, pushax, addysp, _vfscanf - .import spc:zp, ptr1:zp + .import c_sp:zp, ptr1:zp .macpack generic @@ -34,8 +34,8 @@ _scanf: ; Now, calculate the va_list pointer, which does point to Format. - lda spc - ldx spc+1 + lda c_sp + ldx c_sp+1 add ArgSize bcc @L1 inx diff --git a/libsrc/common/setjmp.s b/libsrc/common/setjmp.s index d32200c3d..3c0b8aa17 100644 --- a/libsrc/common/setjmp.s +++ b/libsrc/common/setjmp.s @@ -8,7 +8,7 @@ .export ___setjmp .import return0 - .importzp spc, ptr1 + .importzp c_sp, ptr1 ___setjmp: sta ptr1 ; Save buf @@ -17,10 +17,10 @@ ___setjmp: ; The parameter stack is now empty, put it into buf - lda spc + lda c_sp sta (ptr1),y iny - lda spc+1 + lda c_sp+1 sta (ptr1),y iny diff --git a/libsrc/common/snprintf.s b/libsrc/common/snprintf.s index f924453df..c922a55bc 100644 --- a/libsrc/common/snprintf.s +++ b/libsrc/common/snprintf.s @@ -6,7 +6,7 @@ .export _snprintf .import pushax, addysp, decsp6, _vsnprintf - .importzp spc, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -38,9 +38,9 @@ _snprintf: ; Calculate a pointer to the Format argument lda ParamSize - add spc + add c_sp sta ptr1 - ldx spc+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 @@ -49,7 +49,7 @@ _snprintf: ldy #6-1 @L2: lda (ptr1),y - sta (spc),y + sta (c_sp),y dey bpl @L2 diff --git a/libsrc/common/sprintf.s b/libsrc/common/sprintf.s index feec141e5..d2ce6602e 100644 --- a/libsrc/common/sprintf.s +++ b/libsrc/common/sprintf.s @@ -6,7 +6,7 @@ .export _sprintf .import pushax, addysp, decsp4, _vsprintf - .importzp spc, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -38,9 +38,9 @@ _sprintf: ; Calculate a pointer to the Format argument lda ParamSize - add spc + add c_sp sta ptr1 - ldx spc+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 @@ -49,7 +49,7 @@ _sprintf: ldy #4-1 @L2: lda (ptr1),y - sta (spc),y + sta (c_sp),y dey bpl @L2 diff --git a/libsrc/common/sscanf.s b/libsrc/common/sscanf.s index 6542116ae..d393087d8 100644 --- a/libsrc/common/sscanf.s +++ b/libsrc/common/sscanf.s @@ -6,7 +6,7 @@ .export _sscanf .import addysp, decsp4, _vsscanf - .importzp spc, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -51,9 +51,9 @@ _sscanf: ; Calculate a pointer to the fixed parameters lda ParamSize - add spc + add c_sp sta ptr1 - ldx spc+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 @@ -62,7 +62,7 @@ _sscanf: ldy #4-1 @L2: lda (ptr1),y - sta (spc),y + sta (c_sp),y dey bpl @L2 diff --git a/libsrc/common/vfprintf.s b/libsrc/common/vfprintf.s index 4b941af9b..65bf62a22 100644 --- a/libsrc/common/vfprintf.s +++ b/libsrc/common/vfprintf.s @@ -8,7 +8,7 @@ .export _vfprintf .import push1, pushwysp, incsp6 .import _fwrite, __printf - .importzp spc, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -121,15 +121,15 @@ _vfprintf: ; exactly as _printf expects it. Parameters will get dropped by _printf. ldy #2 - lda (spc),y ; Low byte of f + lda (c_sp),y ; Low byte of f sta ptr lda #<outdesc - sta (spc),y + sta (c_sp),y iny - lda (spc),y ; High byte of f + lda (c_sp),y ; High byte of f sta ptr+1 lda #>outdesc - sta (spc),y + sta (c_sp),y ; Restore low byte of ap and call _printf diff --git a/libsrc/common/vfscanf.s b/libsrc/common/vfscanf.s index 2324f30a4..71d7c634c 100644 --- a/libsrc/common/vfscanf.s +++ b/libsrc/common/vfscanf.s @@ -61,16 +61,16 @@ _vfscanf: ; Swap f against &d on the stack, placing f into d.data ldy #2 ; Offset of f on the stack - lda (spc),y + lda (c_sp),y sta d + SCANFDATA::DATA lda #<d - sta (spc),y + sta (c_sp),y iny ; High byte - lda (spc),y + lda (c_sp),y sta d + SCANFDATA::DATA + 1 lda #>d - sta (spc),y + sta (c_sp),y ; Restore the low byte of ap, and call the _scanf function diff --git a/libsrc/common/vprintf.s b/libsrc/common/vprintf.s index fbfeb9951..1c44b61ef 100644 --- a/libsrc/common/vprintf.s +++ b/libsrc/common/vprintf.s @@ -7,7 +7,7 @@ .export _vprintf .import _vfprintf, _stdout .import decsp2 - .importzp spc + .importzp c_sp .proc _vprintf @@ -23,20 +23,20 @@ ; Move the format parameter down and store stdout in it's place ldy #2 - lda (spc),y + lda (c_sp),y ldy #0 - sta (spc),y + sta (c_sp),y ldy #3 - lda (spc),y + lda (c_sp),y ldy #1 - sta (spc),y + sta (c_sp),y iny lda _stdout - sta (spc),y + sta (c_sp),y iny lda _stdout+1 - sta (spc),y + sta (c_sp),y ; Restore A diff --git a/libsrc/common/vscanf.s b/libsrc/common/vscanf.s index f6a34c34d..1681acd97 100644 --- a/libsrc/common/vscanf.s +++ b/libsrc/common/vscanf.s @@ -31,22 +31,22 @@ _vscanf: ; Move the format down ldy #2 - lda (spc),y ; Load byte of format + lda (c_sp),y ; Load byte of format ldy #0 - sta (spc),y + sta (c_sp),y ldy #3 - lda (spc),y + lda (c_sp),y ldy #1 - sta (spc),y + sta (c_sp),y ; Store stdin into the stack frame iny lda _stdin - sta (spc),y + sta (c_sp),y iny lda _stdin+1 - sta (spc),y + sta (c_sp),y ; Restore the low byte of ap and jump to vfscanf, which will cleanup the stack diff --git a/libsrc/common/vsnprintf.s b/libsrc/common/vsnprintf.s index e1bd1e80d..780ab10ee 100644 --- a/libsrc/common/vsnprintf.s +++ b/libsrc/common/vsnprintf.s @@ -8,7 +8,7 @@ .export _vsnprintf, vsnprintf .import ldaxysp, popax, incsp2, incsp6 .import _memcpy, __printf - .importzp spc, ptr1 + .importzp c_sp, ptr1 .include "errno.inc" @@ -55,19 +55,19 @@ vsnprintf: ; be formatted and counted. ldy #2 - lda (spc),y + lda (c_sp),y sta ptr1 lda #<outdesc - sta (spc),y + sta (c_sp),y iny - lda (spc),y + lda (c_sp),y bmi L9 ; More than $7FFF sta ptr1+1 lda #>outdesc - sta (spc),y + sta (c_sp),y ; Write size-1 to outdesc.uns. It will be -1 if there is no buffer. @@ -178,12 +178,12 @@ out: clc adc ccount+0 ldy #4 - sta (spc),y + sta (c_sp),y lda bufptr+1 adc ccount+1 iny - sta (spc),y + sta (c_sp),y ; Get Count from stack diff --git a/libsrc/common/vsscanf.s b/libsrc/common/vsscanf.s index 9e261389c..2061861dc 100644 --- a/libsrc/common/vsscanf.s +++ b/libsrc/common/vsscanf.s @@ -9,7 +9,7 @@ .export _vsscanf .import popax, __scanf - .importzp spc, ptr1, ptr2 + .importzp c_sp, ptr1, ptr2 .macpack generic @@ -165,15 +165,15 @@ d: .addr get ; to d ldy #2 ; Stack offset of str - lda (spc),y + lda (c_sp),y sta sd + SSCANFDATA::STR lda #<d - sta (spc),y + sta (c_sp),y iny - lda (spc),y + lda (c_sp),y sta sd + SSCANFDATA::STR+1 lda #>d - sta (spc),y + sta (c_sp),y lda #$00 sta sd + SSCANFDATA::INDEX diff --git a/libsrc/conio/cprintf.s b/libsrc/conio/cprintf.s index 64bdf9d3c..80bca2308 100644 --- a/libsrc/conio/cprintf.s +++ b/libsrc/conio/cprintf.s @@ -6,7 +6,7 @@ .export _cprintf .import pushax, addysp, _vcprintf - .importzp spc, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -31,9 +31,9 @@ _cprintf: dey dey ; Sub size of Format tya - add spc + add c_sp sta ptr1 - ldx spc+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 diff --git a/libsrc/conio/cscanf.s b/libsrc/conio/cscanf.s index 5d575185e..7ee532626 100644 --- a/libsrc/conio/cscanf.s +++ b/libsrc/conio/cscanf.s @@ -23,8 +23,8 @@ _cscanf: ; Now, calculate the va_list pointer -- which points to format. - ldx spc+1 - add spc + ldx c_sp+1 + add c_sp bcc @L1 inx @L1: sta ptr1 diff --git a/libsrc/conio/vcprintf.s b/libsrc/conio/vcprintf.s index 677a9f5fd..c6371f00e 100644 --- a/libsrc/conio/vcprintf.s +++ b/libsrc/conio/vcprintf.s @@ -7,7 +7,7 @@ .export _vcprintf .import pushax, popax, popptr1 .import __printf, _cputc - .importzp spc, ptr1, ptr2, ptr3, tmp1 + .importzp c_sp, ptr1, ptr2, ptr3, tmp1 .macpack generic .macpack cpu @@ -138,10 +138,10 @@ _vcprintf: ; Get the format parameter and push it again ldy #1 - lda (spc),y + lda (c_sp),y tax dey - lda (spc),y + lda (c_sp),y jsr pushax ; Replace the passed format parameter on the stack by &d - this creates @@ -150,10 +150,10 @@ _vcprintf: ldy #2 ; Low byte of d lda #<outdesc - sta (spc),y + sta (c_sp),y iny lda #>outdesc - sta (spc),y + sta (c_sp),y ; Restore ap and call _printf diff --git a/libsrc/creativision/crt0.s b/libsrc/creativision/crt0.s index dd6213b45..70009e2ba 100644 --- a/libsrc/creativision/crt0.s +++ b/libsrc/creativision/crt0.s @@ -40,8 +40,8 @@ entry: ; Setup the argument stack ptr lda #<(__ZP_LAST__ + __STACKSIZE__) ldx #>(__ZP_LAST__ + __STACKSIZE__) - sta spc - stx spc+1 + sta c_sp + stx c_sp+1 ; Call module constructors jsr initlib diff --git a/libsrc/cx16/crt0.s b/libsrc/cx16/crt0.s index ab16a95d8..0f8452a32 100644 --- a/libsrc/cx16/crt0.s +++ b/libsrc/cx16/crt0.s @@ -80,8 +80,8 @@ init: lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta spc - stx spc+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Switch to the lower/UPPER PetSCII charset. diff --git a/libsrc/cx16/mou/cx16-std.s b/libsrc/cx16/mou/cx16-std.s index 78b87e1aa..5bfe27a7d 100644 --- a/libsrc/cx16/mou/cx16-std.s +++ b/libsrc/cx16/mou/cx16-std.s @@ -238,11 +238,11 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (spc),y + lda (c_sp),y sta XPos+1 tax dey - lda (spc),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/dbg/dbgdump.s b/libsrc/dbg/dbgdump.s index a0ed097cc..2a4aea3f7 100644 --- a/libsrc/dbg/dbgdump.s +++ b/libsrc/dbg/dbgdump.s @@ -7,23 +7,23 @@ .export _DbgMemDump .import addysp1 .import __hextab - .importzp spc, tmp2, tmp3, tmp4, ptr3, ptr4 + .importzp c_sp, tmp2, tmp3, tmp4, ptr3, ptr4 _DbgMemDump: ldy #0 - lda (spc),y ; Get length + lda (c_sp),y ; Get length sta tmp4 iny - lda (spc),y ; Get the string buffer + lda (c_sp),y ; Get the string buffer sta ptr3 iny - lda (spc),y + lda (c_sp),y sta ptr3+1 iny - lda (spc),y ; Get the address + lda (c_sp),y ; Get the address sta ptr4 iny - lda (spc),y + lda (c_sp),y sta ptr4+1 jsr addysp1 ; Drop the parameters diff --git a/libsrc/dbg/dbgsupp.s b/libsrc/dbg/dbgsupp.s index 02e8a0d90..ce503bcab 100644 --- a/libsrc/dbg/dbgsupp.s +++ b/libsrc/dbg/dbgsupp.s @@ -36,9 +36,9 @@ DbgBreak: jsr DbgSwapZP ; Swap stuff lda #<DbgStack ; Set new stack - sta spc + sta c_sp lda #>DbgStack - sta spc+1 + sta c_sp+1 jsr ResetDbgBreaks ; Reset temporary breakpoints jsr _DbgEntry ; Call C code jsr SetDbgBreaks ; Set temporary breakpoints @@ -61,7 +61,7 @@ DbgStack: ; Swap space for the C temporaries CTemp: -_DbgCS: .res 2 ; spc +_DbgCS: .res 2 ; c_sp _DbgHI: .res 2 ; sreg .res (zpsavespace-4) ; Other stuff @@ -78,7 +78,7 @@ Swap1: ldx CTemp,y lda <__ZP_START__,y sta CTemp,y txa - sta spc,y + sta c_sp,y dey bpl Swap1 rts diff --git a/libsrc/gamate/crt0.s b/libsrc/gamate/crt0.s index be0281e8e..67fa8813f 100644 --- a/libsrc/gamate/crt0.s +++ b/libsrc/gamate/crt0.s @@ -34,8 +34,8 @@ Start: ; Set up the stack lda #<(__RAM_START__+__RAM_SIZE__) ldx #>(__RAM_START__+__RAM_SIZE__) - sta spc - stx spc + 1 + sta c_sp + stx c_sp + 1 ; Call module constructors jsr initlib diff --git a/libsrc/geos-common/drivers/geos-stdmou.s b/libsrc/geos-common/drivers/geos-stdmou.s index 9b04d549a..aacb2590e 100644 --- a/libsrc/geos-common/drivers/geos-stdmou.s +++ b/libsrc/geos-common/drivers/geos-stdmou.s @@ -13,7 +13,7 @@ .export _mouse_move, _mouse_buttons .import popsreg, addysp1 - .importzp spc, sreg, ptr1 + .importzp c_sp, sreg, ptr1 .include "const.inc" .include "jumptab.inc" @@ -87,22 +87,22 @@ _mouse_box: sta mouseBottom - lda (spc),y + lda (c_sp),y sta mouseRight iny - lda (spc),y + lda (c_sp),y sta mouseRight+1 ; maxx iny - lda (spc),y + lda (c_sp),y sta mouseTop iny ; Skip high byte iny - lda (spc),y + lda (c_sp),y sta mouseLeft iny - lda (spc),y + lda (c_sp),y sta mouseLeft+1 ; minx jmp addysp1 ; Drop params, return diff --git a/libsrc/geos-common/system/crt0.s b/libsrc/geos-common/system/crt0.s index 47918a022..e1751baef 100644 --- a/libsrc/geos-common/system/crt0.s +++ b/libsrc/geos-common/system/crt0.s @@ -11,7 +11,7 @@ .import initlib, donelib .import callmain .import zerobss - .importzp spc + .importzp c_sp .include "jumptab.inc" .include "geossym.inc" @@ -48,8 +48,8 @@ lda #<(__STACKADDR__ + __STACKSIZE__) ldx #>(__STACKADDR__ + __STACKSIZE__) - sta spc - stx spc+1 + sta c_sp + stx c_sp+1 ; Call the module constructors. diff --git a/libsrc/kim1/crt0.s b/libsrc/kim1/crt0.s index 3bd6e3e76..adc934a78 100644 --- a/libsrc/kim1/crt0.s +++ b/libsrc/kim1/crt0.s @@ -26,9 +26,9 @@ _init: cld ; Clear decimal mode ; Set cc65 argument stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) - sta spc + sta c_sp lda #>(__RAM_START__ + __RAM_SIZE__) - sta spc+1 + sta c_sp+1 ; Initialize memory storage diff --git a/libsrc/lynx/crt0.s b/libsrc/lynx/crt0.s index 8187c1f05..e1f1c078e 100644 --- a/libsrc/lynx/crt0.s +++ b/libsrc/lynx/crt0.s @@ -80,8 +80,8 @@ MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$2 lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta spc - stx spc+1 + sta c_sp + stx c_sp+1 ; Init Mickey. diff --git a/libsrc/lynx/lseek.s b/libsrc/lynx/lseek.s index 8b3184a04..da0a1922b 100644 --- a/libsrc/lynx/lseek.s +++ b/libsrc/lynx/lseek.s @@ -11,7 +11,7 @@ ; ; off_t __fastcall__ lseek(int fd, off_t offset, int whence); - .importzp spc, sreg, regsave, regbank, tmp1, ptr1, ptr2 + .importzp c_sp, sreg, regsave, regbank, tmp1, ptr1, ptr2 .macpack longbranch .export _lseek .import addysp, stax0sp, tosand0ax, pusheax, asreax2 diff --git a/libsrc/nes/crt0.s b/libsrc/nes/crt0.s index edf9248af..9b5ceb337 100644 --- a/libsrc/nes/crt0.s +++ b/libsrc/nes/crt0.s @@ -107,8 +107,8 @@ start: lda #<(__SRAM_START__ + __SRAM_SIZE__) ldx #>(__SRAM_START__ + __SRAM_SIZE__) - sta spc - stx spc+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/none/crt0.s b/libsrc/none/crt0.s index bc6fb65c5..443f453b9 100644 --- a/libsrc/none/crt0.s +++ b/libsrc/none/crt0.s @@ -10,8 +10,8 @@ lda #<__STACKSTART__ ldx #>__STACKSTART__ - sta spc - stx spc+1 + sta c_sp + stx c_sp+1 jsr zerobss jsr initlib jsr _main diff --git a/libsrc/osic1p/crt0.s b/libsrc/osic1p/crt0.s index b85113902..46d29ed66 100644 --- a/libsrc/osic1p/crt0.s +++ b/libsrc/osic1p/crt0.s @@ -34,8 +34,8 @@ _init: ldx #$FF ; Initialize stack pointer to $01FF lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta spc - stx spc+1 + sta c_sp + stx c_sp+1 ; --------------------------------------------------------------------------- ; Initialize memory storage diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s index 8e2f7758f..675076ec6 100644 --- a/libsrc/pce/_printf.s +++ b/libsrc/pce/_printf.s @@ -329,22 +329,22 @@ MainLoop: jsr decsp6 ; 3 args ldy #5 lda OutData+1 - sta (spc),y + sta (c_sp),y dey lda OutData - sta (spc),y + sta (c_sp),y dey lda FSave+1 - sta (spc),y + sta (c_sp),y dey lda FSave - sta (spc),y + sta (c_sp),y dey lda FCount+1 - sta (spc),y + sta (c_sp),y dey lda FCount - sta (spc),y + sta (c_sp),y jsr CallOutFunc ; Call the output function ; We're back from out(), or we didn't call it. Check for end of string. diff --git a/libsrc/pce/crt0.s b/libsrc/pce/crt0.s index 2bd13253b..660faae7f 100644 --- a/libsrc/pce/crt0.s +++ b/libsrc/pce/crt0.s @@ -13,7 +13,7 @@ .import initlib, donelib .import push0, _main .import IRQStub, __nmi - .importzp spc + .importzp c_sp ; Linker-generated .import __CARTSIZE__ @@ -86,8 +86,8 @@ start: sei ; Set up the stack lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta spc - stx spc+1 + sta c_sp + stx c_sp+1 ; Call the module constructors. jsr initlib diff --git a/libsrc/pce/memcpy.s b/libsrc/pce/memcpy.s index 184250bcb..5a0822ec1 100644 --- a/libsrc/pce/memcpy.s +++ b/libsrc/pce/memcpy.s @@ -18,7 +18,7 @@ .export memcpy_increment, memcpy_transfer, memcpy_getparams .import incsp2, popax, popptr1 - .importzp spc, ptr1, ptr2, ptr3 + .importzp c_sp, ptr1, ptr2, ptr3 ; The structure of the transfer instructions @@ -86,9 +86,9 @@ memcpy_getparams: ; (Direct stack access is six cycles faster [total cycle count].) iny ; (Y=0 by popptr1, need '1' here) save dest - lda (spc),y ; get high byte + lda (c_sp),y ; get high byte tax - lda (spc) ; get low byte + lda (c_sp) ; get low byte sta ptr2 stx ptr2+1 rts ; return dest address (for memmove) diff --git a/libsrc/pet/crt0.s b/libsrc/pet/crt0.s index 3732eba3c..ff57d7bac 100644 --- a/libsrc/pet/crt0.s +++ b/libsrc/pet/crt0.s @@ -23,7 +23,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda spc,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -52,9 +52,9 @@ L1: lda spc,x stx spsave ; Save the system stack ptr lda MEMSIZE - sta spc + sta c_sp lda MEMSIZE+1 - sta spc+1 ; Set argument stack ptr + sta c_sp+1 ; Set argument stack ptr ; Call the module constructors. @@ -73,7 +73,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta spc,x + sta c_sp,x dex bpl L2 diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index 50f7740fa..85bdcac8e 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -34,7 +34,7 @@ Start: sei ; No interrupts since we're banking out the ROM sta ENABLE_RAM ldx #zpspace-1 -L1: lda spc,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -54,8 +54,8 @@ L1: lda spc,x lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta spc - stx spc+1 + sta c_sp + stx c_sp+1 ; Set up the IRQ vector in the banked RAM; and, switch off the ROM. @@ -99,7 +99,7 @@ _exit: pha ; Save the return code ldx #zpspace-1 L2: lda zpsave,x - sta spc,x + sta c_sp,x dex bpl L2 diff --git a/libsrc/rp6502/crt0.s b/libsrc/rp6502/crt0.s index 45c24eb9e..32d565fda 100644 --- a/libsrc/rp6502/crt0.s +++ b/libsrc/rp6502/crt0.s @@ -24,9 +24,9 @@ _init: ; Set cc65 argument stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) - sta spc + sta c_sp lda #>(__RAM_START__ + __RAM_SIZE__) - sta spc+1 + sta c_sp+1 ; Initialize memory storage jsr zerobss ; Clear BSS segment diff --git a/libsrc/rp6502/ria.s b/libsrc/rp6502/ria.s index e23177344..78da4daba 100644 --- a/libsrc/rp6502/ria.s +++ b/libsrc/rp6502/ria.s @@ -11,7 +11,7 @@ .export _ria_call_int, _ria_call_long .export _ria_call_int_errno, _ria_call_long_errno -.importzp spc, sreg +.importzp c_sp, sreg .import ___mappederrno, incsp1 .code diff --git a/libsrc/rp6502/xreg.s b/libsrc/rp6502/xreg.s index 8d5fb9402..a882ab10f 100644 --- a/libsrc/rp6502/xreg.s +++ b/libsrc/rp6502/xreg.s @@ -5,7 +5,7 @@ ; int __cdecl__ xreg(char device, char channel, unsigned char address, ...); .export _xreg -.importzp spc +.importzp c_sp .import addysp, _ria_call_int_errno .include "rp6502.inc" @@ -20,12 +20,12 @@ @copy: ; copy stack dey - lda (spc),y + lda (c_sp),y sta RIA_XSTACK tya bne @copy - ; recover variadic size and move spc + ; recover variadic size and move c_sp txa tay jsr addysp diff --git a/libsrc/runtime/add.s b/libsrc/runtime/add.s index 8d48b30a5..b308614a1 100644 --- a/libsrc/runtime/add.s +++ b/libsrc/runtime/add.s @@ -9,7 +9,7 @@ ; called a lot! .export tosadda0, tosaddax - .importzp spc, tmp1 + .importzp c_sp, tmp1 .macpack cpu @@ -20,34 +20,34 @@ tosaddax: .if (.cpu .bitand ::CPU_ISET_65SC02) - adc (spc) ; (7) + adc (c_sp) ; (7) tay ; (9) - inc spc ; (14) + inc c_sp ; (14) bne hiadd ; (17) - inc spc+1 ; (-1+5) + inc c_sp+1 ; (-1+5) hiadd: txa ; (19) - adc (spc) ; (24) + adc (c_sp) ; (24) tax ; (26) - inc spc ; (31) + inc c_sp ; (31) bne done ; (34) - inc spc+1 ; (-1+5) + inc c_sp+1 ; (-1+5) done: tya ; (36) .else ldy #0 ; (4) - adc (spc),y ; (9) lo byte + adc (c_sp),y ; (9) lo byte iny ; (11) sta tmp1 ; (14) save it txa ; (16) - adc (spc),y ; (21) hi byte + adc (c_sp),y ; (21) hi byte tax ; (23) clc ; (25) - lda spc ; (28) + lda c_sp ; (28) adc #2 ; (30) - sta spc ; (33) + sta c_sp ; (33) bcc L1 ; (36) - inc spc+1 ; (-1+5) + inc c_sp+1 ; (-1+5) L1: lda tmp1 ; (39) restore low byte .endif diff --git a/libsrc/runtime/addeqsp.s b/libsrc/runtime/addeqsp.s index d042e0e8b..3c098ea5f 100644 --- a/libsrc/runtime/addeqsp.s +++ b/libsrc/runtime/addeqsp.s @@ -5,19 +5,19 @@ ; .export addeq0sp, addeqysp - .importzp spc + .importzp c_sp addeq0sp: ldy #0 addeqysp: clc - adc (spc),y - sta (spc),y + adc (c_sp),y + sta (c_sp),y pha iny txa - adc (spc),y - sta (spc),y + adc (c_sp),y + sta (c_sp),y tax pla rts diff --git a/libsrc/runtime/addysp.s b/libsrc/runtime/addysp.s index 246b0f4c9..553ed98c7 100644 --- a/libsrc/runtime/addysp.s +++ b/libsrc/runtime/addysp.s @@ -5,17 +5,17 @@ ; .export addysp1, addysp - .importzp spc + .importzp c_sp addysp1: iny addysp: pha ; Save A clc tya ; Get the value - adc spc ; Add low byte - sta spc ; Put it back + adc c_sp ; Add low byte + sta c_sp ; Put it back bcc @L1 ; If no carry, we're done - inc spc+1 ; Inc high byte + inc c_sp+1 ; Inc high byte @L1: pla ; Restore A rts diff --git a/libsrc/runtime/and.s b/libsrc/runtime/and.s index 7ad593b5c..21acebb66 100644 --- a/libsrc/runtime/and.s +++ b/libsrc/runtime/and.s @@ -6,7 +6,7 @@ .export tosanda0, tosandax .import addysp1 - .importzp spc, ptr4 + .importzp c_sp, ptr4 .macpack cpu @@ -14,16 +14,16 @@ tosanda0: ldx #$00 tosandax: .if (.cpu .bitand CPU_ISET_65SC02) - and (spc) ; 65SC02 version, saves 2 cycles and 1 byte + and (c_sp) ; 65SC02 version, saves 2 cycles and 1 byte ldy #1 .else ldy #0 - and (spc),y + and (c_sp),y iny .endif pha txa - and (spc),y + and (c_sp),y tax pla jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/bpushbsp.s b/libsrc/runtime/bpushbsp.s index 6f94aa322..c2cc18cf6 100644 --- a/libsrc/runtime/bpushbsp.s +++ b/libsrc/runtime/bpushbsp.s @@ -6,12 +6,12 @@ .export bpushbsp, bpushbysp .import pusha - .importzp spc + .importzp c_sp bpushbsp: ldy #0 bpushbysp: - lda (spc),y + lda (c_sp),y jmp pusha diff --git a/libsrc/runtime/decsp1.s b/libsrc/runtime/decsp1.s index 73b03f5db..4fd5392bb 100644 --- a/libsrc/runtime/decsp1.s +++ b/libsrc/runtime/decsp1.s @@ -5,14 +5,14 @@ ; .export decsp1 - .importzp spc + .importzp c_sp .proc decsp1 - ldy spc + ldy c_sp bne @L1 - dec spc+1 -@L1: dec spc + dec c_sp+1 +@L1: dec c_sp rts .endproc diff --git a/libsrc/runtime/decsp2.s b/libsrc/runtime/decsp2.s index 8d4e38477..c6c533d83 100644 --- a/libsrc/runtime/decsp2.s +++ b/libsrc/runtime/decsp2.s @@ -5,18 +5,18 @@ ; .export decsp2 - .importzp spc + .importzp c_sp .proc decsp2 - lda spc + lda c_sp sec sbc #2 - sta spc + sta c_sp bcc @L1 rts -@L1: dec spc+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp3.s b/libsrc/runtime/decsp3.s index cd4cb4798..2a2b22a15 100644 --- a/libsrc/runtime/decsp3.s +++ b/libsrc/runtime/decsp3.s @@ -5,18 +5,18 @@ ; .export decsp3 - .importzp spc + .importzp c_sp .proc decsp3 - lda spc + lda c_sp sec sbc #3 - sta spc + sta c_sp bcc @L1 rts -@L1: dec spc+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp4.s b/libsrc/runtime/decsp4.s index 739bc43f1..c756473bd 100644 --- a/libsrc/runtime/decsp4.s +++ b/libsrc/runtime/decsp4.s @@ -5,18 +5,18 @@ ; .export decsp4 - .importzp spc + .importzp c_sp .proc decsp4 - lda spc + lda c_sp sec sbc #4 - sta spc + sta c_sp bcc @L1 rts -@L1: dec spc+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp5.s b/libsrc/runtime/decsp5.s index 6d63cd290..71b2fb176 100644 --- a/libsrc/runtime/decsp5.s +++ b/libsrc/runtime/decsp5.s @@ -5,18 +5,18 @@ ; .export decsp5 - .importzp spc + .importzp c_sp .proc decsp5 - lda spc + lda c_sp sec sbc #5 - sta spc + sta c_sp bcc @L1 rts -@L1: dec spc+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp6.s b/libsrc/runtime/decsp6.s index 06f1bee2f..1d0b93136 100644 --- a/libsrc/runtime/decsp6.s +++ b/libsrc/runtime/decsp6.s @@ -5,18 +5,18 @@ ; .export decsp6 - .importzp spc + .importzp c_sp .proc decsp6 - lda spc + lda c_sp sec sbc #6 - sta spc + sta c_sp bcc @L1 rts -@L1: dec spc+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp7.s b/libsrc/runtime/decsp7.s index 341ce4dff..1646d9ec9 100644 --- a/libsrc/runtime/decsp7.s +++ b/libsrc/runtime/decsp7.s @@ -5,18 +5,18 @@ ; .export decsp7 - .importzp spc + .importzp c_sp .proc decsp7 - lda spc + lda c_sp sec sbc #7 - sta spc + sta c_sp bcc @L1 rts -@L1: dec spc+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp8.s b/libsrc/runtime/decsp8.s index 68bb08d17..1726331c5 100644 --- a/libsrc/runtime/decsp8.s +++ b/libsrc/runtime/decsp8.s @@ -5,18 +5,18 @@ ; .export decsp8 - .importzp spc + .importzp c_sp .proc decsp8 - lda spc + lda c_sp sec sbc #8 - sta spc + sta c_sp bcc @L1 rts -@L1: dec spc+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/enter.s b/libsrc/runtime/enter.s index b9091b0eb..5915f579a 100644 --- a/libsrc/runtime/enter.s +++ b/libsrc/runtime/enter.s @@ -5,14 +5,14 @@ ; .export enter - .importzp spc + .importzp c_sp enter: tya ; get arg size - ldy spc + ldy c_sp bne L1 - dec spc+1 -L1: dec spc + dec c_sp+1 +L1: dec c_sp ldy #0 - sta (spc),y ; Store the arg count + sta (c_sp),y ; Store the arg count rts diff --git a/libsrc/runtime/eq.s b/libsrc/runtime/eq.s index 073232e34..87cf1c085 100644 --- a/libsrc/runtime/eq.s +++ b/libsrc/runtime/eq.s @@ -6,7 +6,7 @@ .export toseq00, toseqa0, toseqax .import tosicmp, booleq - .importzp spc, tmp1 + .importzp c_sp, tmp1 toseq00: lda #$00 diff --git a/libsrc/runtime/icmp.s b/libsrc/runtime/icmp.s index 5c91d2c5a..0d3bb6140 100644 --- a/libsrc/runtime/icmp.s +++ b/libsrc/runtime/icmp.s @@ -6,7 +6,7 @@ ; .export tosicmp, tosicmp0 - .importzp spc, sreg + .importzp c_sp, sreg tosicmp0: @@ -17,16 +17,16 @@ tosicmp: stx sreg+1 ; Save ax ldy #$00 - lda (spc),y ; Get low byte + lda (c_sp),y ; Get low byte tax - inc spc ; 5 + inc c_sp ; 5 bne @L1 ; 3 - inc spc+1 ; (5) + inc c_sp+1 ; (5) @L1: - lda (spc),y ; Get high byte - inc spc ; 5 + lda (c_sp),y ; Get high byte + inc c_sp ; 5 bne @L2 ; 3 - inc spc+1 ; (5) + inc c_sp+1 ; (5) ; Do the compare. diff --git a/libsrc/runtime/incsp1.s b/libsrc/runtime/incsp1.s index d19412a7d..dde6c47b2 100644 --- a/libsrc/runtime/incsp1.s +++ b/libsrc/runtime/incsp1.s @@ -5,13 +5,13 @@ ; .export incsp1 - .importzp spc + .importzp c_sp .proc incsp1 - inc spc + inc c_sp bne @L1 - inc spc+1 + inc c_sp+1 @L1: rts .endproc diff --git a/libsrc/runtime/incsp2.s b/libsrc/runtime/incsp2.s index f7a0937e8..0d84dc7bb 100644 --- a/libsrc/runtime/incsp2.s +++ b/libsrc/runtime/incsp2.s @@ -5,7 +5,7 @@ ; this module also contains the popax function. .export popax, incsp2 - .importzp spc + .importzp c_sp .macpack cpu @@ -14,13 +14,13 @@ .proc popax ldy #1 - lda (spc),y ; get hi byte + lda (c_sp),y ; get hi byte tax ; into x .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (spc) ; get lo byte + lda (c_sp) ; get lo byte .else dey - lda (spc),y ; get lo byte + lda (c_sp),y ; get lo byte .endif .endproc @@ -29,14 +29,14 @@ .proc incsp2 - inc spc ; 5 + inc c_sp ; 5 beq @L1 ; 2 - inc spc ; 5 + inc c_sp ; 5 beq @L2 ; 2 rts -@L1: inc spc ; 5 -@L2: inc spc+1 ; 5 +@L1: inc c_sp ; 5 +@L2: inc c_sp+1 ; 5 rts .endproc diff --git a/libsrc/runtime/ladd.s b/libsrc/runtime/ladd.s index 3e9b546d7..6658d7ec6 100644 --- a/libsrc/runtime/ladd.s +++ b/libsrc/runtime/ladd.s @@ -6,7 +6,7 @@ .export tosadd0ax, tosaddeax .import addysp1 - .importzp spc, sreg, tmp1 + .importzp c_sp, sreg, tmp1 .macpack cpu @@ -20,24 +20,24 @@ tosadd0ax: tosaddeax: clc .if (.cpu .bitand CPU_ISET_65SC02) - adc (spc) ; 65SC02 version - saves 2 cycles + adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else ldy #0 - adc (spc),y ; lo byte + adc (c_sp),y ; lo byte iny .endif sta tmp1 ; use as temp storage txa - adc (spc),y ; byte 1 + adc (c_sp),y ; byte 1 tax iny lda sreg - adc (spc),y ; byte 2 + adc (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - adc (spc),y ; byte 3 + adc (c_sp),y ; byte 3 sta sreg+1 lda tmp1 ; load byte 0 jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/laddeqsp.s b/libsrc/runtime/laddeqsp.s index 21c41e8d9..13dbf8112 100644 --- a/libsrc/runtime/laddeqsp.s +++ b/libsrc/runtime/laddeqsp.s @@ -5,29 +5,29 @@ ; .export laddeq0sp, laddeqysp - .importzp spc, sreg + .importzp c_sp, sreg laddeq0sp: ldy #0 laddeqysp: clc - adc (spc),y - sta (spc),y + adc (c_sp),y + sta (c_sp),y pha iny txa - adc (spc),y - sta (spc),y + adc (c_sp),y + sta (c_sp),y tax iny lda sreg - adc (spc),y - sta (spc),y + adc (c_sp),y + sta (c_sp),y sta sreg iny lda sreg+1 - adc (spc),y - sta (spc),y + adc (c_sp),y + sta (c_sp),y sta sreg+1 pla rts diff --git a/libsrc/runtime/land.s b/libsrc/runtime/land.s index c14de06f3..9dd3cad6a 100644 --- a/libsrc/runtime/land.s +++ b/libsrc/runtime/land.s @@ -7,7 +7,7 @@ .export tosand0ax, tosandeax .import addysp1 - .importzp spc, sreg, tmp1 + .importzp c_sp, sreg, tmp1 .macpack cpu @@ -23,24 +23,24 @@ tosand0ax: tosandeax: .if (.cpu .bitand ::CPU_ISET_65SC02) - and (spc) ; byte 0 + and (c_sp) ; byte 0 ldy #1 .else ldy #0 - and (spc),y ; byte 0 + and (c_sp),y ; byte 0 iny .endif sta tmp1 txa - and (spc),y ; byte 1 + and (c_sp),y ; byte 1 tax iny lda sreg - and (spc),y ; byte 2 + and (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - and (spc),y ; byte 3 + and (c_sp),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/lcmp.s b/libsrc/runtime/lcmp.s index a8633578f..59c02dd56 100644 --- a/libsrc/runtime/lcmp.s +++ b/libsrc/runtime/lcmp.s @@ -7,7 +7,7 @@ .export toslcmp .import incsp4 - .importzp spc, sreg, ptr1 + .importzp c_sp, sreg, ptr1 toslcmp: @@ -15,23 +15,23 @@ toslcmp: stx ptr1+1 ; EAX now in sreg:ptr1 ldy #$03 - lda (spc),y + lda (c_sp),y sec sbc sreg+1 bne L4 dey - lda (spc),y + lda (c_sp),y cmp sreg bne L1 dey - lda (spc),y + lda (c_sp),y cmp ptr1+1 bne L1 dey - lda (spc),y + lda (c_sp),y cmp ptr1 L1: php ; Save flags diff --git a/libsrc/runtime/ldau0sp.s b/libsrc/runtime/ldau0sp.s index 88834a698..a808f6f84 100644 --- a/libsrc/runtime/ldau0sp.s +++ b/libsrc/runtime/ldau0sp.s @@ -5,17 +5,17 @@ ; .export ldau00sp, ldau0ysp - .importzp spc, ptr1 + .importzp c_sp, ptr1 .macpack cpu ldau00sp: ldy #1 ldau0ysp: - lda (spc),y + lda (c_sp),y sta ptr1+1 dey - lda (spc),y + lda (c_sp),y sta ptr1 ldx #0 .if (.cpu .bitand CPU_ISET_65SC02) diff --git a/libsrc/runtime/ldauisp.s b/libsrc/runtime/ldauisp.s index 0019a1f68..957f245be 100644 --- a/libsrc/runtime/ldauisp.s +++ b/libsrc/runtime/ldauisp.s @@ -5,15 +5,15 @@ ; .export ldaui0sp, ldauiysp - .importzp spc, ptr1 + .importzp c_sp, ptr1 ldaui0sp: ldy #1 ldauiysp: - lda (spc),y + lda (c_sp),y sta ptr1+1 dey - lda (spc),y + lda (c_sp),y sta ptr1 txa tay diff --git a/libsrc/runtime/ldaxsp.s b/libsrc/runtime/ldaxsp.s index 085c0cd36..88a3043a0 100644 --- a/libsrc/runtime/ldaxsp.s +++ b/libsrc/runtime/ldaxsp.s @@ -5,16 +5,16 @@ ; .export ldax0sp, ldaxysp - .importzp spc + .importzp c_sp ; Beware: The optimizer knows about the value in Y after return! ldax0sp: ldy #1 ldaxysp: - lda (spc),y ; get high byte + lda (c_sp),y ; get high byte tax ; and save it dey ; point to lo byte - lda (spc),y ; load low byte + lda (c_sp),y ; load low byte rts diff --git a/libsrc/runtime/ldeaxysp.s b/libsrc/runtime/ldeaxysp.s index 566925265..b6ce7254f 100644 --- a/libsrc/runtime/ldeaxysp.s +++ b/libsrc/runtime/ldeaxysp.s @@ -9,20 +9,20 @@ .export ldeax0sp, ldeaxysp - .importzp sreg, spc + .importzp sreg, c_sp ldeax0sp: ldy #3 ldeaxysp: - lda (spc),y + lda (c_sp),y sta sreg+1 dey - lda (spc),y + lda (c_sp),y sta sreg dey - lda (spc),y + lda (c_sp),y tax dey - lda (spc),y + lda (c_sp),y rts diff --git a/libsrc/runtime/leaaxsp.s b/libsrc/runtime/leaaxsp.s index 09f2bfccc..451d7191f 100644 --- a/libsrc/runtime/leaaxsp.s +++ b/libsrc/runtime/leaaxsp.s @@ -5,16 +5,16 @@ ; .export leaaxsp, leaa0sp - .importzp spc + .importzp c_sp leaa0sp: ldx #$00 leaaxsp: clc - adc spc + adc c_sp pha txa - adc spc+1 + adc c_sp+1 tax pla rts diff --git a/libsrc/runtime/leave.s b/libsrc/runtime/leave.s index 0dfd79556..a917ab955 100644 --- a/libsrc/runtime/leave.s +++ b/libsrc/runtime/leave.s @@ -12,7 +12,7 @@ .export leave00, leave0, leavey00, leavey0, leavey .export leave .import addysp - .importzp spc + .importzp c_sp .macpack cpu @@ -31,24 +31,24 @@ leavey: .if (.cpu .bitand ::CPU_ISET_65SC02) leave: tay ; save A a sec - lda (spc) ; that's the pushed arg size + lda (c_sp) ; that's the pushed arg size sec ; Count the byte, the count's stored in - adc spc - sta spc + adc c_sp + sta c_sp bcc L1 - inc spc+1 + inc c_sp+1 L1: tya ; Get return value back .else leave: pha ; save A a sec ldy #0 - lda (spc),y ; that's the pushed arg size + lda (c_sp),y ; that's the pushed arg size sec ; Count the byte, the count's stored in - adc spc - sta spc + adc c_sp + sta c_sp bcc L1 - inc spc+1 + inc c_sp+1 L1: pla ; Get return value back .endif diff --git a/libsrc/runtime/lmul.s b/libsrc/runtime/lmul.s index 2c337e143..a68c3e5c1 100644 --- a/libsrc/runtime/lmul.s +++ b/libsrc/runtime/lmul.s @@ -7,7 +7,7 @@ .export tosumul0ax, tosumuleax, tosmul0ax, tosmuleax .import addysp1 - .importzp spc, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 + .importzp c_sp, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 .macpack cpu @@ -27,21 +27,21 @@ tosumuleax: mul32: sta ptr1 stx ptr1+1 ; op2 now in ptr1/sreg .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (spc) + lda (c_sp) ldy #1 .else ldy #0 - lda (spc),y + lda (c_sp),y iny .endif sta ptr3 - lda (spc),y + lda (c_sp),y sta ptr3+1 iny - lda (spc),y + lda (c_sp),y sta ptr4 iny - lda (spc),y + lda (c_sp),y sta ptr4+1 ; op1 in pre3/ptr4 jsr addysp1 ; Drop TOS diff --git a/libsrc/runtime/lor.s b/libsrc/runtime/lor.s index 521f53e07..94731adac 100644 --- a/libsrc/runtime/lor.s +++ b/libsrc/runtime/lor.s @@ -7,7 +7,7 @@ .export tosor0ax, tosoreax .import addysp1 - .importzp spc, sreg, tmp1 + .importzp c_sp, sreg, tmp1 .macpack cpu @@ -23,24 +23,24 @@ tosor0ax: tosoreax: .if (.cpu .bitand ::CPU_ISET_65SC02) - ora (spc) + ora (c_sp) ldy #1 .else ldy #0 - ora (spc),y ; byte 0 + ora (c_sp),y ; byte 0 iny .endif sta tmp1 txa - ora (spc),y ; byte 1 + ora (c_sp),y ; byte 1 tax iny lda sreg - ora (spc),y ; byte 2 + ora (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - ora (spc),y ; byte 3 + ora (c_sp),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/lpop.s b/libsrc/runtime/lpop.s index 3c57e5b15..9690aff24 100644 --- a/libsrc/runtime/lpop.s +++ b/libsrc/runtime/lpop.s @@ -7,24 +7,24 @@ .export popeax .import incsp4 - .importzp spc, sreg + .importzp c_sp, sreg .macpack cpu popeax: ldy #3 - lda (spc),y + lda (c_sp),y sta sreg+1 dey - lda (spc),y + lda (c_sp),y sta sreg dey - lda (spc),y + lda (c_sp),y tax .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (spc) + lda (c_sp) .else dey - lda (spc),y + lda (c_sp),y .endif jmp incsp4 diff --git a/libsrc/runtime/lpush.s b/libsrc/runtime/lpush.s index 7a101af13..ec2c865af 100644 --- a/libsrc/runtime/lpush.s +++ b/libsrc/runtime/lpush.s @@ -10,7 +10,7 @@ ; .export pushl0, push0ax, pusheax .import decsp4 - .importzp spc, sreg + .importzp c_sp, sreg .macpack cpu @@ -31,19 +31,19 @@ pusheax: jsr decsp4 ldy #3 lda sreg+1 - sta (spc),y + sta (c_sp),y dey lda sreg - sta (spc),y + sta (c_sp),y dey txa - sta (spc),y + sta (c_sp),y pla .if (.cpu .bitand ::CPU_ISET_65SC02) - sta (spc) + sta (c_sp) .else dey - sta (spc),y + sta (c_sp),y .endif rts diff --git a/libsrc/runtime/lrsub.s b/libsrc/runtime/lrsub.s index bf7e3ee50..3bf941951 100644 --- a/libsrc/runtime/lrsub.s +++ b/libsrc/runtime/lrsub.s @@ -10,7 +10,7 @@ ; .export tosrsub0ax, tosrsubeax .import addysp1 - .importzp spc, sreg, tmp1 + .importzp c_sp, sreg, tmp1 .macpack cpu @@ -27,24 +27,24 @@ tosrsub0ax: tosrsubeax: sec .if (.cpu .bitand ::CPU_ISET_65SC02) - sbc (spc) + sbc (c_sp) ldy #1 .else ldy #0 - sbc (spc),y ; byte 0 + sbc (c_sp),y ; byte 0 iny .endif sta tmp1 ; use as temp storage txa - sbc (spc),y ; byte 1 + sbc (c_sp),y ; byte 1 tax iny lda sreg - sbc (spc),y ; byte 2 + sbc (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - sbc (spc),y ; byte 3 + sbc (c_sp),y ; byte 3 sta sreg+1 lda tmp1 jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/lsub.s b/libsrc/runtime/lsub.s index 559d0362f..2c0082deb 100644 --- a/libsrc/runtime/lsub.s +++ b/libsrc/runtime/lsub.s @@ -9,7 +9,7 @@ ; .export tossub0ax, tossubeax .import addysp1 - .importzp spc, sreg + .importzp c_sp, sreg .macpack cpu @@ -27,24 +27,24 @@ tossubeax: sec eor #$FF .if (.cpu .bitand ::CPU_ISET_65SC02) - adc (spc) ; 65SC02 version - saves 2 cycles + adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else ldy #0 - adc (spc),y ; lo byte + adc (c_sp),y ; lo byte iny .endif pha ; Save low byte txa eor #$FF - adc (spc),y ; byte 1 + adc (c_sp),y ; byte 1 tax iny - lda (spc),y + lda (c_sp),y sbc sreg ; byte 2 sta sreg iny - lda (spc),y + lda (c_sp),y sbc sreg+1 ; byte 3 sta sreg+1 pla ; Restore byte 0 diff --git a/libsrc/runtime/lsubeqsp.s b/libsrc/runtime/lsubeqsp.s index af2a38cc4..6f8377484 100644 --- a/libsrc/runtime/lsubeqsp.s +++ b/libsrc/runtime/lsubeqsp.s @@ -5,31 +5,31 @@ ; .export lsubeq0sp, lsubeqysp - .importzp spc, sreg + .importzp c_sp, sreg lsubeq0sp: ldy #0 lsubeqysp: sec eor #$FF - adc (spc),y - sta (spc),y + adc (c_sp),y + sta (c_sp),y pha ; Save low byte iny txa eor #$FF - adc (spc),y - sta (spc),y + adc (c_sp),y + sta (c_sp),y tax iny - lda (spc),y + lda (c_sp),y sbc sreg - sta (spc),y + sta (c_sp),y sta sreg iny - lda (spc),y + lda (c_sp),y sbc sreg+1 - sta (spc),y + sta (c_sp),y sta sreg+1 pla rts diff --git a/libsrc/runtime/ludiv.s b/libsrc/runtime/ludiv.s index 695fac4f3..b47207222 100644 --- a/libsrc/runtime/ludiv.s +++ b/libsrc/runtime/ludiv.s @@ -7,7 +7,7 @@ .export tosudiv0ax, tosudiveax, getlop, udiv32 .import addysp1 - .importzp spc, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 + .importzp c_sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 .macpack cpu @@ -39,21 +39,21 @@ getlop: sta ptr3 ; Put right operand in place sta ptr4+1 .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (spc) + lda (c_sp) ldy #1 .else ldy #0 ; Put left operand in place - lda (spc),y + lda (c_sp),y iny .endif sta ptr1 - lda (spc),y + lda (c_sp),y sta ptr1+1 iny - lda (spc),y + lda (c_sp),y sta sreg iny - lda (spc),y + lda (c_sp),y sta sreg+1 jmp addysp1 ; Drop parameters diff --git a/libsrc/runtime/lxor.s b/libsrc/runtime/lxor.s index fa012118d..8b17d8df6 100644 --- a/libsrc/runtime/lxor.s +++ b/libsrc/runtime/lxor.s @@ -7,7 +7,7 @@ .export tosxor0ax, tosxoreax .import addysp1 - .importzp spc, sreg, tmp1 + .importzp c_sp, sreg, tmp1 .macpack cpu @@ -23,24 +23,24 @@ tosxor0ax: tosxoreax: .if (.cpu .bitand ::CPU_ISET_65SC02) - eor (spc) ; byte 0 + eor (c_sp) ; byte 0 ldy #1 .else ldy #0 - eor (spc),y ; byte 0 + eor (c_sp),y ; byte 0 iny .endif sta tmp1 txa - eor (spc),y ; byte 1 + eor (c_sp),y ; byte 1 tax iny lda sreg - eor (spc),y ; byte 2 + eor (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - eor (spc),y ; byte 3 + eor (c_sp),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/or.s b/libsrc/runtime/or.s index dc06c92ed..04389be5f 100644 --- a/libsrc/runtime/or.s +++ b/libsrc/runtime/or.s @@ -7,7 +7,7 @@ .export tosora0, tosorax .import addysp1 - .importzp spc, tmp1 + .importzp c_sp, tmp1 .macpack cpu @@ -15,16 +15,16 @@ tosora0: ldx #$00 tosorax: .if (.cpu .bitand ::CPU_ISET_65SC02) - ora (spc) + ora (c_sp) ldy #1 .else ldy #0 - ora (spc),y + ora (c_sp),y iny .endif sta tmp1 txa - ora (spc),y + ora (c_sp),y tax lda tmp1 jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/popa.s b/libsrc/runtime/popa.s index d24391293..c90f2be59 100644 --- a/libsrc/runtime/popa.s +++ b/libsrc/runtime/popa.s @@ -5,23 +5,23 @@ ; .export popa - .importzp spc + .importzp c_sp .macpack cpu .proc popa .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (spc) + lda (c_sp) .else ldy #0 ; (2) - lda (spc),y ; (7) Read byte + lda (c_sp),y ; (7) Read byte .endif - inc spc ; (12) + inc c_sp ; (12) beq @L1 ; (14) rts ; (20) -@L1: inc spc+1 +@L1: inc c_sp+1 rts .endproc diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index 5c52b5d34..caa43f3e0 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -6,19 +6,19 @@ .export popptr1 .import incsp2 - .importzp spc, ptr1 + .importzp c_sp, ptr1 .macpack cpu .proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) ldy #1 - lda (spc),y ; get hi byte + lda (c_sp),y ; get hi byte sta ptr1+1 ; into ptr hi dey ; dey even for for 65C02 here to have Y=0 at exit! .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (spc) ; get lo byte + lda (c_sp) ; get lo byte .else - lda (spc),y ; get lo byte + lda (c_sp),y ; get lo byte .endif sta ptr1 ; to ptr lo jmp incsp2 diff --git a/libsrc/runtime/popsreg.s b/libsrc/runtime/popsreg.s index 2f2236813..6c1a61a32 100644 --- a/libsrc/runtime/popsreg.s +++ b/libsrc/runtime/popsreg.s @@ -6,20 +6,20 @@ .export popsreg .import incsp2 - .importzp spc, sreg + .importzp c_sp, sreg .macpack cpu popsreg: pha ; save A ldy #1 - lda (spc),y ; get hi byte + lda (c_sp),y ; get hi byte sta sreg+1 ; store it .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (spc) ; get lo byte + lda (c_sp) ; get lo byte .else dey - lda (spc),y ; get lo byte + lda (c_sp),y ; get lo byte .endif sta sreg ; store it pla ; get A back diff --git a/libsrc/runtime/pusha.s b/libsrc/runtime/pusha.s index f7c65f35d..253612172 100644 --- a/libsrc/runtime/pusha.s +++ b/libsrc/runtime/pusha.s @@ -5,7 +5,7 @@ ; .export pusha0sp, pushaysp, pusha - .importzp spc + .importzp c_sp .macpack cpu @@ -14,16 +14,16 @@ pusha0sp: ldy #$00 pushaysp: - lda (spc),y -pusha: ldy spc ; (3) + lda (c_sp),y +pusha: ldy c_sp ; (3) beq @L1 ; (6) - dec spc ; (11) + dec c_sp ; (11) ldy #0 ; (13) - sta (spc),y ; (19) + sta (c_sp),y ; (19) rts ; (25) -@L1: dec spc+1 ; (11) - dec spc ; (16) - sta (spc),y ; (22) +@L1: dec c_sp+1 ; (11) + dec c_sp ; (16) + sta (c_sp),y ; (22) rts ; (28) diff --git a/libsrc/runtime/pushax.s b/libsrc/runtime/pushax.s index 06e7d4942..247a38630 100644 --- a/libsrc/runtime/pushax.s +++ b/libsrc/runtime/pushax.s @@ -5,7 +5,7 @@ ; .export push0, pusha0, pushax - .importzp spc + .importzp c_sp .macpack cpu @@ -20,21 +20,21 @@ pusha0: ldx #0 .proc pushax pha ; (3) - lda spc ; (6) + lda c_sp ; (6) sec ; (8) sbc #2 ; (10) - sta spc ; (13) + sta c_sp ; (13) bcs @L1 ; (17) - dec spc+1 ; (+5) + dec c_sp+1 ; (+5) @L1: ldy #1 ; (19) txa ; (21) - sta (spc),y ; (27) + sta (c_sp),y ; (27) pla ; (31) dey ; (33) .if (.cpu .bitand ::CPU_ISET_65SC02) - sta (spc) ; (37) + sta (c_sp) ; (37) .else - sta (spc),y ; (38) + sta (c_sp),y ; (38) .endif rts ; (44/43) diff --git a/libsrc/runtime/pushbsp.s b/libsrc/runtime/pushbsp.s index abbaf7589..64da06723 100644 --- a/libsrc/runtime/pushbsp.s +++ b/libsrc/runtime/pushbsp.s @@ -6,12 +6,12 @@ .export pushbsp, pushbysp .import pusha0 - .importzp spc + .importzp c_sp pushbsp: ldy #0 pushbysp: - lda (spc),y ; get lo byte + lda (c_sp),y ; get lo byte jmp pusha0 ; promote to unsigned and push diff --git a/libsrc/runtime/pushlysp.s b/libsrc/runtime/pushlysp.s index c64c90d7d..86bb87dbd 100644 --- a/libsrc/runtime/pushlysp.s +++ b/libsrc/runtime/pushlysp.s @@ -7,23 +7,23 @@ .export pushlysp .import pusheax - .importzp sreg, spc + .importzp sreg, c_sp .proc pushlysp iny iny - lda (spc),y + lda (c_sp),y iny sta sreg - lda (spc),y + lda (c_sp),y sta sreg+1 dey dey - lda (spc),y + lda (c_sp),y dey tax - lda (spc),y + lda (c_sp),y jmp pusheax .endproc diff --git a/libsrc/runtime/pushwsp.s b/libsrc/runtime/pushwsp.s index de005d08c..3bd164230 100644 --- a/libsrc/runtime/pushwsp.s +++ b/libsrc/runtime/pushwsp.s @@ -5,27 +5,27 @@ ; .export pushwysp, pushw0sp - .importzp spc + .importzp c_sp .macpack generic pushw0sp: ldy #3 pushwysp: - lda spc ; 3 + lda c_sp ; 3 sub #2 ; 4 - sta spc ; 3 + sta c_sp ; 3 bcs @L1 ; 3(+1) - dec spc+1 ; (5) -@L1: lda (spc),y ; 5 =16 + dec c_sp+1 ; (5) +@L1: lda (c_sp),y ; 5 =16 tax ; 2 dey ; 2 - lda (spc),y ; 5 + lda (c_sp),y ; 5 ldy #$00 ; 2 - sta (spc),y ; 5 + sta (c_sp),y ; 5 iny ; 2 txa ; 2 - sta (spc),y ; 5 + sta (c_sp),y ; 5 rts diff --git a/libsrc/runtime/regswap.s b/libsrc/runtime/regswap.s index 0185b0503..96080c823 100644 --- a/libsrc/runtime/regswap.s +++ b/libsrc/runtime/regswap.s @@ -5,17 +5,17 @@ ; .export regswap - .importzp spc, regbank, tmp1 + .importzp c_sp, regbank, tmp1 .proc regswap sta tmp1 ; Store count @L1: lda regbank,x ; Get old value pha ; Save it - lda (spc),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank,x ; Store new value pla - sta (spc),y ; Store old value + sta (c_sp),y ; Store old value inx iny dec tmp1 diff --git a/libsrc/runtime/regswap1.s b/libsrc/runtime/regswap1.s index 28e069562..34cfd50eb 100644 --- a/libsrc/runtime/regswap1.s +++ b/libsrc/runtime/regswap1.s @@ -5,16 +5,16 @@ ; .export regswap1 - .importzp spc, regbank + .importzp c_sp, regbank .proc regswap1 lda regbank,x ; Get old value pha ; Save it - lda (spc),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank,x ; Store new value pla - sta (spc),y ; Store old value + sta (c_sp),y ; Store old value rts .endproc diff --git a/libsrc/runtime/regswap2.s b/libsrc/runtime/regswap2.s index 205458fa2..4f55fad40 100644 --- a/libsrc/runtime/regswap2.s +++ b/libsrc/runtime/regswap2.s @@ -5,7 +5,7 @@ ; .export regswap2 - .importzp spc, regbank + .importzp c_sp, regbank .proc regswap2 @@ -13,20 +13,20 @@ lda regbank,x ; Get old value pha ; Save it - lda (spc),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank,x ; Store new value pla - sta (spc),y ; Store old value + sta (c_sp),y ; Store old value ; Second byte iny lda regbank+1,x ; Get old value pha ; Save it - lda (spc),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank+1,x ; Store new value pla - sta (spc),y ; Store old value + sta (c_sp),y ; Store old value rts diff --git a/libsrc/runtime/rsub.s b/libsrc/runtime/rsub.s index afee1f7c3..c91b983dd 100644 --- a/libsrc/runtime/rsub.s +++ b/libsrc/runtime/rsub.s @@ -7,7 +7,7 @@ .export tosrsuba0, tosrsubax .import addysp1 - .importzp spc, tmp1 + .importzp c_sp, tmp1 .macpack cpu @@ -20,16 +20,16 @@ tosrsuba0: tosrsubax: sec .if (.cpu .bitand CPU_ISET_65SC02) - sbc (spc) + sbc (c_sp) ldy #1 .else ldy #0 - sbc (spc),y ; lo byte + sbc (c_sp),y ; lo byte iny .endif sta tmp1 ; save lo byte txa - sbc (spc),y ; hi byte + sbc (c_sp),y ; hi byte tax lda tmp1 jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/staspidx.s b/libsrc/runtime/staspidx.s index c1018b0d2..bd9b0c79d 100644 --- a/libsrc/runtime/staspidx.s +++ b/libsrc/runtime/staspidx.s @@ -6,17 +6,17 @@ .export staspidx .import incsp2 - .importzp spc, tmp1, ptr1 + .importzp c_sp, tmp1, ptr1 .proc staspidx pha sty tmp1 ; Save Index ldy #1 - lda (spc),y + lda (c_sp),y sta ptr1+1 dey - lda (spc),y + lda (c_sp),y sta ptr1 ; Pointer now in ptr1 ldy tmp1 ; Restore offset pla ; Restore value diff --git a/libsrc/runtime/staxsp.s b/libsrc/runtime/staxsp.s index bacadcddc..15bec22ee 100644 --- a/libsrc/runtime/staxsp.s +++ b/libsrc/runtime/staxsp.s @@ -1,20 +1,20 @@ ; ; Ullrich von Bassewitz, 31.08.1998 ; -; CC65 runtime: Store ax at (spc),y +; CC65 runtime: Store ax at (c_sp),y ; .export staxysp, stax0sp - .importzp spc + .importzp c_sp stax0sp: ldy #0 staxysp: - sta (spc),y + sta (c_sp),y iny pha txa - sta (spc),y + sta (c_sp),y pla rts diff --git a/libsrc/runtime/staxspi.s b/libsrc/runtime/staxspi.s index 44fee6789..aefed428f 100644 --- a/libsrc/runtime/staxspi.s +++ b/libsrc/runtime/staxspi.s @@ -7,7 +7,7 @@ .export staxspidx .import incsp2 - .importzp spc, tmp1, ptr1 + .importzp c_sp, tmp1, ptr1 .macpack cpu @@ -16,13 +16,13 @@ sty tmp1 ; Save Y pha ; Save A ldy #1 - lda (spc),y + lda (c_sp),y sta ptr1+1 .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (spc) + lda (c_sp) .else dey - lda (spc),y + lda (c_sp),y .endif sta ptr1 ; Address now in ptr1 ldy tmp1 ; Restore Y diff --git a/libsrc/runtime/steaxsp.s b/libsrc/runtime/steaxsp.s index 89d013fe7..33dbc04d7 100644 --- a/libsrc/runtime/steaxsp.s +++ b/libsrc/runtime/steaxsp.s @@ -1,26 +1,26 @@ ; ; Ullrich von Bassewitz, 31.08.1998 ; -; CC65 runtime: Store eax at (spc),y +; CC65 runtime: Store eax at (c_sp),y ; .export steaxysp, steax0sp - .importzp spc, sreg + .importzp c_sp, sreg steax0sp: ldy #0 steaxysp: - sta (spc),y + sta (c_sp),y iny pha txa - sta (spc),y + sta (c_sp),y iny lda sreg - sta (spc),y + sta (c_sp),y iny lda sreg+1 - sta (spc),y + sta (c_sp),y pla rts diff --git a/libsrc/runtime/stkchk.s b/libsrc/runtime/stkchk.s index 6125ae442..a7ca39f21 100644 --- a/libsrc/runtime/stkchk.s +++ b/libsrc/runtime/stkchk.s @@ -17,7 +17,7 @@ .constructor initstkchk, 25 .import __STACKSIZE__ ; Linker defined .import pusha0, _exit - .importzp spc + .importzp c_sp ; Use macros for better readability .macpack generic @@ -32,11 +32,11 @@ .proc initstkchk - lda spc + lda c_sp sta initialsp sub #<__STACKSIZE__ sta lowwater - lda spc+1 + lda c_sp+1 sta initialsp+1 sbc #>__STACKSIZE__ .if (.cpu .bitand ::CPU_ISET_65SC02) @@ -70,7 +70,7 @@ cstkchk: ; Check the high byte of the software stack @L0: lda lowwater+1 - cmp spc+1 + cmp c_sp+1 bcs @L1 rts @@ -78,7 +78,7 @@ cstkchk: @L1: bne CStackOverflow lda lowwater - cmp spc + cmp c_sp bcs CStackOverflow Done: rts @@ -87,9 +87,9 @@ Done: rts CStackOverflow: lda initialsp - sta spc + sta c_sp lda initialsp+1 - sta spc+1 + sta c_sp+1 ; Generic abort entry. We should output a diagnostic here, but this is ; difficult, since we're operating at a lower level here. diff --git a/libsrc/runtime/sub.s b/libsrc/runtime/sub.s index 4134987e0..07e7dc5e3 100644 --- a/libsrc/runtime/sub.s +++ b/libsrc/runtime/sub.s @@ -6,7 +6,7 @@ .export tossuba0, tossubax .import addysp1 - .importzp spc + .importzp c_sp .macpack cpu @@ -18,17 +18,17 @@ tossubax: sec eor #$FF .if (.cpu .bitand CPU_ISET_65SC02) - adc (spc) + adc (c_sp) ldy #1 .else ldy #0 - adc (spc),y ; Subtract low byte + adc (c_sp),y ; Subtract low byte iny .endif pha ; Save high byte txa eor #$FF - adc (spc),y ; Subtract high byte + adc (c_sp),y ; Subtract high byte tax ; High byte into X pla ; Restore low byte jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/subeqsp.s b/libsrc/runtime/subeqsp.s index 568b73df9..880e5f2fc 100644 --- a/libsrc/runtime/subeqsp.s +++ b/libsrc/runtime/subeqsp.s @@ -5,21 +5,21 @@ ; .export subeq0sp, subeqysp - .importzp spc + .importzp c_sp subeq0sp: ldy #0 subeqysp: sec eor #$FF - adc (spc),y - sta (spc),y + adc (c_sp),y + sta (c_sp),y pha ; Save low byte iny txa eor #$FF - adc (spc),y - sta (spc),y + adc (c_sp),y + sta (c_sp),y tax pla ; Restore low byte rts diff --git a/libsrc/runtime/subysp.s b/libsrc/runtime/subysp.s index 3fe03bc53..8f5bea806 100644 --- a/libsrc/runtime/subysp.s +++ b/libsrc/runtime/subysp.s @@ -6,17 +6,17 @@ ; .export subysp - .importzp spc + .importzp c_sp .proc subysp tya eor #$ff sec - adc spc - sta spc + adc c_sp + sta c_sp bcs @L1 - dec spc+1 + dec c_sp+1 @L1: rts .endproc diff --git a/libsrc/runtime/swap.s b/libsrc/runtime/swap.s index fd4e8154d..3796b0a97 100644 --- a/libsrc/runtime/swap.s +++ b/libsrc/runtime/swap.s @@ -6,7 +6,7 @@ ; .export swapstk - .importzp spc, ptr4 + .importzp c_sp, ptr4 .macpack cpu @@ -14,22 +14,22 @@ swapstk: sta ptr4 stx ptr4+1 ldy #1 ; index - lda (spc),y + lda (c_sp),y tax lda ptr4+1 - sta (spc),y + sta (c_sp),y .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (spc) + lda (c_sp) tay lda ptr4 - sta (spc) + sta (c_sp) tya .else dey - lda (spc),y + lda (c_sp),y pha lda ptr4 - sta (spc),y + sta (c_sp),y pla .endif rts ; whew! diff --git a/libsrc/runtime/tosint.s b/libsrc/runtime/tosint.s index 80341050d..b924a53e3 100644 --- a/libsrc/runtime/tosint.s +++ b/libsrc/runtime/tosint.s @@ -6,7 +6,7 @@ .export tosint .import incsp2 - .importzp spc + .importzp c_sp .macpack cpu @@ -16,17 +16,17 @@ pha .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (spc) + lda (c_sp) .else ldy #0 - lda (spc),y ; spc+1 + lda (c_sp),y ; c_sp+1 .endif ldy #2 - sta (spc),y + sta (c_sp),y dey - lda (spc),y + lda (c_sp),y ldy #3 - sta (spc),y + sta (c_sp),y pla jmp incsp2 ; Drop 16 bit diff --git a/libsrc/runtime/toslong.s b/libsrc/runtime/toslong.s index 7df441383..8e417367f 100644 --- a/libsrc/runtime/toslong.s +++ b/libsrc/runtime/toslong.s @@ -6,7 +6,7 @@ .export tosulong, toslong .import decsp2 - .importzp spc + .importzp c_sp .macpack cpu @@ -16,25 +16,25 @@ tosulong: pha jsr decsp2 ; Make room ldy #2 - lda (spc),y + lda (c_sp),y .if (.cpu .bitand CPU_ISET_65SC02) - sta (spc) ; 65C02 version + sta (c_sp) ; 65C02 version iny ; Y = 3 .else ldy #0 - sta (spc),y + sta (c_sp),y ldy #3 .endif - lda (spc),y + lda (c_sp),y toslong1: ldy #1 - sta (spc),y + sta (c_sp),y lda #0 ; Zero extend toslong2: iny - sta (spc),y + sta (c_sp),y iny - sta (spc),y + sta (c_sp),y pla rts @@ -42,19 +42,19 @@ toslong: pha jsr decsp2 ; Make room ldy #2 - lda (spc),y + lda (c_sp),y .if (.cpu .bitand CPU_ISET_65SC02) - sta (spc) ; 65C02 version + sta (c_sp) ; 65C02 version iny ; Y = 3 .else ldy #0 - sta (spc),y + sta (c_sp),y ldy #3 .endif - lda (spc),y + lda (c_sp),y bpl toslong1 ; Jump if positive, high word is zero ldy #1 - sta (spc),y + sta (c_sp),y lda #$FF bne toslong2 ; Branch always diff --git a/libsrc/runtime/xor.s b/libsrc/runtime/xor.s index 38c127a90..15394413c 100644 --- a/libsrc/runtime/xor.s +++ b/libsrc/runtime/xor.s @@ -7,7 +7,7 @@ .export tosxora0, tosxorax .import addysp1 - .importzp spc, tmp1 + .importzp c_sp, tmp1 .macpack cpu @@ -15,16 +15,16 @@ tosxora0: ldx #$00 tosxorax: .if (.cpu .bitand CPU_ISET_65SC02) - eor (spc) + eor (c_sp) ldy #1 .else ldy #0 - eor (spc),y + eor (c_sp),y iny .endif sta tmp1 txa - eor (spc),y + eor (c_sp),y tax lda tmp1 jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/zeropage.s b/libsrc/runtime/zeropage.s index 2b95a2899..73b25bf0a 100644 --- a/libsrc/runtime/zeropage.s +++ b/libsrc/runtime/zeropage.s @@ -10,7 +10,7 @@ .zeropage -spc: .res 2 ; Stack pointer +c_sp: .res 2 ; Stack pointer sreg: .res 2 ; Secondary register/high 16 bit for longs regsave: .res 4 ; Slot to save/restore (E)AX into ptr1: .res 2 diff --git a/libsrc/sim6502/crt0.s b/libsrc/sim6502/crt0.s index a2d4e7e97..26be7888b 100644 --- a/libsrc/sim6502/crt0.s +++ b/libsrc/sim6502/crt0.s @@ -22,8 +22,8 @@ startup:cld txs lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta spc - stx spc+1 + sta c_sp + stx c_sp+1 jsr zerobss jsr initlib jsr callmain diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s index 7eb1c1c74..0a0e4bb26 100644 --- a/libsrc/sim6502/exehdr.s +++ b/libsrc/sim6502/exehdr.s @@ -5,7 +5,7 @@ ; .export __EXEHDR__ : absolute = 1 ; Linker referenced - .importzp spc + .importzp c_sp .import __MAIN_START__ .import startup @@ -24,6 +24,6 @@ .else .error Unknown CPU type. .endif - .byte spc ; spc address + .byte c_sp ; c_sp address .addr __MAIN_START__ ; load address .addr startup ; reset address diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index 8a3f59c66..931ec8be8 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -33,8 +33,8 @@ reset: lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) ldx #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - sta spc - stx spc+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr jsr initlib jsr _main _exit: jsr donelib diff --git a/libsrc/sym1/crt0.s b/libsrc/sym1/crt0.s index 4ce070c9c..d20b4cf6c 100644 --- a/libsrc/sym1/crt0.s +++ b/libsrc/sym1/crt0.s @@ -33,9 +33,9 @@ _init: jsr ACCESS ; Unlock System RAM ; Set cc65 argument stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) - sta spc + sta c_sp lda #>(__RAM_START__ + __RAM_SIZE__) - sta spc+1 + sta c_sp+1 ; Initialize memory storage diff --git a/libsrc/telestrat/crt0.s b/libsrc/telestrat/crt0.s index f6796487d..430c4f8c8 100644 --- a/libsrc/telestrat/crt0.s +++ b/libsrc/telestrat/crt0.s @@ -47,7 +47,7 @@ _exit: jsr donelib ldx #zpspace - 1 L2: lda zpsave,x - sta spc,x + sta c_sp,x dex bpl L2 @@ -64,7 +64,7 @@ L2: lda zpsave,x ; Save the zero-page area that we're about to use. init: ldx #zpspace - 1 -L1: lda spc,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -74,8 +74,8 @@ L1: lda spc,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta spc - stx spc+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/telestrat/open.s b/libsrc/telestrat/open.s index c53a01b53..08c572e23 100644 --- a/libsrc/telestrat/open.s +++ b/libsrc/telestrat/open.s @@ -2,7 +2,7 @@ .import addysp,popax - .importzp spc,tmp2,tmp3,tmp1 + .importzp c_sp,tmp2,tmp3,tmp1 .include "telestrat.inc" diff --git a/libsrc/telestrat/wherex.s b/libsrc/telestrat/wherex.s index 835a57c0e..256b967c3 100644 --- a/libsrc/telestrat/wherex.s +++ b/libsrc/telestrat/wherex.s @@ -3,7 +3,7 @@ ; .export _wherex - .importzp spc + .importzp c_sp .include "telestrat.inc" diff --git a/libsrc/tgi/tgi_outtextxy.s b/libsrc/tgi/tgi_outtextxy.s index ea0f3d098..24183396f 100644 --- a/libsrc/tgi/tgi_outtextxy.s +++ b/libsrc/tgi/tgi_outtextxy.s @@ -8,7 +8,7 @@ .include "tgi-kernel.inc" .import addysp1 - .importzp spc + .importzp c_sp .proc _tgi_outtextxy @@ -17,16 +17,16 @@ pha ; ldy #0 - lda (spc),y + lda (c_sp),y sta _tgi_cury iny - lda (spc),y + lda (c_sp),y sta _tgi_cury+1 iny - lda (spc),y + lda (c_sp),y sta _tgi_curx iny - lda (spc),y + lda (c_sp),y sta _tgi_curx+1 pla jsr addysp1 ; Drop arguments from stack diff --git a/libsrc/vic20/crt0.s b/libsrc/vic20/crt0.s index 9e07f832d..64ccf6085 100644 --- a/libsrc/vic20/crt0.s +++ b/libsrc/vic20/crt0.s @@ -24,7 +24,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda spc,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -45,8 +45,8 @@ L1: lda spc,x lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta spc - stx spc+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. @@ -65,7 +65,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta spc,x + sta c_sp,x dex bpl L2 diff --git a/libsrc/zlib/inflatemem.s b/libsrc/zlib/inflatemem.s index 35d0532b3..2f2a1b295 100644 --- a/libsrc/zlib/inflatemem.s +++ b/libsrc/zlib/inflatemem.s @@ -12,7 +12,7 @@ .export _inflatemem .import incsp2 - .importzp spc, sreg, ptr1, ptr2, ptr3, ptr4 + .importzp c_sp, sreg, ptr1, ptr2, ptr3, ptr4 ; -------------------------------------------------------------------------- ; @@ -79,10 +79,10 @@ _inflatemem: stx inputPointer+1 ; outputPointer = dest ldy #1 - lda (spc),y + lda (c_sp),y sta outputPointer+1 dey - lda (spc),y + lda (c_sp),y sta outputPointer ; ldy #0 @@ -129,11 +129,11 @@ inflate_nextBlock: lda outputPointer ; ldy #0 ; sec - sbc (spc),y + sbc (c_sp),y iny pha lda outputPointer+1 - sbc (spc),y + sbc (c_sp),y tax pla ; pop dest diff --git a/samples/getsp.s b/samples/getsp.s index 6f0d4bdde..95db689f4 100644 --- a/samples/getsp.s +++ b/samples/getsp.s @@ -1,11 +1,11 @@ .export _getsp - .importzp spc + .importzp c_sp .proc _getsp - ldx spc+1 - lda spc + ldx c_sp+1 + lda c_sp rts .endproc diff --git a/samples/tinyshell.c b/samples/tinyshell.c index 300ad6e91..a8d5340d9 100644 --- a/samples/tinyshell.c +++ b/samples/tinyshell.c @@ -112,17 +112,17 @@ static void get_command(void) #ifdef CHECK_SP static char firstcall = 1; static unsigned int good_sp; - unsigned int spc; + unsigned int c_sp; if (firstcall) - spc = good_sp = getsp(); + c_sp = good_sp = getsp(); else - spc = getsp(); + c_sp = getsp(); - if (spc != good_sp) { - printf("SP: 0x%04X ***MISMATCH*** 0x%04X\n", spc, good_sp); + if (c_sp != good_sp) { + printf("SP: 0x%04X ***MISMATCH*** 0x%04X\n", c_sp, good_sp); } else if (verbose) - printf("SP: 0x%04X\n", spc); + printf("SP: 0x%04X\n", c_sp); #endif arg1 = arg2 = arg3 = NULL; diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index a986b4244..f07d289be 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -218,7 +218,10 @@ void g_preamble (void) AddTextLine ("\t.debuginfo\t%s", (DebugInfo != 0)? "on" : "off"); /* Import zero page variables */ - AddTextLine ("\t.importzp\tspc, sreg, regsave, regbank"); + AddTextLine ("\t.importzp\t" "c_sp, sreg, regsave, regbank"); + /* The space above is intentional, to ease replacement of the name of + ** the stack pointer. Don't worry, the preprocessor will concatenate them. + */ AddTextLine ("\t.importzp\ttmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4"); /* Define long branch macros */ @@ -569,11 +572,11 @@ void g_swap_regvars (int StackOffs, int RegOffs, unsigned Bytes) AddCodeLine ("ldx #$%02X", RegOffs & 0xFF); AddCodeLine ("jsr regswap1"); } else { - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("ldx regbank%+d", RegOffs); AddCodeLine ("sta regbank%+d", RegOffs); AddCodeLine ("txa"); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); } } else if (Bytes == 2) { @@ -615,7 +618,7 @@ void g_save_regvars (int RegOffs, unsigned Bytes) AddCodeLine ("ldx #$%02X", (unsigned char) Bytes); g_defcodelabel (Label); AddCodeLine ("lda regbank%+d,x", RegOffs-1); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("dey"); AddCodeLine ("dex"); AddCodeLine ("bne %s", LocalLabelName (Label)); @@ -639,28 +642,28 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) if (Bytes == 1) { AddCodeLine ("ldy #$%02X", StackOffs); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs); } else if (Bytes == 2) { AddCodeLine ("ldy #$%02X", StackOffs); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs); AddCodeLine ("iny"); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs+1); } else if (Bytes == 3 && IS_Get (&CodeSizeFactor) >= 133) { AddCodeLine ("ldy #$%02X", StackOffs); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs); AddCodeLine ("iny"); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs+1); AddCodeLine ("iny"); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs+2); } else if (StackOffs <= RegOffs) { @@ -672,7 +675,7 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) unsigned Label = GetLocalLabel (); AddCodeLine ("ldy #$%02X", StackOffs); g_defcodelabel (Label); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d,y", RegOffs - StackOffs); AddCodeLine ("iny"); AddCodeLine ("cpy #$%02X", StackOffs + Bytes); @@ -688,7 +691,7 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) AddCodeLine ("ldy #$%02X", (unsigned char) (StackOffs + Bytes - 1)); AddCodeLine ("ldx #$%02X", (unsigned char) (Bytes - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d,x", RegOffs); AddCodeLine ("dey"); AddCodeLine ("dex"); @@ -834,11 +837,11 @@ void g_getlocal (unsigned Flags, int Offs) CheckLocalOffs (Offs); if ((Flags & CF_FORCECHAR) || (Flags & CF_TEST)) { AddCodeLine ("ldy #$%02X", Offs); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); } else { AddCodeLine ("ldy #$%02X", Offs); AddCodeLine ("ldx #$00"); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); if ((Flags & CF_UNSIGNED) == 0) { unsigned L = GetLocalLabel(); AddCodeLine ("bpl %s", LocalLabelName (L)); @@ -852,9 +855,9 @@ void g_getlocal (unsigned Flags, int Offs) CheckLocalOffs (Offs + 1); AddCodeLine ("ldy #$%02X", (unsigned char) (Offs+1)); if (Flags & CF_TEST) { - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("dey"); - AddCodeLine ("ora (spc),y"); + AddCodeLine ("ora (c_sp),y"); } else { AddCodeLine ("jsr ldaxysp"); } @@ -935,7 +938,7 @@ void g_leasp (int Offs) { unsigned char Lo, Hi; - /* Calculate the offset relative to spc */ + /* Calculate the offset relative to c_sp */ Offs -= StackPtr; /* Get low and high byte */ @@ -945,17 +948,17 @@ void g_leasp (int Offs) /* Generate code */ if (Lo == 0) { if (Hi <= 3) { - AddCodeLine ("lda spc"); - AddCodeLine ("ldx spc+1"); + AddCodeLine ("lda c_sp"); + AddCodeLine ("ldx c_sp+1"); while (Hi--) { AddCodeLine ("inx"); } } else { - AddCodeLine ("lda spc+1"); + AddCodeLine ("lda c_sp+1"); AddCodeLine ("clc"); AddCodeLine ("adc #$%02X", Hi); AddCodeLine ("tax"); - AddCodeLine ("lda spc"); + AddCodeLine ("lda c_sp"); } } else if (Hi == 0) { /* 8 bit offset */ @@ -966,8 +969,8 @@ void g_leasp (int Offs) } else { /* 8 bit offset inlined */ unsigned L = GetLocalLabel (); - AddCodeLine ("lda spc"); - AddCodeLine ("ldx spc+1"); + AddCodeLine ("lda c_sp"); + AddCodeLine ("ldx c_sp+1"); AddCodeLine ("clc"); AddCodeLine ("adc #$%02X", Lo); AddCodeLine ("bcc %s", LocalLabelName (L)); @@ -981,11 +984,11 @@ void g_leasp (int Offs) AddCodeLine ("jsr leaaxsp"); } else { /* Full 16 bit offset inlined */ - AddCodeLine ("lda spc"); + AddCodeLine ("lda c_sp"); AddCodeLine ("clc"); AddCodeLine ("adc #$%02X", Lo); AddCodeLine ("pha"); - AddCodeLine ("lda spc+1"); + AddCodeLine ("lda c_sp+1"); AddCodeLine ("adc #$%02X", Hi); AddCodeLine ("tax"); AddCodeLine ("pla"); @@ -1001,10 +1004,10 @@ void g_leavariadic (int Offs) { unsigned ArgSizeOffs; - /* Calculate the offset relative to spc */ + /* Calculate the offset relative to c_sp */ Offs -= StackPtr; - /* Get the offset of the parameter which is stored at spc+0 on function + /* Get the offset of the parameter which is stored at c_sp+0 on function ** entry and check if this offset is reachable with a byte offset. */ CHECK (StackPtr <= 0); @@ -1013,14 +1016,14 @@ void g_leavariadic (int Offs) /* Get the size of all parameters. */ AddCodeLine ("ldy #$%02X", ArgSizeOffs); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); /* Add the value of the stackpointer */ if (IS_Get (&CodeSizeFactor) > 250) { unsigned L = GetLocalLabel(); - AddCodeLine ("ldx spc+1"); + AddCodeLine ("ldx c_sp+1"); AddCodeLine ("clc"); - AddCodeLine ("adc spc"); + AddCodeLine ("adc c_sp"); AddCodeLine ("bcc %s", LocalLabelName (L)); AddCodeLine ("inx"); g_defcodelabel (L); @@ -1092,14 +1095,14 @@ void g_putlocal (unsigned Flags, int Offs, long Val) AddCodeLine ("lda #$%02X", (unsigned char) Val); } AddCodeLine ("ldy #$%02X", Offs); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); break; case CF_INT: if (Flags & CF_CONST) { AddCodeLine ("ldy #$%02X", Offs+1); AddCodeLine ("lda #$%02X", (unsigned char) (Val >> 8)); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); if ((Flags & CF_NOKEEP) == 0) { /* Place high byte into X */ AddCodeLine ("tax"); @@ -1112,16 +1115,16 @@ void g_putlocal (unsigned Flags, int Offs, long Val) AddCodeLine ("dey"); AddCodeLine ("lda #$%02X", (unsigned char) Val); } - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); } else { AddCodeLine ("ldy #$%02X", Offs); if ((Flags & CF_NOKEEP) == 0 || IS_Get (&CodeSizeFactor) < 160) { AddCodeLine ("jsr staxysp"); } else { - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCodeLine ("txa"); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); } } break; @@ -1161,12 +1164,12 @@ void g_putind (unsigned Flags, unsigned Offs) AddCodeLine ("pha"); } AddCodeLine ("lda #$%02X", Offs & 0xFF); - AddCodeLine ("adc (spc),y"); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCodeLine ("lda #$%02X", (Offs >> 8) & 0xFF); - AddCodeLine ("adc (spc),y"); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); if ((Flags & CF_NOKEEP) == 0) { AddCodeLine ("pla"); } @@ -1183,8 +1186,8 @@ void g_putind (unsigned Flags, unsigned Offs) AddCodeLine ("pha"); } AddCodeLine ("lda #$%02X", (Offs >> 8) & 0xFF); - AddCodeLine ("adc (spc),y"); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); if ((Flags & CF_NOKEEP) == 0) { AddCodeLine ("pla"); } @@ -1618,7 +1621,7 @@ void g_addlocal (unsigned flags, int offs) L = GetLocalLabel(); AddCodeLine ("ldy #$%02X", NewOff & 0xFF); AddCodeLine ("clc"); - AddCodeLine ("adc (spc),y"); + AddCodeLine ("adc (c_sp),y"); AddCodeLine ("bcc %s", LocalLabelName (L)); AddCodeLine ("inx"); g_defcodelabel (L); @@ -1627,11 +1630,11 @@ void g_addlocal (unsigned flags, int offs) case CF_INT: AddCodeLine ("ldy #$%02X", NewOff & 0xFF); AddCodeLine ("clc"); - AddCodeLine ("adc (spc),y"); + AddCodeLine ("adc (c_sp),y"); AddCodeLine ("pha"); AddCodeLine ("txa"); AddCodeLine ("iny"); - AddCodeLine ("adc (spc),y"); + AddCodeLine ("adc (c_sp),y"); AddCodeLine ("tax"); AddCodeLine ("pla"); break; @@ -1839,12 +1842,12 @@ void g_addeqlocal (unsigned flags, int Offs, unsigned long val) if (flags & CF_CONST) { AddCodeLine ("clc"); AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); - AddCodeLine ("adc (spc),y"); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); } else { AddCodeLine ("clc"); - AddCodeLine ("adc (spc),y"); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); } if ((flags & CF_UNSIGNED) == 0) { unsigned L = GetLocalLabel(); @@ -1862,16 +1865,16 @@ void g_addeqlocal (unsigned flags, int Offs, unsigned long val) if (IS_Get (&CodeSizeFactor) >= 400) { AddCodeLine ("clc"); AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); - AddCodeLine ("adc (spc),y"); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCodeLine ("lda #$%02X", (int) ((val >> 8) & 0xFF)); - AddCodeLine ("adc (spc),y"); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); if ((flags & CF_NOKEEP) == 0) { AddCodeLine ("tax"); AddCodeLine ("dey"); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); } } else { g_getimmed (flags, val, 0); @@ -1923,7 +1926,7 @@ void g_addeqind (unsigned flags, unsigned offs, unsigned long val) case CF_INT: case CF_LONG: AddCodeLine ("jsr pushax"); /* Push the address */ - push (CF_PTR); /* Correct the internal spc */ + push (CF_PTR); /* Correct the internal c_sp */ g_getind (flags, offs); /* Fetch the value */ g_inc (flags, val); /* Increment value in primary */ g_putind (flags, offs); /* Store the value back */ @@ -2089,15 +2092,15 @@ void g_subeqlocal (unsigned flags, int Offs, unsigned long val) AddCodeLine ("ldy #$%02X", Offs); AddCodeLine ("ldx #$00"); if (flags & CF_CONST) { - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sec"); AddCodeLine ("sbc #$%02X", (unsigned char)val); } else { AddCodeLine ("eor #$FF"); AddCodeLine ("sec"); - AddCodeLine ("adc (spc),y"); + AddCodeLine ("adc (c_sp),y"); } - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); if ((flags & CF_UNSIGNED) == 0) { unsigned L = GetLocalLabel(); AddCodeLine ("bpl %s", LocalLabelName (L)); @@ -2157,7 +2160,7 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val) case CF_INT: case CF_LONG: AddCodeLine ("jsr pushax"); /* Push the address */ - push (CF_PTR); /* Correct the internal spc */ + push (CF_PTR); /* Correct the internal c_sp */ g_getind (flags, offs); /* Fetch the value */ g_dec (flags, val); /* Increment value in primary */ g_putind (flags, offs); /* Store the value back */ @@ -2208,10 +2211,10 @@ void g_addaddr_local (unsigned flags attribute ((unused)), int offs) /* Label was used above */ g_defcodelabel (L); } - AddCodeLine ("adc spc"); + AddCodeLine ("adc c_sp"); AddCodeLine ("tay"); AddCodeLine ("txa"); - AddCodeLine ("adc spc+1"); + AddCodeLine ("adc c_sp+1"); AddCodeLine ("tax"); AddCodeLine ("tya"); } @@ -2512,10 +2515,10 @@ void g_callind (unsigned Flags, unsigned ArgSize, int Offs) CheckLocalOffs (Offs); AddCodeLine ("pha"); AddCodeLine ("ldy #$%02X", Offs); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta jmpvec+1"); AddCodeLine ("iny"); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta jmpvec+2"); AddCodeLine ("pla"); AddCodeLine ("jsr jmpvec"); @@ -2573,11 +2576,11 @@ void g_lateadjustSP (unsigned label) AddCodeLine ("pha"); AddCodeLine ("lda %s", LocalDataLabelName (label)); AddCodeLine ("clc"); - AddCodeLine ("adc spc"); - AddCodeLine ("sta spc"); + AddCodeLine ("adc c_sp"); + AddCodeLine ("sta c_sp"); AddCodeLine ("lda %s+1", LocalDataLabelName (label)); - AddCodeLine ("adc spc+1"); - AddCodeLine ("sta spc+1"); + AddCodeLine ("adc c_sp+1"); + AddCodeLine ("sta c_sp+1"); AddCodeLine ("pla"); } @@ -2591,11 +2594,11 @@ void g_drop (unsigned Space) AddCodeLine ("pha"); AddCodeLine ("lda #$%02X", (unsigned char) Space); AddCodeLine ("clc"); - AddCodeLine ("adc spc"); - AddCodeLine ("sta spc"); + AddCodeLine ("adc c_sp"); + AddCodeLine ("sta c_sp"); AddCodeLine ("lda #$%02X", (unsigned char) (Space >> 8)); - AddCodeLine ("adc spc+1"); - AddCodeLine ("sta spc+1"); + AddCodeLine ("adc c_sp+1"); + AddCodeLine ("sta c_sp+1"); AddCodeLine ("pla"); } else if (Space > 8) { AddCodeLine ("ldy #$%02X", Space); @@ -2618,13 +2621,13 @@ void g_space (int Space) ** overhead. */ AddCodeLine ("pha"); - AddCodeLine ("lda spc"); + AddCodeLine ("lda c_sp"); AddCodeLine ("sec"); AddCodeLine ("sbc #$%02X", (unsigned char) Space); - AddCodeLine ("sta spc"); - AddCodeLine ("lda spc+1"); + AddCodeLine ("sta c_sp"); + AddCodeLine ("lda c_sp+1"); AddCodeLine ("sbc #$%02X", (unsigned char) (Space >> 8)); - AddCodeLine ("sta spc+1"); + AddCodeLine ("sta c_sp+1"); AddCodeLine ("pla"); } else if (Space > 8) { AddCodeLine ("ldy #$%02X", Space); @@ -4584,14 +4587,14 @@ void g_initauto (unsigned Label, unsigned Size) AddCodeLine ("ldy #$%02X", Size-1); g_defcodelabel (CodeLabel); AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, Label, 0)); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (CodeLabel)); } else if (Size <= 256) { AddCodeLine ("ldy #$00"); g_defcodelabel (CodeLabel); AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, Label, 0)); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Size); AddCodeLine ("bne %s", LocalLabelName (CodeLabel)); diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 5be8a38e2..5e5c431aa 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -380,7 +380,10 @@ static const FuncInfo FuncInfoTable[] = { #define FuncInfoCount (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0])) /* Table with names of zero page locations used by the compiler */ +/* MUST BE SORTED BY NAME !!! */ static const ZPInfo ZPInfoTable[] = { + { 0, "c_sp", 2, REG_SP_LO, REG_SP }, + { 0, "c_sp+1", 1, REG_SP_HI, REG_SP }, { 0, "ptr1", 2, REG_PTR1_LO, REG_PTR1 }, { 0, "ptr1+1", 1, REG_PTR1_HI, REG_PTR1 }, { 0, "ptr2", 2, REG_PTR2_LO, REG_PTR2 }, @@ -390,8 +393,6 @@ static const ZPInfo ZPInfoTable[] = { { 7, "regbank", 6, REG_NONE, REG_NONE }, { 0, "regsave", 4, REG_SAVE_LO, REG_SAVE }, { 0, "regsave+1", 3, REG_SAVE_HI, REG_SAVE }, - { 0, "spc", 2, REG_SP_LO, REG_SP }, - { 0, "spc+1", 1, REG_SP_HI, REG_SP }, { 0, "sreg", 2, REG_SREG_LO, REG_SREG }, { 0, "sreg+1", 1, REG_SREG_HI, REG_SREG }, { 0, "tmp1", 1, REG_TMP1, REG_TMP1 }, diff --git a/src/cc65/codeinfo.h b/src/cc65/codeinfo.h index 01cf345c5..d03962343 100644 --- a/src/cc65/codeinfo.h +++ b/src/cc65/codeinfo.h @@ -75,8 +75,8 @@ struct RegContents; #define REG_SP_HI 0x2000U /* Defines for some special register usage */ -#define SLV_IND 0x00010000U /* Accesses (spc),y */ -#define SLV_TOP 0x00020000U /* Accesses (spc),0 */ +#define SLV_IND 0x00010000U /* Accesses (c_sp),y */ +#define SLV_TOP 0x00020000U /* Accesses (c_sp),0 */ #define SLV_SP65 0x00200000U /* Accesses 6502 stack pointer */ #define SLV_PH65 0x00400000U /* Pushes onto 6502 stack */ #define SLV_PL65 0x00800000U /* Pops from 6502 stack */ @@ -122,7 +122,7 @@ struct RegContents; typedef struct ZPInfo ZPInfo; struct ZPInfo { unsigned char Len; /* Length of the following string */ - char Name[10]; /* Name of zero page symbol */ + char Name[64]; /* Name of zero page symbol */ unsigned char Size; /* Maximum buffer size of this register */ unsigned short ByteUse; /* Register info for this symbol */ unsigned short WordUse; /* Register info for 16 bit access */ diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 3a896a9c1..f4027c64e 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -810,7 +810,7 @@ static unsigned RunOptGroup5 (CodeSeg* S) static unsigned RunOptGroup6 (CodeSeg* S) -/* This one is quite special. It tries to replace "lda (spc),y" by "lda (spc,x)". +/* This one is quite special. It tries to replace "lda (c_sp),y" by "lda (c_sp,x)". ** The latter is ony cycle slower, but if we're able to remove the necessary ** load of the Y register, because X is zero anyway, we gain 1 cycle and ** shorten the code by one (transfer) or two bytes (load). So what we do is diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 2335a283a..bab271ee9 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -333,14 +333,14 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) */ if (E->AM == AM65_ABS || E->AM == AM65_ZP || - (E->AM == AM65_ZP_INDY && strcmp (E->ArgBase, "spc") == 0) + (E->AM == AM65_ZP_INDY && strcmp (E->ArgBase, "c_sp") == 0) ) { if ((LRI->Flags & LI_CHECK_ARG) != 0) { if (AE == 0 || (AE->AM != AM65_ABS && AE->AM != AM65_ZP && (AE->AM != AM65_ZP_INDY || - strcmp (AE->ArgBase, "spc") != 0)) || + strcmp (AE->ArgBase, "c_sp") != 0)) || (AE->ArgOff == E->ArgOff && strcmp (AE->ArgBase, E->ArgBase) == 0)) { @@ -445,7 +445,7 @@ void PrepairLoadRegInfoForArgCheck (CodeSeg* S, LoadRegInfo* LRI, CodeEntry* E) /* These insns are replaceable only if they are not modified later */ LRI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; } else if ((E->AM == AM65_ZP_INDY) && - strcmp (E->Arg, "spc") == 0) { + strcmp (E->Arg, "c_sp") == 0) { /* A load from the stack with known offset is also ok, but in this ** case we must reload the index register later. Please note that ** a load indirect via other zero page locations is not ok, since @@ -556,7 +556,7 @@ unsigned int TrackLoads (LoadInfo* LI, CodeSeg* S, int I) /* These insns are replaceable only if they are not modified later */ LRI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; } else if (E->AM == AM65_ZP_INDY && - strcmp (E->Arg, "spc") == 0) { + strcmp (E->Arg, "c_sp") == 0) { /* A load from the stack with known offset is also ok, but in this ** case we must reload the index register later. Please note that ** a load indirect via other zero page locations is not ok, since @@ -839,7 +839,7 @@ void AdjustStackOffset (StackOpData* D, unsigned Offs) if (E->OPC != OP65_JSR) { /* Check against some things that should not happen */ CHECK (E->AM == AM65_ZP_INDY && E->RI->In.RegY >= (short) Offs); - CHECK (strcmp (E->Arg, "spc") == 0); + CHECK (strcmp (E->Arg, "c_sp") == 0); /* We need to correct this one */ Correction = 2; @@ -1056,8 +1056,8 @@ void AddOpLow (StackOpData* D, opc_t OPC, LoadInfo* LI) InsertEntry (D, X, D->IP++); if (LI->A.LoadEntry->OPC == OP65_JSR) { - /* opc (spc),y */ - X = NewCodeEntry (OPC, AM65_ZP_INDY, "spc", 0, D->OpEntry->LI); + /* opc (c_sp),y */ + X = NewCodeEntry (OPC, AM65_ZP_INDY, "c_sp", 0, D->OpEntry->LI); } else { /* opc src,y */ X = NewCodeEntry (OPC, LI->A.LoadEntry->AM, LI->A.LoadEntry->Arg, 0, D->OpEntry->LI); @@ -1119,8 +1119,8 @@ void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) InsertEntry (D, X, D->IP++); if (LI->X.LoadEntry->OPC == OP65_JSR) { - /* opc (spc),y */ - X = NewCodeEntry (OPC, AM65_ZP_INDY, "spc", 0, D->OpEntry->LI); + /* opc (c_sp),y */ + X = NewCodeEntry (OPC, AM65_ZP_INDY, "c_sp", 0, D->OpEntry->LI); } else { /* opc src,y */ X = NewCodeEntry (OPC, LI->X.LoadEntry->AM, LI->X.LoadEntry->Arg, 0, D->OpEntry->LI); @@ -1310,10 +1310,10 @@ const char* GetZPName (unsigned ZPLoc) return "save+1"; } if ((ZPLoc & REG_SP_LO) != 0) { - return "spc"; + return "c_sp"; } if ((ZPLoc & REG_SP_HI) != 0) { - return "spc+1"; + return "c_sp+1"; } return 0; diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index 5af9c1079..3636e0e20 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -62,15 +62,15 @@ unsigned OptAdd1 (CodeSeg* S) ** and replace it by: ** ** ldy #xx-1 -** lda (spc),y +** lda (c_sp),y ** ldy #yy-3 ** clc -** adc (spc),y +** adc (c_sp),y ** pha ** ldy #xx -** lda (spc),y +** lda (c_sp),y ** ldy #yy-2 -** adc (spc),y +** adc (c_sp),y ** tax ** pla */ @@ -104,8 +104,8 @@ unsigned OptAdd1 (CodeSeg* S) /* Correct the stack of the first Y register load */ CE_SetNumArg (L[0], L[0]->Num - 1); - /* lda (spc),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+1); /* ldy #yy-3 */ @@ -117,8 +117,8 @@ unsigned OptAdd1 (CodeSeg* S) X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[5]->LI); CS_InsertEntry (S, X, I+3); - /* adc (spc),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "spc", 0, L[5]->LI); + /* adc (c_sp),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "c_sp", 0, L[5]->LI); CS_InsertEntry (S, X, I+4); /* pha */ @@ -130,8 +130,8 @@ unsigned OptAdd1 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); CS_InsertEntry (S, X, I+6); - /* lda (spc),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+7); /* ldy #yy-2 */ @@ -139,8 +139,8 @@ unsigned OptAdd1 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[4]->LI); CS_InsertEntry (S, X, I+8); - /* adc (spc),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "spc", 0, L[5]->LI); + /* adc (c_sp),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "c_sp", 0, L[5]->LI); CS_InsertEntry (S, X, I+9); /* tax */ @@ -181,16 +181,16 @@ unsigned OptAdd2 (CodeSeg* S) ** and replace it by: ** ** ldy #xx-1 -** lda (spc),y +** lda (c_sp),y ** ldy #yy ** clc -** adc (spc),y -** sta (spc),y +** adc (c_sp),y +** sta (c_sp),y ** ldy #xx -** lda (spc),y +** lda (c_sp),y ** ldy #yy+1 -** adc (spc),y -** sta (spc),y +** adc (c_sp),y +** sta (c_sp),y ** ** provided that a/x is not used later. */ @@ -226,8 +226,8 @@ unsigned OptAdd2 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+4); - /* lda (spc),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+5); /* ldy #yy */ @@ -238,20 +238,20 @@ unsigned OptAdd2 (CodeSeg* S) X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[3]->LI); CS_InsertEntry (S, X, I+7); - /* adc (spc),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "spc", 0, L[3]->LI); + /* adc (c_sp),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "c_sp", 0, L[3]->LI); CS_InsertEntry (S, X, I+8); - /* sta (spc),y */ - X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "spc", 0, L[3]->LI); + /* sta (c_sp),y */ + X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "c_sp", 0, L[3]->LI); CS_InsertEntry (S, X, I+9); /* ldy #xx */ X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+10); - /* lda (spc),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+11); /* ldy #yy+1 */ @@ -259,12 +259,12 @@ unsigned OptAdd2 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[2]->LI); CS_InsertEntry (S, X, I+12); - /* adc (spc),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "spc", 0, L[3]->LI); + /* adc (c_sp),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "c_sp", 0, L[3]->LI); CS_InsertEntry (S, X, I+13); - /* sta (spc),y */ - X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "spc", 0, L[3]->LI); + /* sta (c_sp),y */ + X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "c_sp", 0, L[3]->LI); CS_InsertEntry (S, X, I+14); /* Delete the old code */ diff --git a/src/cc65/coptadd.h b/src/cc65/coptadd.h index 2598f726d..d29783305 100644 --- a/src/cc65/coptadd.h +++ b/src/cc65/coptadd.h @@ -55,14 +55,14 @@ unsigned OptAdd1 (CodeSeg* S); ** jsr pushax ** ldy xxx ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** jsr tosaddax ** ** and replace it by: ** ** ldy xxx-2 ** clc -** adc (spc),y +** adc (c_sp),y ** bcc L ** inx ** L: @@ -72,26 +72,26 @@ unsigned OptAdd2 (CodeSeg* S); /* Search for the sequence ** ** ldy #xx -** lda (spc),y +** lda (c_sp),y ** tax ** dey -** lda (spc),y +** lda (c_sp),y ** ldy #$yy ** jsr addeqysp ** ** and replace it by: ** ** ldy #xx-1 -** lda (spc),y +** lda (c_sp),y ** ldy #yy ** clc -** adc (spc),y -** sta (spc),y +** adc (c_sp),y +** sta (c_sp),y ** ldy #xx -** lda (spc),y +** lda (c_sp),y ** ldy #yy+1 -** adc (spc),y -** sta (spc),y +** adc (c_sp),y +** sta (c_sp),y ** ** provided that a/x is not used later. */ diff --git a/src/cc65/coptbool.c b/src/cc65/coptbool.c index c5a54f9be..e0a79238e 100644 --- a/src/cc65/coptbool.c +++ b/src/cc65/coptbool.c @@ -743,9 +743,9 @@ unsigned OptBNegAX2 (CodeSeg* S) ** and replace it by ** ** ldy #xx -** lda (spc),y +** lda (c_sp),y ** dey -** ora (spc),y +** ora (c_sp),y ** jeq/jne ... */ { @@ -772,16 +772,16 @@ unsigned OptBNegAX2 (CodeSeg* S) CodeEntry* X; - /* lda (spc),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+1); /* dey */ X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[1]->LI); CS_InsertEntry (S, X, I+2); - /* ora (spc),y */ - X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "spc", 0, L[1]->LI); + /* ora (c_sp),y */ + X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+3); /* Invert the branch */ diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index 0148e87f9..eb138e78d 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -431,22 +431,22 @@ unsigned OptCmp5 (CodeSeg* S) /* The value is zero, we may use the simple code version: ** ldy #o-1 - ** lda (spc),y + ** lda (c_sp),y ** ldy #o - ** ora (spc),y + ** ora (c_sp),y ** jne/jeq ... */ sprintf (Buf, "$%02X", (int)(L[0]->Num-1)); X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI); CS_InsertEntry (S, X, I+1); - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+2); X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+3); - X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "spc", 0, L[1]->LI); + X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+4); CS_DelEntries (S, I+5, 3); /* cpx/bne/cmp */ @@ -461,18 +461,18 @@ unsigned OptCmp5 (CodeSeg* S) ** of the low byte after the first branch if possible: ** ** ldy #o - ** lda (spc),y + ** lda (c_sp),y ** cmp #a ** bne L1 ** ldy #o-1 - ** lda (spc),y + ** lda (c_sp),y ** cmp #b ** jne/jeq ... */ X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+3); - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+4); X = NewCodeEntry (OP65_CMP, L[2]->AM, L[2]->Arg, 0, L[2]->LI); @@ -482,7 +482,7 @@ unsigned OptCmp5 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI); CS_InsertEntry (S, X, I+7); - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[1]->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+8); CS_DelEntries (S, I, 3); /* ldy/jsr/cpx */ diff --git a/src/cc65/coptcmp.h b/src/cc65/coptcmp.h index 222892679..98e75715b 100644 --- a/src/cc65/coptcmp.h +++ b/src/cc65/coptcmp.h @@ -113,10 +113,10 @@ unsigned OptCmp5 (CodeSeg* S); /* Optimize compares of local variables: ** ** ldy #o -** lda (spc),y +** lda (c_sp),y ** tax ** dey -** lda (spc),y +** lda (c_sp),y ** cpx #a ** bne L1 ** cmp #b diff --git a/src/cc65/coptmisc.c b/src/cc65/coptmisc.c index 323e0e7bc..6560ccc26 100644 --- a/src/cc65/coptmisc.c +++ b/src/cc65/coptmisc.c @@ -492,9 +492,9 @@ unsigned OptGotoSPAdj (CodeSeg* S) L[1]->AM == AM65_ABS && L[2]->OPC == OP65_CLC && L[3]->OPC == OP65_ADC && - strcmp (L[3]->Arg, "spc") == 0 && + strcmp (L[3]->Arg, "c_sp") == 0 && L[6]->OPC == OP65_ADC && - strcmp (L[6]->Arg, "spc+1") == 0 && + strcmp (L[6]->Arg, "c_sp+1") == 0 && L[9]->OPC == OP65_JMP) { adjustment = FindSPAdjustment (L[1]->Arg); @@ -617,7 +617,7 @@ unsigned OptLoad1 (CodeSeg* S) CS_InsertEntry (S, X, I+1); /* Load from stack */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, E->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, E->LI); CS_InsertEntry (S, X, I+2); /* Now remove the call to the subroutine */ @@ -673,8 +673,8 @@ unsigned OptLoad2 (CodeSeg* S) ** later */ - /* lda (spc),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[0]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[0]->LI); CS_InsertEntry (S, X, I+3); /* sta abs */ @@ -685,8 +685,8 @@ unsigned OptLoad2 (CodeSeg* S) X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[0]->LI); CS_InsertEntry (S, X, I+5); - /* lda (spc),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[0]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[0]->LI); CS_InsertEntry (S, X, I+6); /* sta abs */ @@ -700,8 +700,8 @@ unsigned OptLoad2 (CodeSeg* S) /* Standard replacement */ - /* lda (spc),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[0]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[0]->LI); CS_InsertEntry (S, X, I+1); /* tax */ @@ -712,8 +712,8 @@ unsigned OptLoad2 (CodeSeg* S) X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[0]->LI); CS_InsertEntry (S, X, I+3); - /* lda (spc),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "spc", 0, L[0]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[0]->LI); CS_InsertEntry (S, X, I+4); /* Now remove the call to the subroutine */ diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index 26aa37a2e..e28bf5d39 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -359,7 +359,7 @@ unsigned OptPtrLoad4 (CodeSeg* S) ** ldx #>(label+0) ** ldy #$xx ** clc -** adc (spc),y +** adc (c_sp),y ** bcc L ** inx ** L: ldy #$00 @@ -368,7 +368,7 @@ unsigned OptPtrLoad4 (CodeSeg* S) ** and replace it by: ** ** ldy #$xx -** lda (spc),y +** lda (c_sp),y ** tay ** ldx #$00 ** lda label,y @@ -553,7 +553,7 @@ unsigned OptPtrLoad6 (CodeSeg* S) ** jsr pushax ** ldy #xxx ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** jsr tosaddax ** ldy #$00 ** jsr ldauidx @@ -563,7 +563,7 @@ unsigned OptPtrLoad6 (CodeSeg* S) ** sta ptr1 ** stx ptr1+1 ** ldy #xxx-2 -** lda (spc),y +** lda (c_sp),y ** tay ** ldx #$00 ** lda (ptr1),y @@ -613,7 +613,7 @@ unsigned OptPtrLoad6 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); CS_InsertEntry (S, X, I+9); - /* lda (spc),y */ + /* lda (c_sp),y */ X = NewCodeEntry (OP65_LDA, L[3]->AM, L[3]->Arg, 0, L[3]->LI); CS_InsertEntry (S, X, I+10); diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h index f8aee9b1a..259d1587b 100644 --- a/src/cc65/coptptrload.h +++ b/src/cc65/coptptrload.h @@ -127,7 +127,7 @@ unsigned OptPtrLoad4 (CodeSeg* S); ** ldx #>(label+0) ** ldy #$xx ** clc -** adc (spc),y +** adc (c_sp),y ** bcc L ** inx ** L: ldy #$00 @@ -136,7 +136,7 @@ unsigned OptPtrLoad4 (CodeSeg* S); ** and replace it by: ** ** ldy #$xx -** lda (spc),y +** lda (c_sp),y ** tay ** ldx #$00 ** lda label,y @@ -166,7 +166,7 @@ unsigned OptPtrLoad6 (CodeSeg* S); ** jsr pushax ** ldy xxx ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** jsr tosaddax ** ldy #$00 ** jsr ldauidx @@ -176,7 +176,7 @@ unsigned OptPtrLoad6 (CodeSeg* S); ** sta ptr1 ** stx ptr1+1 ** ldy xxx -** lda (spc),y +** lda (c_sp),y ** tay ** lda (ptr1),y */ diff --git a/src/cc65/coptptrstore.c b/src/cc65/coptptrstore.c index 558c12859..6891d8353 100644 --- a/src/cc65/coptptrstore.c +++ b/src/cc65/coptptrstore.c @@ -396,7 +396,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** L: jsr pushax ** ldy yyy ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** ldy #$00 ** jsr staspidx ** @@ -406,7 +406,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** stx ptr1+1 ** ldy yyy-2 ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** ldy xxx ** sta (ptr1),y ** @@ -414,7 +414,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** ** ldy yyy-2 ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** ldy xxx ** sta (zp),y ** @@ -422,7 +422,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** ** ldy yyy-2 ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** ldy xxx ** sta label,y ** @@ -430,7 +430,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** ** ldy yyy-2 ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** ldy xxx ** sta $xxxx,y ** @@ -468,7 +468,7 @@ unsigned OptPtrStore2 (CodeSeg* S) L[6]->OPC == OP65_LDX && L[7]->OPC == OP65_LDA && L[7]->AM == AM65_ZP_INDY && - strcmp (L[7]->Arg, "spc") == 0 && + strcmp (L[7]->Arg, "c_sp") == 0 && L[8]->OPC == OP65_LDY && (L[8]->AM == AM65_ABS || L[8]->AM == AM65_ZP || diff --git a/src/cc65/coptptrstore.h b/src/cc65/coptptrstore.h index 77e73649a..fd36eddba 100644 --- a/src/cc65/coptptrstore.h +++ b/src/cc65/coptptrstore.h @@ -105,7 +105,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** L: jsr pushax ** ldy yyy ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** ldy #$00 ** jsr staspidx ** @@ -115,7 +115,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** stx ptr1+1 ** ldy yyy-2 ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** ldy xxx ** sta (ptr1),y ** @@ -123,7 +123,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** ** ldy yyy-2 ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** ldy xxx ** sta (zp),y ** @@ -131,7 +131,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** ** ldy yyy-2 ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** ldy xxx ** sta label,y ** @@ -139,7 +139,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** ** ldy yyy-2 ** ldx #$00 -** lda (spc),y +** lda (c_sp),y ** ldy xxx ** sta $xxxx,y ** diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index e14e049c6..aa30e2038 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1292,10 +1292,10 @@ static unsigned Opt_a_tosicmp (StackOpData* D) } InsertEntry (D, X, D->IP++); - /* cmp src,y OR cmp (spc),y */ + /* cmp src,y OR cmp (c_sp),y */ if (D->Rhs.A.LoadEntry->OPC == OP65_JSR) { - /* opc (spc),y */ - X = NewCodeEntry (OP65_CMP, AM65_ZP_INDY, "spc", 0, D->OpEntry->LI); + /* opc (c_sp),y */ + X = NewCodeEntry (OP65_CMP, AM65_ZP_INDY, "c_sp", 0, D->OpEntry->LI); } else { /* opc src,y */ X = NewCodeEntry (OP65_CMP, D->Rhs.A.LoadEntry->AM, D->Rhs.A.LoadEntry->Arg, 0, D->OpEntry->LI); diff --git a/src/cc65/coptstore.c b/src/cc65/coptstore.c index a3458835b..2fc83b5fb 100644 --- a/src/cc65/coptstore.c +++ b/src/cc65/coptstore.c @@ -48,7 +48,7 @@ static void InsertStore (CodeSeg* S, unsigned* IP, LineInfo* LI) { - CodeEntry* X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "spc", 0, LI); + CodeEntry* X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "c_sp", 0, LI); CS_InsertEntry (S, X, (*IP)++); } diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 98ba16d3b..08fe83b75 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -269,7 +269,7 @@ static void ParseAutoDecl (Declarator* Decl) Sym->V.Offs = F_ReserveLocalSpace (CurrentFunc, Size); /* Next, allocate the space on the stack. This means that the - ** variable is now located at offset 0 from the current spc. + ** variable is now located at offset 0 from the current c_sp. */ F_AllocLocalSpace (CurrentFunc); diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index f22bb314e..6a2bcd2de 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -370,7 +370,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); g_defcodelabel (Label); AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); } else { @@ -378,7 +378,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); g_defcodelabel (Label); AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("dey"); AddCodeLine ("dex"); AddCodeLine ("bpl %s", LocalLabelName (Label)); @@ -390,7 +390,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); @@ -399,7 +399,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCodeLine ("inx"); AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal); @@ -447,7 +447,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Offs == 0) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); @@ -455,7 +455,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldx #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); AddCodeLine ("dey"); AddCodeLine ("dex"); @@ -467,7 +467,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Offs == 0 || AllowOneIndex) { AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs)); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); @@ -476,7 +476,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldx #$00"); AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); AddCodeLine ("iny"); AddCodeLine ("inx"); @@ -511,14 +511,14 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Arg3.Expr.IVal <= 129) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta (ptr1),y"); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); } else { AddCodeLine ("ldy #$00"); g_defcodelabel (Label); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta (ptr1),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); @@ -702,7 +702,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) Offs); AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); g_defcodelabel (Label); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); @@ -856,7 +856,7 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Generate code */ AddCodeLine ("ldy #$%02X", Offs); AddCodeLine ("ldx #$00"); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); } else if (IsArray && ED_IsLocConst (&Arg1.Expr)) { /* Drop the generated code */ RemoveCode (&Arg1.Load); @@ -1089,14 +1089,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Offs == 0 || AllowOneIndex) { g_defcodelabel (L1); AddCodeLine ("iny"); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs)); } else { AddCodeLine ("ldx #$FF"); g_defcodelabel (L1); AddCodeLine ("iny"); AddCodeLine ("inx"); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); } AddCodeLine ("bne %s", LocalLabelName (L1)); @@ -1137,14 +1137,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) g_defcodelabel (L1); AddCodeLine ("iny"); AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); } else { AddCodeLine ("ldx #$FF"); g_defcodelabel (L1); AddCodeLine ("iny"); AddCodeLine ("inx"); AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("sta (spc),y"); + AddCodeLine ("sta (c_sp),y"); } AddCodeLine ("bne %s", LocalLabelName (L1)); @@ -1284,7 +1284,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) g_defcodelabel (L); AddCodeLine ("inx"); AddCodeLine ("iny"); - AddCodeLine ("lda (spc),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("bne %s", LocalLabelName (L)); AddCodeLine ("txa"); AddCodeLine ("ldx #$00"); diff --git a/src/dbginfo/dbgsh.c b/src/dbginfo/dbgsh.c index 23a943c3b..280221fc9 100644 --- a/src/dbginfo/dbgsh.c +++ b/src/dbginfo/dbgsh.c @@ -458,7 +458,7 @@ static unsigned FindIdType (const char* TypeName) { "segment", SegmentId }, { "source", SourceId }, { "src", SourceId }, - { "spc", SpanId }, + { "c_sp", SpanId }, { "span", SpanId }, { "sym", SymbolId }, { "symbol", SymbolId }, diff --git a/src/sim65/main.c b/src/sim65/main.c index 98b33dacb..3cc9581b5 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -230,7 +230,7 @@ static unsigned char ReadProgramFile (void) } } - /* Get the address of spc from the file header */ + /* Get the address of c_sp from the file header */ if ((Val = fgetc(F)) != EOF) { SPAddr = Val; } diff --git a/targettest/atari/mem.c b/targettest/atari/mem.c index b72866ee9..f063d1e46 100644 --- a/targettest/atari/mem.c +++ b/targettest/atari/mem.c @@ -41,7 +41,7 @@ int main(void) printf(" data: $%04X (data)\n", &data); printf(" _dos_type: $%04X (bss)\n", &_dos_type); printf(" allocmem: $%04X (dyn. data)\n", allocmem); - printf(" spc: $%04X (stack ptr)\n", getsp()); + printf(" c_sp: $%04X (stack ptr)\n", getsp()); if (allocmem) free(allocmem); if (doesclrscrafterexit()) cgetc(); diff --git a/targettest/ft.c b/targettest/ft.c index ecaf72519..a28795f2b 100644 --- a/targettest/ft.c +++ b/targettest/ft.c @@ -10,7 +10,7 @@ ** got one from argv). I then opens the file, ** reads the first 16 bytes and displays them ** (as hex values). -** The values of spc (cc65 runtime stack pointer) +** The values of c_sp (cc65 runtime stack pointer) ** are displayed at some places. The displayed ** value should always be the same. */ @@ -64,16 +64,16 @@ int main(int argc,char **argv) } printf("using filename \"%s\"\n",filename); csp = getsp(); - printf("now opening file... spc = %d\n",csp); + printf("now opening file... c_sp = %d\n",csp); fd = open(filename,O_RDONLY); csp = getsp(); if (fd == -1) { char x1 = _oserror; - printf("open failed: os: %d,\n\terrno: %d, spc = %d\n",x1,errno,csp); + printf("open failed: os: %d,\n\terrno: %d, c_sp = %d\n",x1,errno,csp); cgetc(); return(0); } - printf("open success -- handle = $%x, spc = %d\n",fd,csp); + printf("open success -- handle = $%x, c_sp = %d\n",fd,csp); #ifdef __ATARI__ printf("fd_index:\n "); for (i=0; i<12; i++) printf("%02X ",__fd_index[i]); @@ -88,7 +88,7 @@ int main(int argc,char **argv) lr = read(fd,buf,16); /* read first 16 bytes */ csp = getsp(); if (lr == -1) { - printf("read failed: %d (spc = %d)\n",errno,csp); + printf("read failed: %d (c_sp = %d)\n",errno,csp); cgetc(); return(0); } @@ -99,7 +99,7 @@ int main(int argc,char **argv) return(0); } csp = getsp(); - printf("\n\nThe data read: (%d bytes, spc = %d)\n",lr,csp); + printf("\n\nThe data read: (%d bytes, c_sp = %d)\n",lr,csp); for (i=0; i<lr; i++) { printf("%02X ",buf[i]); if (!((i+1) & 7)) printf("\n"); diff --git a/targettest/getsp.s b/targettest/getsp.s index 6f0d4bdde..95db689f4 100644 --- a/targettest/getsp.s +++ b/targettest/getsp.s @@ -1,11 +1,11 @@ .export _getsp - .importzp spc + .importzp c_sp .proc _getsp - ldx spc+1 - lda spc + ldx c_sp+1 + lda c_sp rts .endproc diff --git a/test/asm/opcodes/m740-opcodes.s b/test/asm/opcodes/m740-opcodes.s index 1cdafc9c8..3ea91cf5f 100644 --- a/test/asm/opcodes/m740-opcodes.s +++ b/test/asm/opcodes/m740-opcodes.s @@ -36,7 +36,7 @@ bbr1 $12,*+122 ; clb 0,zp jsr $3456 and ($12,x) - .byte $22,$00,$00 ; jsr spc + .byte $22,$00,$00 ; jsr c_sp .byte $23,$00,$00 ; bbs 1,a bit $12 and $12 diff --git a/test/val/bug1652-optimizer.c b/test/val/bug1652-optimizer.c index 9ddb9c25c..97d0c5e4d 100644 --- a/test/val/bug1652-optimizer.c +++ b/test/val/bug1652-optimizer.c @@ -10,9 +10,9 @@ before: jsr pusha ldy #$01 ldx #$00 - lda (spc),y + lda (c_sp),y beq L0005 - lda (spc,x) + lda (c_sp,x) beq L0005 txa jmp incsp2 ; <-- @@ -24,9 +24,9 @@ after: jsr pusha ldy #$01 ldx #$00 - lda (spc),y + lda (c_sp),y beq L0004 - lda (spc,x) + lda (c_sp,x) beq L0004 txa jmp L0001 ; <-- diff --git a/test/val/cq85.c b/test/val/cq85.c index 566dbaeb1..ce836b649 100644 --- a/test/val/cq85.c +++ b/test/val/cq85.c @@ -62,7 +62,7 @@ int s85(struct defs *pd0){ struct tnode *right; }; - struct tnode s1, s2, *spc; + struct tnode s1, s2, *c_sp; struct{ char cdummy; From a0772cfa10d879d9f91dd25855a3519c1b1626a5 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Wed, 4 Jun 2025 06:43:29 +0000 Subject: [PATCH 460/707] one more comment --- src/cc65/codeinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 5e5c431aa..37b7bf68f 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -90,6 +90,7 @@ struct FuncInfo { ** routines are marked to use only the A register. The remainder is ignored ** anyway. */ +/* MUST BE SORTED BY NAME !!! */ static const FuncInfo FuncInfoTable[] = { { "addeq0sp", SLV_TOP | REG_AX, PSTATE_ALL | REG_AXY }, { "addeqysp", SLV_IND | REG_AXY, PSTATE_ALL | REG_AXY }, From de524a6561a86e218225f3b21e3ca5881e4a2861 Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Wed, 4 Jun 2025 22:51:17 +0300 Subject: [PATCH 461/707] Initial Agat support --- asminc/agat.inc | 38 ++++++++++++++ cfg/agat.cfg | 44 ++++++++++++++++ include/agat.h | 67 ++++++++++++++++++++++++ libsrc/Makefile | 3 +- libsrc/agat/break.s | 113 ++++++++++++++++++++++++++++++++++++++++ libsrc/agat/cclear.s | 17 ++++++ libsrc/agat/cgetc.s | 23 ++++++++ libsrc/agat/clrscr.s | 10 ++++ libsrc/agat/color.s | 21 ++++++++ libsrc/agat/cout.s | 14 +++++ libsrc/agat/cputc.s | 45 ++++++++++++++++ libsrc/agat/crt0.s | 25 +++++++++ libsrc/agat/exehdr.s | 40 ++++++++++++++ libsrc/agat/gotoxy.s | 28 ++++++++++ libsrc/agat/gotoy.s | 18 +++++++ libsrc/agat/home.s | 15 ++++++ libsrc/agat/kbhit.s | 19 +++++++ libsrc/agat/randomize.s | 18 +++++++ libsrc/agat/revers.s | 38 ++++++++++++++ libsrc/agat/vtabz.s | 24 +++++++++ libsrc/agat/wherex.s | 19 +++++++ libsrc/agat/wherey.s | 17 ++++++ libsrc/agat/write.s | 50 ++++++++++++++++++ src/ca65/main.c | 4 ++ src/cc65/main.c | 4 ++ src/common/target.c | 22 +++++++- src/common/target.h | 1 + 27 files changed, 735 insertions(+), 2 deletions(-) create mode 100644 asminc/agat.inc create mode 100644 cfg/agat.cfg create mode 100644 include/agat.h create mode 100644 libsrc/agat/break.s create mode 100644 libsrc/agat/cclear.s create mode 100644 libsrc/agat/cgetc.s create mode 100644 libsrc/agat/clrscr.s create mode 100644 libsrc/agat/color.s create mode 100644 libsrc/agat/cout.s create mode 100644 libsrc/agat/cputc.s create mode 100644 libsrc/agat/crt0.s create mode 100644 libsrc/agat/exehdr.s create mode 100644 libsrc/agat/gotoxy.s create mode 100644 libsrc/agat/gotoy.s create mode 100644 libsrc/agat/home.s create mode 100644 libsrc/agat/kbhit.s create mode 100644 libsrc/agat/randomize.s create mode 100644 libsrc/agat/revers.s create mode 100644 libsrc/agat/vtabz.s create mode 100644 libsrc/agat/wherex.s create mode 100644 libsrc/agat/wherey.s create mode 100644 libsrc/agat/write.s diff --git a/asminc/agat.inc b/asminc/agat.inc new file mode 100644 index 000000000..84d21dbc2 --- /dev/null +++ b/asminc/agat.inc @@ -0,0 +1,38 @@ + +;----------------------------------------------------------------------------- +; 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 + +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 diff --git a/cfg/agat.cfg b/cfg/agat.cfg new file mode 100644 index 000000000..1a740cfc7 --- /dev/null +++ b/cfg/agat.cfg @@ -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__; +} diff --git a/include/agat.h b/include/agat.h new file mode 100644 index 000000000..a8ed98bb0 --- /dev/null +++ b/include/agat.h @@ -0,0 +1,67 @@ +#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_ENTER 0x0D +#define CH_ESC 0x1B +#define CH_CURS_LEFT 0x08 +#define CH_CURS_RIGHT 0x15 + + +/* 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 //_AGAT_H diff --git a/libsrc/Makefile b/libsrc/Makefile index 8a4f11414..2f1b604d7 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -15,7 +15,8 @@ CBMS = c128 \ GEOS = geos-apple \ geos-cbm -TARGETS = apple2 \ +TARGETS = agat \ + apple2 \ apple2enh \ atari \ atarixl \ diff --git a/libsrc/agat/break.s b/libsrc/agat/break.s new file mode 100644 index 000000000..d46679ba2 --- /dev/null +++ b/libsrc/agat/break.s @@ -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 + diff --git a/libsrc/agat/cclear.s b/libsrc/agat/cclear.s new file mode 100644 index 000000000..65ae10049 --- /dev/null +++ b/libsrc/agat/cclear.s @@ -0,0 +1,17 @@ +; +; 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 diff --git a/libsrc/agat/cgetc.s b/libsrc/agat/cgetc.s new file mode 100644 index 000000000..a4b1389d2 --- /dev/null +++ b/libsrc/agat/cgetc.s @@ -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) + diff --git a/libsrc/agat/clrscr.s b/libsrc/agat/clrscr.s new file mode 100644 index 000000000..2fe54607a --- /dev/null +++ b/libsrc/agat/clrscr.s @@ -0,0 +1,10 @@ +; +; Kevin Ruland +; +; void clrscr (void); +; + + .export _clrscr + .import HOME + +_clrscr := HOME diff --git a/libsrc/agat/color.s b/libsrc/agat/color.s new file mode 100644 index 000000000..c68b6c3f6 --- /dev/null +++ b/libsrc/agat/color.s @@ -0,0 +1,21 @@ +; +; 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 + diff --git a/libsrc/agat/cout.s b/libsrc/agat/cout.s new file mode 100644 index 000000000..30b054b7e --- /dev/null +++ b/libsrc/agat/cout.s @@ -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) diff --git a/libsrc/agat/cputc.s b/libsrc/agat/cputc.s new file mode 100644 index 000000000..b30b6c45c --- /dev/null +++ b/libsrc/agat/cputc.s @@ -0,0 +1,45 @@ +; +; Oleg A. Odintsov, Moscow, 2024 +; +; void __fastcall__ cputcxy (unsigned char x, unsigned char y, char c); +; void __fastcall__ cputc (char c); +; + + .import COUT + .export _cputcxy, _cputc + .import gotoxy, VTABZ + .include "agat.inc" + +_cputcxy: + pha + jsr gotoxy + pla +_cputc: + cmp #$0D + bne notleft + ldy #$00 + sty CH + rts +notleft:cmp #$0A + beq newline +putchar: + ldy CH + sta (BASL),Y + iny + lda TATTR + bmi wch + 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 diff --git a/libsrc/agat/crt0.s b/libsrc/agat/crt0.s new file mode 100644 index 000000000..d678a79c8 --- /dev/null +++ b/libsrc/agat/crt0.s @@ -0,0 +1,25 @@ +; +; Startup code for cc65 (Agat version) +; + + .export __STARTUP__ : absolute = 1 ; Mark as startup + + .import initlib, donelib + .import zerobss, callmain + .import __ONCE_LOAD__, __ONCE_SIZE__ ; Linker generated + + .include "zeropage.inc" + .include "agat.inc" + +; ------------------------------------------------------------------------ + + .segment "STARTUP" + lda HIMEM + ldx HIMEM+1 + sta sp + stx sp+1 + jsr initlib + jsr zerobss + jsr callmain + jsr donelib + rts diff --git a/libsrc/agat/exehdr.s b/libsrc/agat/exehdr.s new file mode 100644 index 000000000..72ea390e9 --- /dev/null +++ b/libsrc/agat/exehdr.s @@ -0,0 +1,40 @@ +; +; 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. +; + + .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: diff --git a/libsrc/agat/gotoxy.s b/libsrc/agat/gotoxy.s new file mode 100644 index 000000000..2f9580c91 --- /dev/null +++ b/libsrc/agat/gotoxy.s @@ -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 diff --git a/libsrc/agat/gotoy.s b/libsrc/agat/gotoy.s new file mode 100644 index 000000000..f4a8a4c4e --- /dev/null +++ b/libsrc/agat/gotoy.s @@ -0,0 +1,18 @@ +; +; 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 + + diff --git a/libsrc/agat/home.s b/libsrc/agat/home.s new file mode 100644 index 000000000..d3f000d25 --- /dev/null +++ b/libsrc/agat/home.s @@ -0,0 +1,15 @@ +; +; Oleg A. Odintsov, Moscow, 2024 +; +; HOME routine +; + + .export HOME + .import COUT + + .include "agat.inc" + +HOME: + lda #$8C + jsr COUT + rts diff --git a/libsrc/agat/kbhit.s b/libsrc/agat/kbhit.s new file mode 100644 index 000000000..f2bc4fc9f --- /dev/null +++ b/libsrc/agat/kbhit.s @@ -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 diff --git a/libsrc/agat/randomize.s b/libsrc/agat/randomize.s new file mode 100644 index 000000000..914f40634 --- /dev/null +++ b/libsrc/agat/randomize.s @@ -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 "apple2.inc" + +__randomize: + ldx RNDH ; Use random value supplied by ROM + lda RNDL + jmp _srand ; Initialize generator + diff --git a/libsrc/agat/revers.s b/libsrc/agat/revers.s new file mode 100644 index 000000000..ceca7cf5b --- /dev/null +++ b/libsrc/agat/revers.s @@ -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 diff --git a/libsrc/agat/vtabz.s b/libsrc/agat/vtabz.s new file mode 100644 index 000000000..a711a87c9 --- /dev/null +++ b/libsrc/agat/vtabz.s @@ -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 diff --git a/libsrc/agat/wherex.s b/libsrc/agat/wherex.s new file mode 100644 index 000000000..b6d277680 --- /dev/null +++ b/libsrc/agat/wherex.s @@ -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 diff --git a/libsrc/agat/wherey.s b/libsrc/agat/wherey.s new file mode 100644 index 000000000..4660a55f9 --- /dev/null +++ b/libsrc/agat/wherey.s @@ -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 diff --git a/libsrc/agat/write.s b/libsrc/agat/write.s new file mode 100644 index 000000000..6ac28f32c --- /dev/null +++ b/libsrc/agat/write.s @@ -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 + diff --git a/src/ca65/main.c b/src/ca65/main.c index f3100162a..c99ce06c6 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -350,6 +350,10 @@ static void SetSys (const char* Sys) NewSymbol ("__RP6502__", 1); break; + case TGT_AGAT: + NewSymbol ("__AGAT__", 1); + break; + default: AbEnd ("Invalid target name: '%s'", Sys); diff --git a/src/cc65/main.c b/src/cc65/main.c index 47435757c..baf6f2f17 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -306,6 +306,10 @@ static void SetSys (const char* Sys) case TGT_RP6502: DefineNumericMacro ("__RP6502__", 1); break; + + case TGT_AGAT: + DefineNumericMacro ("__AGAT__", 1); + break; default: AbEnd ("Unknown target system '%s'", Sys); diff --git a/src/common/target.c b/src/common/target.c index b50478e16..761f7c3fd 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -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, }; - +/* 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,0x5F, + 0x1B,0x5C,0x10,0x12,0x1D,0x1F,0x13,0x1C,0x11,0x1E,0x14,0x8B,0x8C,0x8D,0x8E,0x8F, + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, + 0xA0,0xA1,0xA2,0x0F,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, + 0xB0,0xB1,0xB2,0x9F,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, + 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 */ typedef struct TargetEntry TargetEntry; @@ -142,6 +160,7 @@ struct TargetEntry { ** Allows multiple entries for one target ID (target name aliases). */ static const TargetEntry TargetMap[] = { + { "agat", TGT_AGAT }, { "apple2", TGT_APPLE2 }, { "apple2enh", TGT_APPLE2ENH }, { "atari", TGT_ATARI }, @@ -223,6 +242,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "sym1", CPU_6502, BINFMT_BINARY, CTNone }, { "kim1", CPU_6502, BINFMT_BINARY, CTNone }, { "rp6502", CPU_65C02, BINFMT_BINARY, CTNone }, + { "agat", CPU_6502, BINFMT_BINARY, CTAgat }, }; /* Target system */ diff --git a/src/common/target.h b/src/common/target.h index 730b8211e..d6c9fc35b 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -89,6 +89,7 @@ typedef enum { TGT_SYM1, TGT_KIM1, TGT_RP6502, + TGT_AGAT, TGT_COUNT /* Number of target systems */ } target_t; From 5ff18c1ebc7179002b9be74262ea536d968ffaea Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Wed, 4 Jun 2025 23:11:13 +0300 Subject: [PATCH 462/707] Updates --- asminc/agat.inc | 1 + include/agat.h | 12 ++++++---- libsrc/agat/crt0.s | 57 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/asminc/agat.inc b/asminc/agat.inc index 84d21dbc2..b96d31834 100644 --- a/asminc/agat.inc +++ b/asminc/agat.inc @@ -22,6 +22,7 @@ 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 diff --git a/include/agat.h b/include/agat.h index a8ed98bb0..6333170c7 100644 --- a/include/agat.h +++ b/include/agat.h @@ -24,10 +24,14 @@ #define COLOR_WHITE 0x07 /* Characters codes */ -#define CH_ENTER 0x0D -#define CH_ESC 0x1B -#define CH_CURS_LEFT 0x08 -#define CH_CURS_RIGHT 0x15 +#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 /* Masks for joy_read */ diff --git a/libsrc/agat/crt0.s b/libsrc/agat/crt0.s index d678a79c8..9f8993332 100644 --- a/libsrc/agat/crt0.s +++ b/libsrc/agat/crt0.s @@ -3,6 +3,7 @@ ; .export __STARTUP__ : absolute = 1 ; Mark as startup + .export _exit .import initlib, donelib .import zerobss, callmain @@ -14,12 +15,60 @@ ; ------------------------------------------------------------------------ .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 - jsr initlib - jsr zerobss - jsr callmain - jsr donelib + 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 From 79ecb2071cc15964467165fb2a756ed2d8a25c6f Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Thu, 5 Jun 2025 02:09:11 +0200 Subject: [PATCH 463/707] Update Makefile - use ld65, not cl65, for linking --- samples/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index abdaa4ee8..f0c6835bb 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -149,9 +149,9 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000 .o: ifeq ($(SYS),vic20) - $(CL) $(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 - $(CL) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib + $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib endif # -------------------------------------------------------------------------- From c3b87779b7bf711dd35f8922e08886f7a6df9eee Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Thu, 5 Jun 2025 02:23:29 +0200 Subject: [PATCH 464/707] Update Makefile - link all Plus4 samples with plus4-hires.cfg - using the LDFLAGS mechanism for this does not work --- samples/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index f0c6835bb..44ef4377e 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -112,9 +112,6 @@ LDFLAGS_mandelbrot_apple2enh = --start-addr 0x4000 LDFLAGS_tgidemo_apple2 = --start-addr 0x4000 LDFLAGS_tgidemo_apple2enh = --start-addr 0x4000 -LDFLAGS_mandelbrot_plus4 = -C plus4-hires.cfg -LDFLAGS_tgidemo_plus4 = -C plus4-hires.cfg - # The Apple ][ needs the start address adjusted for the mousedemo LDFLAGS_mousedemo_apple2 = --start-addr 0x4000 @@ -150,6 +147,8 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000 .o: ifeq ($(SYS),vic20) $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib +else ifeq ($(SYS),plus4) + $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -C plus4-hires.cfg -m $@.map $^ $(SYS).lib else $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib endif From 1a109c0b3438928e1dce045799ae678a576584d0 Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Sat, 7 Jun 2025 12:36:49 +0300 Subject: [PATCH 465/707] Fix codestyle --- include/agat.h | 50 +++++++++++----------- libsrc/agat/cclear.s | 18 ++++---- libsrc/agat/cgetc.s | 29 +++++++------ libsrc/agat/clrscr.s | 4 +- libsrc/agat/color.s | 21 +++++----- libsrc/agat/cout.s | 12 +++--- libsrc/agat/cputc.s | 68 +++++++++++++++--------------- libsrc/agat/crt0.s | 98 ++++++++++++++++++++++---------------------- libsrc/agat/gotoxy.s | 22 +++++----- libsrc/agat/gotoy.s | 16 ++++---- libsrc/agat/home.s | 6 +-- libsrc/agat/revers.s | 46 ++++++++++----------- libsrc/agat/vtabz.s | 32 +++++++-------- libsrc/agat/wherex.s | 12 +++--- 14 files changed, 215 insertions(+), 219 deletions(-) diff --git a/include/agat.h b/include/agat.h index 6333170c7..2cdf24ae6 100644 --- a/include/agat.h +++ b/include/agat.h @@ -14,38 +14,38 @@ /* 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 +#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_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 /* 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 +#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 */ +#define AGAT_UNKNOWN 0x00 +#define AGAT_7 0x10 /* Agat 7 */ +#define AGAT_9 0x20 /* Agat 9 */ /*****************************************************************************/ diff --git a/libsrc/agat/cclear.s b/libsrc/agat/cclear.s index 65ae10049..dcc5834ad 100644 --- a/libsrc/agat/cclear.s +++ b/libsrc/agat/cclear.s @@ -4,14 +4,14 @@ ; void __fastcall__ cclear (unsigned char length); ; - .export _cclear - .import COUT - .include "zeropage.inc" + .export _cclear + .import COUT + .include "zeropage.inc" _cclear: - sta ptr1 - lda #$A0 -next: jsr COUT - dec ptr1 - bne next - rts + sta ptr1 + lda #$A0 +next: jsr COUT + dec ptr1 + bne next + rts diff --git a/libsrc/agat/cgetc.s b/libsrc/agat/cgetc.s index a4b1389d2..18bba2fd8 100644 --- a/libsrc/agat/cgetc.s +++ b/libsrc/agat/cgetc.s @@ -4,20 +4,19 @@ ; char cgetc (void); ; - .export _cgetc - .import cursor - .include "agat.inc" + .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) - + lda #$DF ; _ + bit cursor + bne hascur + lda #$00 +hascur: sta CURSOR + jsr j1 + cmp #$A0 + bpl :+ + and #$7F +: rts +j1: jmp (VCIN) diff --git a/libsrc/agat/clrscr.s b/libsrc/agat/clrscr.s index 2fe54607a..8b2d7100b 100644 --- a/libsrc/agat/clrscr.s +++ b/libsrc/agat/clrscr.s @@ -4,7 +4,7 @@ ; void clrscr (void); ; - .export _clrscr - .import HOME + .export _clrscr + .import HOME _clrscr := HOME diff --git a/libsrc/agat/color.s b/libsrc/agat/color.s index c68b6c3f6..0992bb860 100644 --- a/libsrc/agat/color.s +++ b/libsrc/agat/color.s @@ -5,17 +5,16 @@ ; - .export _textcolor - .include "agat.inc" + .export _textcolor + .include "agat.inc" _textcolor: - ldx TATTR - eor TATTR - and #$07 - eor TATTR - sta TATTR - txa - and #$0F - rts - + ldx TATTR + eor TATTR + and #$07 + eor TATTR + sta TATTR + txa + and #$0F + rts diff --git a/libsrc/agat/cout.s b/libsrc/agat/cout.s index 30b054b7e..ae9d8a177 100644 --- a/libsrc/agat/cout.s +++ b/libsrc/agat/cout.s @@ -4,11 +4,11 @@ ; COUT routine ; - .export COUT - .include "agat.inc" + .export COUT + .include "agat.inc" COUT: - cmp #$10 - bpl out - ora #$80 -out: jmp (VCOUT) + cmp #$10 + bpl out + ora #$80 +out: jmp (VCOUT) diff --git a/libsrc/agat/cputc.s b/libsrc/agat/cputc.s index b30b6c45c..6bf9b604f 100644 --- a/libsrc/agat/cputc.s +++ b/libsrc/agat/cputc.s @@ -5,41 +5,41 @@ ; void __fastcall__ cputc (char c); ; - .import COUT - .export _cputcxy, _cputc - .import gotoxy, VTABZ - .include "agat.inc" + .import COUT + .export _cputcxy, _cputc + .import gotoxy, VTABZ + .include "agat.inc" _cputcxy: - pha - jsr gotoxy - pla + pha + jsr gotoxy + pla _cputc: - cmp #$0D - bne notleft - ldy #$00 - sty CH - rts -notleft:cmp #$0A - beq newline + cmp #$0D + bne notleft + ldy #$00 + sty CH + rts +notleft:cmp #$0A + beq newline putchar: - ldy CH - sta (BASL),Y - iny - lda TATTR - bmi wch - 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 + ldy CH + sta (BASL),Y + iny + lda TATTR + bmi wch + 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 diff --git a/libsrc/agat/crt0.s b/libsrc/agat/crt0.s index 9f8993332..78fef06bc 100644 --- a/libsrc/agat/crt0.s +++ b/libsrc/agat/crt0.s @@ -14,61 +14,61 @@ ; ------------------------------------------------------------------------ - .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 "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" + .segment "ONCE" -init: ldx #zpspace-1 -: lda sp,x - sta zpsave,x - dex - bpl :- +init: ldx #zpspace-1 +: lda sp,x + sta zpsave,x + dex + bpl :- - ldx #$02 -: lda SOFTEV,x - sta rvsave,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 + lda HIMEM + ldx HIMEM+1 + sta sp + stx sp+1 + ldx #<_exit + lda #>_exit + jsr reset + jmp initlib - .code + .code -reset: stx SOFTEV - sta SOFTEV+1 - eor #$A5 - sta PWREDUP - rts +reset: stx SOFTEV + sta SOFTEV+1 + eor #$A5 + sta PWREDUP + rts - .segment "INIT" -zpsave: .res zpspace -rvsave: .res 3 + .segment "INIT" +zpsave: .res zpspace +rvsave: .res 3 diff --git a/libsrc/agat/gotoxy.s b/libsrc/agat/gotoxy.s index 2f9580c91..13e7cb747 100644 --- a/libsrc/agat/gotoxy.s +++ b/libsrc/agat/gotoxy.s @@ -12,17 +12,17 @@ .include "agat.inc" gotoxy: - jsr popa ; Get Y + jsr popa ; Get Y _gotoxy: - clc - adc WNDTOP - sta CV ; Store Y - jsr VTABZ - jsr popa ; Get X + clc + adc WNDTOP + sta CV ; Store Y + jsr VTABZ + jsr popa ; Get X _gotox: - bit TATTR - bmi t64 - asl + bit TATTR + bmi t64 + asl t64: - sta CH ; Store X - rts + sta CH ; Store X + rts diff --git a/libsrc/agat/gotoy.s b/libsrc/agat/gotoy.s index f4a8a4c4e..ea0eadbf2 100644 --- a/libsrc/agat/gotoy.s +++ b/libsrc/agat/gotoy.s @@ -5,14 +5,12 @@ ; void __fastcall__ gotoy (unsigned char y); ; - .import VTABZ - .export _gotoy - .include "agat.inc" + .import VTABZ + .export _gotoy + .include "agat.inc" _gotoy: - clc - adc WNDTOP - sta CV - jmp VTABZ - - + clc + adc WNDTOP + sta CV + jmp VTABZ diff --git a/libsrc/agat/home.s b/libsrc/agat/home.s index d3f000d25..5067a782a 100644 --- a/libsrc/agat/home.s +++ b/libsrc/agat/home.s @@ -10,6 +10,6 @@ .include "agat.inc" HOME: - lda #$8C - jsr COUT - rts + lda #$8C + jsr COUT + rts diff --git a/libsrc/agat/revers.s b/libsrc/agat/revers.s index ceca7cf5b..20c1b9bdb 100644 --- a/libsrc/agat/revers.s +++ b/libsrc/agat/revers.s @@ -6,33 +6,33 @@ ; unsigned char __fastcall__ flash (unsigned char onoff) ; - .export _revers, _flash + .export _revers, _flash - .include "agat.inc" + .include "agat.inc" _revers: - tax - beq noinv - lda TATTR - and #$D7 - sta TATTR - rts + tax + beq noinv + lda TATTR + and #$D7 + sta TATTR + rts noinv: - lda TATTR - ora #$20 - sta TATTR - rts + lda TATTR + ora #$20 + sta TATTR + rts _flash: - tax - beq noflash - lda TATTR - and #$DF - ora #$08 - sta TATTR - rts + tax + beq noflash + lda TATTR + and #$DF + ora #$08 + sta TATTR + rts noflash: - lda TATTR - ora #$20 - sta TATTR - rts + lda TATTR + ora #$20 + sta TATTR + rts diff --git a/libsrc/agat/vtabz.s b/libsrc/agat/vtabz.s index a711a87c9..88166eb35 100644 --- a/libsrc/agat/vtabz.s +++ b/libsrc/agat/vtabz.s @@ -4,21 +4,21 @@ ; VTABZ routine ; - .export VTABZ - .include "agat.inc" + .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 + lda CV + ror + ror + ror + and #$C0 + sta BASL + lda CV + lsr + lsr + eor BASH + and #$07 + eor BASH + sta BASH + rts diff --git a/libsrc/agat/wherex.s b/libsrc/agat/wherex.s index b6d277680..a83f7cd75 100644 --- a/libsrc/agat/wherex.s +++ b/libsrc/agat/wherex.s @@ -10,10 +10,10 @@ .include "agat.inc" _wherex: - lda CH - bit TATTR - bmi t64 - lsr + lda CH + bit TATTR + bmi t64 + lsr t64: - ldx #$00 - rts + ldx #$00 + rts From cbf1b1d5a7857e7e3248787f61cf9d9058a784f5 Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Sat, 7 Jun 2025 14:00:10 +0300 Subject: [PATCH 466/707] Updated translation table --- src/common/target.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/common/target.c b/src/common/target.c index 761f7c3fd..fc1a9df25 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -138,11 +138,11 @@ static unsigned char CTAgat[256] = { 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,0x5F, - 0x1B,0x5C,0x10,0x12,0x1D,0x1F,0x13,0x1C,0x11,0x1E,0x14,0x8B,0x8C,0x8D,0x8E,0x8F, - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, - 0xA0,0xA1,0xA2,0x0F,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, - 0xB0,0xB1,0xB2,0x9F,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, + 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, From 34daf33d932eaf4f0ea832b7656b591b4b47ee21 Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Sat, 7 Jun 2025 14:10:50 +0300 Subject: [PATCH 467/707] Remove dangling spaces --- src/ca65/main.c | 2 +- src/cc65/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index c99ce06c6..682e9be7f 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -353,7 +353,7 @@ static void SetSys (const char* Sys) case TGT_AGAT: NewSymbol ("__AGAT__", 1); break; - + default: AbEnd ("Invalid target name: '%s'", Sys); diff --git a/src/cc65/main.c b/src/cc65/main.c index baf6f2f17..f56974361 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -306,7 +306,7 @@ static void SetSys (const char* Sys) case TGT_RP6502: DefineNumericMacro ("__RP6502__", 1); break; - + case TGT_AGAT: DefineNumericMacro ("__AGAT__", 1); break; From 41a82f7165030ec0e0cddf225c720398aab813ec Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Sun, 8 Jun 2025 23:20:21 +0300 Subject: [PATCH 468/707] fix codestyle --- libsrc/agat/_scrsize.s | 17 +++++++++++++++++ libsrc/agat/cclear.s | 3 ++- libsrc/agat/cgetc.s | 3 ++- libsrc/agat/cputc.s | 12 ++++++++---- libsrc/agat/crt0.s | 12 ++++++++---- libsrc/agat/randomize.s | 2 +- 6 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 libsrc/agat/_scrsize.s diff --git a/libsrc/agat/_scrsize.s b/libsrc/agat/_scrsize.s new file mode 100644 index 000000000..f9d7c3785 --- /dev/null +++ b/libsrc/agat/_scrsize.s @@ -0,0 +1,17 @@ +; +; Ullrich von Bassewitz, 26.10.2000 +; +; Screen size variables +; + + .export screensize + + .include "agat.inc" + +screensize: + ldx WNDWDTH + lda WNDBTM + sec + sbc WNDTOP + tay + rts diff --git a/libsrc/agat/cclear.s b/libsrc/agat/cclear.s index dcc5834ad..93a561ef4 100644 --- a/libsrc/agat/cclear.s +++ b/libsrc/agat/cclear.s @@ -11,7 +11,8 @@ _cclear: sta ptr1 lda #$A0 -next: jsr COUT +next: + jsr COUT dec ptr1 bne next rts diff --git a/libsrc/agat/cgetc.s b/libsrc/agat/cgetc.s index 18bba2fd8..839e4314a 100644 --- a/libsrc/agat/cgetc.s +++ b/libsrc/agat/cgetc.s @@ -13,7 +13,8 @@ _cgetc: bit cursor bne hascur lda #$00 -hascur: sta CURSOR +hascur: + sta CURSOR jsr j1 cmp #$A0 bpl :+ diff --git a/libsrc/agat/cputc.s b/libsrc/agat/cputc.s index 6bf9b604f..b8d99aaea 100644 --- a/libsrc/agat/cputc.s +++ b/libsrc/agat/cputc.s @@ -20,7 +20,8 @@ _cputc: ldy #$00 sty CH rts -notleft:cmp #$0A +notleft: + cmp #$0A beq newline putchar: ldy CH @@ -30,16 +31,19 @@ putchar: bmi wch sta (BASL),Y iny -wch:sty CH +wch: + sty CH cpy WNDWDTH bcc noend ldy #$00 sty CH -newline:inc CV +newline: + inc CV lda CV cmp WNDBTM bcc :+ lda WNDTOP sta CV : jmp VTABZ -noend: rts +noend: + rts diff --git a/libsrc/agat/crt0.s b/libsrc/agat/crt0.s index 78fef06bc..41f03b24d 100644 --- a/libsrc/agat/crt0.s +++ b/libsrc/agat/crt0.s @@ -18,11 +18,13 @@ jsr init jsr zerobss jsr callmain -_exit: ldx #<exit +_exit: + ldx #<exit lda #>exit jsr reset jsr donelib -exit: ldx #$02 +exit: + ldx #$02 : lda rvsave,x sta SOFTEV,x dex @@ -40,7 +42,8 @@ exit: ldx #$02 .segment "ONCE" -init: ldx #zpspace-1 +init: + ldx #zpspace-1 : lda sp,x sta zpsave,x dex @@ -63,7 +66,8 @@ init: ldx #zpspace-1 .code -reset: stx SOFTEV +reset: + stx SOFTEV sta SOFTEV+1 eor #$A5 sta PWREDUP diff --git a/libsrc/agat/randomize.s b/libsrc/agat/randomize.s index 914f40634..9eef16f05 100644 --- a/libsrc/agat/randomize.s +++ b/libsrc/agat/randomize.s @@ -9,7 +9,7 @@ .export __randomize .import _srand - .include "apple2.inc" + .include "agat.inc" __randomize: ldx RNDH ; Use random value supplied by ROM From 4d5a290135950b5f5c97e9d6b9a5a25f992ba98e Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Sun, 8 Jun 2025 23:30:34 +0300 Subject: [PATCH 469/707] add docs and readme.md --- README.md | 1 + doc/agat.sgml | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ doc/index.sgml | 3 ++ 3 files changed, 83 insertions(+) create mode 100644 doc/agat.sgml diff --git a/README.md b/README.md index e3f1ab30f..4c1003179 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ the [cc65 web site](https://cc65.github.io): | Dr. Jozo Dujmović | Picocomputer (RP6502) | | Watara | Watura/QuickShot Supervision | | Synertek | SYM-1 | +| USSR | Agat 7/9 | A generic configuration to adapt cc65 to new targets is also around. diff --git a/doc/agat.sgml b/doc/agat.sgml new file mode 100644 index 000000000..1238dd394 --- /dev/null +++ b/doc/agat.sgml @@ -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> diff --git a/doc/index.sgml b/doc/index.sgml index 92df5e018..e39fd11b4 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -109,6 +109,9 @@ <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> Topics specific to the Apple ][. From fb421d7a81e3cc89f17f26e50621a3382864626f Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Sun, 8 Jun 2025 23:44:51 +0300 Subject: [PATCH 470/707] Remove dangling spaces --- doc/agat.sgml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/agat.sgml b/doc/agat.sgml index 1238dd394..ca5338c5f 100644 --- a/doc/agat.sgml +++ b/doc/agat.sgml @@ -18,16 +18,16 @@ compiler. <sect>Overview -<p>The Agat was a series of 8-bit computers produced in the Soviet Union from 1983 to 1993. +<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. +<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. +<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 +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. From ba80de5efc99b4173fe3b0946fc480e4fa459dac Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 9 Jun 2025 17:58:58 +0200 Subject: [PATCH 471/707] fix bsearch tables that must be sorted, add comment to all tables that must be sorted --- src/ca65/instr.c | 9 +++++++++ src/ca65/scanner.c | 1 + src/cc65/codeinfo.c | 10 ++++++---- src/cc65/codeopt.c | 18 ++++++++++-------- src/cc65/codeoptutil.c | 8 ++++---- src/cc65/coptstop.c | 2 ++ src/cc65/opcodes.c | 1 + src/cc65/pragma.c | 1 + src/cc65/preproc.c | 1 + src/cc65/scanner.c | 1 + src/cc65/stdfunc.c | 5 ++--- src/common/filetype.c | 1 + src/common/target.c | 3 ++- src/dbginfo/dbginfo.c | 1 + src/sp65/convert.c | 3 ++- src/sp65/input.c | 3 ++- src/sp65/output.c | 3 ++- src/sp65/palconv.c | 3 ++- 18 files changed, 50 insertions(+), 24 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index da6bd6e44..f1d8d706a 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -169,6 +169,7 @@ static const struct { unsigned Count; InsDesc Ins[56]; } InsTab6502 = { + /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab6502.Ins) / sizeof (InsTab6502.Ins[0]), { { "ADC", 0x080A26C, 0x60, 0, PutAll }, @@ -235,6 +236,7 @@ static const struct { unsigned Count; InsDesc Ins[75]; } InsTab6502X = { + /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab6502X.Ins) / sizeof (InsTab6502X.Ins[0]), { { "ADC", 0x080A26C, 0x60, 0, PutAll }, @@ -324,6 +326,7 @@ static const struct { unsigned Count; InsDesc Ins[71]; } InsTab6502DTV = { + /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab6502DTV.Ins) / sizeof (InsTab6502DTV.Ins[0]), { { "ADC", 0x080A26C, 0x60, 0, PutAll }, @@ -405,6 +408,7 @@ static const struct { unsigned Count; InsDesc Ins[66]; } InsTab65SC02 = { + /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab65SC02.Ins) / sizeof (InsTab65SC02.Ins[0]), { { "ADC", 0x080A66C, 0x60, 0, PutAll }, @@ -481,6 +485,7 @@ static const struct { unsigned Count; InsDesc Ins[100]; } InsTab65C02 = { + /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab65C02.Ins) / sizeof (InsTab65C02.Ins[0]), { { "ADC", 0x080A66C, 0x60, 0, PutAll }, @@ -591,6 +596,7 @@ static const struct { unsigned Count; InsDesc Ins[133]; } InsTab4510 = { + /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab4510.Ins) / sizeof (InsTab4510.Ins[0]), { { "ADC", 0x080A66C, 0x60, 0, PutAll }, @@ -734,6 +740,7 @@ static const struct { unsigned Count; InsDesc Ins[100]; } InsTab65816 = { + /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab65816.Ins) / sizeof (InsTab65816.Ins[0]), { { "ADC", 0x0b8f6fc, 0x60, 0, PutAll }, @@ -844,6 +851,7 @@ static const struct { unsigned Count; InsDesc Ins[26]; } InsTabSweet16 = { + /* CAUTION: table must be sorted for bsearch */ sizeof (InsTabSweet16.Ins) / sizeof (InsTabSweet16.Ins[0]), { { "ADD", AMSW16_REG, 0xA0, 0, PutSweet16 }, @@ -880,6 +888,7 @@ static const struct { unsigned Count; InsDesc Ins[135]; } InsTabHuC6280 = { + /* CAUTION: table must be sorted for bsearch */ sizeof (InsTabHuC6280.Ins) / sizeof (InsTabHuC6280.Ins[0]), { { "ADC", 0x080A66C, 0x60, 0, PutAll }, diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index da9883e52..11beb4d63 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -131,6 +131,7 @@ static int C = 0; /* Current input character */ int ForcedEnd = 0; /* List of dot keywords with the corresponding tokens */ +/* CAUTION: table must be sorted for bsearch */ struct DotKeyword { const char* Key; /* MUST be first field */ token_t Tok; diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 435794613..8396ecfd5 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -90,6 +90,7 @@ struct FuncInfo { ** routines are marked to use only the A register. The remainder is ignored ** anyway. */ +/* CAUTION: table must be sorted for bsearch */ static const FuncInfo FuncInfoTable[] = { { "addeq0sp", SLV_TOP | REG_AX, PSTATE_ALL | REG_AXY }, { "addeqysp", SLV_IND | REG_AXY, PSTATE_ALL | REG_AXY }, @@ -190,12 +191,12 @@ static const FuncInfo FuncInfoTable[] = { { "ldeaxysp", SLV_IND | REG_Y, PSTATE_ALL | REG_EAXY }, { "leaa0sp", REG_SP | REG_A, 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 }, - { "leavey00", REG_SP, PSTATE_ALL | REG_SP | REG_AXY }, - { "leavey0", REG_SP, PSTATE_ALL | REG_SP | REG_XY }, + { "leave0", 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 }, + { "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 }, { "lsubeq0sp", SLV_TOP | REG_EAX, PSTATE_ALL | REG_EAXY }, { "lsubeq1", REG_Y | REG_PTR1_LO, PSTATE_ALL | REG_EAXY | REG_PTR1_HI }, @@ -380,6 +381,7 @@ static const FuncInfo FuncInfoTable[] = { #define FuncInfoCount (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0])) /* Table with names of zero page locations used by the compiler */ +/* CAUTION: table must be sorted for bsearch */ static const ZPInfo ZPInfoTable[] = { { 0, "ptr1", 2, REG_PTR1_LO, REG_PTR1 }, { 0, "ptr1+1", 1, REG_PTR1_HI, REG_PTR1 }, diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index a716ad431..9de2ab7ba 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -102,6 +102,7 @@ struct OptFunc { /* A list of all the function descriptions */ +/* CAUTION: should be sorted by "name" */ static OptFunc DOpt65C02BitOps = { Opt65C02BitOps, "Opt65C02BitOps", 66, 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 }; @@ -152,18 +153,13 @@ static OptFunc DOptJumpTarget3 = { OptJumpTarget3, "OptJumpTarget3", 100, 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 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 DOptLongCopy = { OptLongCopy, "OptLongCopy", 100, 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 DOptPrecalc = { OptPrecalc, "OptPrecalc", 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 DOptPtrLoad12 = { OptPtrLoad12, "OptPtrLoad12", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrLoad13 = { OptPtrLoad13, "OptPtrLoad13", 65, 0, 0, 0, 0, 0 }; @@ -173,6 +169,12 @@ static OptFunc DOptPtrLoad16 = { OptPtrLoad16, "OptPtrLoad16", 100, 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 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 DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 65, 0, 0, 0, 0, 0 }; static OptFunc DOptPtrStore3 = { OptPtrStore3, "OptPtrStore3", 100, 0, 0, 0, 0, 0 }; @@ -202,7 +204,6 @@ static OptFunc DOptStore3 = { OptStore3, "OptStore3", 120, 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 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 DOptSub2 = { OptSub2, "OptSub2", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptSub3 = { OptSub3, "OptSub3", 100, 0, 0, 0, 0, 0 }; @@ -217,6 +218,7 @@ static OptFunc DOptUnusedStores = { OptUnusedStores, "OptUnusedStores", 0, 0, /* Table containing all the steps in alphabetical order */ +/* CAUTION: table must be sorted for bsearch */ static OptFunc* OptFuncs[] = { &DOpt65C02BitOps, &DOpt65C02Ind, @@ -268,6 +270,7 @@ static OptFunc* OptFuncs[] = { &DOptLoad1, &DOptLoad2, &DOptLoad3, + &DOptLoadStoreLoad, &DOptLongAssign, &DOptLongCopy, &DOptNegAX1, @@ -318,7 +321,6 @@ static OptFunc* OptFuncs[] = { &DOptStore4, &DOptStore5, &DOptStoreLoad, - &DOptLoadStoreLoad, &DOptSub1, &DOptSub2, &DOptSub3, diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 43b1dee22..c18ccf18b 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -1225,6 +1225,10 @@ static int CmpHarmless (const void* Key, const void* Entry) } +/* CAUTION: table must be sorted for bsearch */ +static const char* const Tab[] = { + "_abs", +}; int HarmlessCall (const CodeEntry* E, int PushedBytes) /* Check if this is a call to a harmless subroutine that will not interrupt @@ -1252,10 +1256,6 @@ int HarmlessCall (const CodeEntry* E, int PushedBytes) } return 1; } else { - static const char* const Tab[] = { - "_abs", - }; - void* R = bsearch (E->Arg, Tab, sizeof (Tab) / sizeof (Tab[0]), diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 402f16b97..90ab78c50 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1464,6 +1464,7 @@ static unsigned Opt_a_tosxor (StackOpData* D) /* The first column of these two tables must be sorted in lexical order */ +/* CAUTION: table must be sorted for bsearch */ static const OptFuncDesc FuncTable[] = { { "___bzero", Opt___bzero, REG_NONE, OP_X_ZERO | OP_A_KNOWN }, { "staspidx", Opt_staspidx, REG_NONE, OP_NONE }, @@ -1487,6 +1488,7 @@ static const OptFuncDesc FuncTable[] = { { "tosxorax", Opt_tosxorax, REG_NONE, OP_NONE }, }; +/* CAUTION: table must be sorted for bsearch */ static const OptFuncDesc FuncRegATable[] = { { "tosandax", Opt_a_tosand, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, { "toseqax", Opt_a_toseq, REG_NONE, OP_NONE }, diff --git a/src/cc65/opcodes.c b/src/cc65/opcodes.c index aeea0297b..c591c4ea3 100644 --- a/src/cc65/opcodes.c +++ b/src/cc65/opcodes.c @@ -55,6 +55,7 @@ /* Opcode description table */ +/* CAUTION: table must be sorted by mnemonic for bsearch */ const OPCDesc OPCTable[OP65_COUNT] = { /* 65XX opcodes */ diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index ee71b42d8..5de4c8dfc 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -89,6 +89,7 @@ typedef enum { } pragma_t; /* Pragma table */ +/* CAUTION: table must be sorted for bsearch */ static const struct Pragma { const char* Key; /* Keyword */ pragma_t Tok; /* Token */ diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 5cdec3142..d70c28147 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -216,6 +216,7 @@ typedef enum { /* Preprocessor directive tokens mapping table */ +/* CAUTION: table must be sorted for bsearch */ static const struct PPDType { const char* Tok; /* Token */ ppdirective_t Type; /* Type */ diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index f0ff664fd..1549b51bd 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -87,6 +87,7 @@ enum { }; /* Token table */ +/* CAUTION: table must be sorted for bsearch */ static const struct Keyword { char* Key; /* Keyword name */ unsigned char Tok; /* The token */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 2889a176e..3bd3f3552 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -78,8 +78,8 @@ static void StdFunc_strlen (FuncDesc*, ExprDesc*); -/* Table with all known functions and their handlers. Must be sorted -** alphabetically! +/* Table with all known functions and their handlers. +** CAUTION: table must be alphabetically sorted for bsearch */ static struct StdFuncDesc { const char* Name; @@ -90,7 +90,6 @@ static struct StdFuncDesc { { "strcmp", StdFunc_strcmp }, { "strcpy", StdFunc_strcpy }, { "strlen", StdFunc_strlen }, - }; #define FUNC_COUNT (sizeof (StdFuncs) / sizeof (StdFuncs[0])) diff --git a/src/common/filetype.c b/src/common/filetype.c index ae8b636dc..4aececa78 100644 --- a/src/common/filetype.c +++ b/src/common/filetype.c @@ -48,6 +48,7 @@ +/* CAUTION: table must be sorted for bsearch */ static const FileId TypeTable[] = { /* Upper case stuff for obsolete operating systems */ { "A", FILETYPE_LIB }, diff --git a/src/common/target.c b/src/common/target.c index b50478e16..18da67b00 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -138,8 +138,9 @@ struct TargetEntry { 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). +** CAUTION: must be alphabetically for bsearch(). */ static const TargetEntry TargetMap[] = { { "apple2", TGT_APPLE2 }, diff --git a/src/dbginfo/dbginfo.c b/src/dbginfo/dbginfo.c index 1f693e513..4fe7a37ec 100644 --- a/src/dbginfo/dbginfo.c +++ b/src/dbginfo/dbginfo.c @@ -2523,6 +2523,7 @@ static void NextChar (InputData* D) +/* CAUTION: table must be sorted for bsearch */ static void NextToken (InputData* D) /* Read the next token from the input stream */ { diff --git a/src/sp65/convert.c b/src/sp65/convert.c index a9047ffb0..71c9d09a6 100644 --- a/src/sp65/convert.c +++ b/src/sp65/convert.c @@ -61,7 +61,8 @@ struct ConverterMapEntry { StrBuf* (*ConvertFunc) (const Bitmap*, const Collection*); }; -/* Converter table, alphabetically sorted */ +/* Converter table */ +/* CAUTION: table must be alphabetically sorted for bsearch */ static const ConverterMapEntry ConverterMap[] = { { "geos-bitmap", GenGeosBitmap }, { "geos-icon", GenGeosIcon }, diff --git a/src/sp65/input.c b/src/sp65/input.c index f1df247ae..22cfb1678 100644 --- a/src/sp65/input.c +++ b/src/sp65/input.c @@ -69,7 +69,8 @@ static InputFormatDesc InputFormatTable[ifCount] = { { 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[] = { /* Upper case stuff for obsolete operating systems */ { "PCX", ifPCX }, diff --git a/src/sp65/output.c b/src/sp65/output.c index c12d1f612..8b569502b 100644 --- a/src/sp65/output.c +++ b/src/sp65/output.c @@ -78,7 +78,8 @@ static OutputFormatDesc OutputFormatTable[ofCount] = { { 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[] = { /* Upper case stuff for obsolete operating systems */ { "A", ofAsm }, diff --git a/src/sp65/palconv.c b/src/sp65/palconv.c index e92f3c22e..ff5891b99 100644 --- a/src/sp65/palconv.c +++ b/src/sp65/palconv.c @@ -56,7 +56,8 @@ struct PaletteMapEntry { StrBuf* (*PaletteFunc) (const Bitmap*, const Collection*); }; -/* Converter table, alphabetically sorted */ +/* Converter table */ +/* CAUTION: table must be alphabetically sorted for bsearch */ static const PaletteMapEntry PaletteMap[] = { { "lynx-palette", GenLynxPalette }, }; From d368f3d0ea3e93ddd7933831932f3f068926fb7f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 9 Jun 2025 18:26:41 +0200 Subject: [PATCH 472/707] simple script(s) to check if bsearch tables are sorted correctly --- .github/checks/Makefile | 12 +++- .github/checks/sorted.sh | 117 +++++++++++++++++++++++++++++++ .github/checks/sorted_codeopt.sh | 42 +++++++++++ Makefile | 1 + 4 files changed, 170 insertions(+), 2 deletions(-) create mode 100755 .github/checks/sorted.sh create mode 100755 .github/checks/sorted_codeopt.sh diff --git a/.github/checks/Makefile b/.github/checks/Makefile index 93eeddd19..8245958c1 100644 --- a/.github/checks/Makefile +++ b/.github/checks/Makefile @@ -5,14 +5,18 @@ endif ifdef CMD_EXE -.PHONY: checkstyle +.PHONY: checkstyle sorted checkstyle: $(info INFO: style checks require bash.) +sorted: + $(info INFO: table checks require bash.) 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 @@ -31,4 +35,8 @@ spaces: spaces.sh noexec: noexec.sh @./noexec.sh +sorted: sorted.sh sorted_codeopt.sh + @./sorted.sh + @./sorted_codeopt.sh + endif diff --git a/.github/checks/sorted.sh b/.github/checks/sorted.sh new file mode 100755 index 000000000..4311225cd --- /dev/null +++ b/.github/checks/sorted.sh @@ -0,0 +1,117 @@ +#! /bin/bash +OLDCWD=`pwd` +SCRIPT_PATH=`dirname $0` + +SORT_OPT=-u + +function checkarray_quoted_name +{ + CHECK_FILE="$1" + + awk '/'"$2"'/{flag=1;next}/};/{flag=0}flag' "$CHECK_FILE" | \ + sed -e 's:.*\"\(.*\)\".*:\1:g' | \ + sed '/^\s*$/d' > .a.tmp + + if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then + echo "error: "$2" table is empty" + exit -1 + fi + + LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp + + if cmp --silent -- .a.tmp .b.tmp; then + echo ""$2" definitions OK" + else + echo "error: "$2" definitions are not sorted." + diff -y .a.tmp .b.tmp + exit -1 + fi + rm -rf .a.tmp .b.tmp +} + +function checkinstr_quoted_name +{ + CHECK_FILE="$1" + + awk '/'"$2"'/{flag=1;next}/};/{flag=0}flag' "$CHECK_FILE" | \ + sed -e 's:^ *{$::g' | \ + sed -e 's:^ *}$::g' | \ + sed -e 's:.*\"\(.*\)\".*:\1:g' | \ + sed '/^\s*$/d' > .a.tmp + + if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then + echo "error: "$2" table is empty" + exit -1 + fi + + LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp + + if cmp --silent -- .a.tmp .b.tmp; then + echo ""$2" definitions OK" + else + echo "error: "$2" definitions are not sorted." + diff -y .a.tmp .b.tmp + exit -1 + fi + rm -rf .a.tmp .b.tmp +} + +function checkopcodes_quoted_name +{ + CHECK_FILE="$1" + + awk '/'"$2"'/{flag=1;next}/};/{flag=0}flag' "$CHECK_FILE" | \ + grep "^ *\".*\"," | \ + sed '/^\s*$/d' > .a.tmp + + if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then + echo "error: "$2" table is empty" + exit -1 + fi + + LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp + + if cmp --silent -- .a.tmp .b.tmp; then + echo ""$2" definitions OK" + else + echo "error: "$2" definitions are not sorted." + diff -y .a.tmp .b.tmp + exit -1 + fi + rm -rf .a.tmp .b.tmp +} + +checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab6502\.Ins\) \/ sizeof \(InsTab6502\.Ins\[0\]\)," +checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab6502X\.Ins\) \/ sizeof \(InsTab6502X\.Ins\[0\]\)," +checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab6502DTV\.Ins\) \/ sizeof \(InsTab6502DTV\.Ins\[0\]\)," +checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab65C02\.Ins\) \/ sizeof \(InsTab65C02\.Ins\[0\]\)," +checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab4510\.Ins\) \/ sizeof \(InsTab4510\.Ins\[0\]\)," +checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab65816\.Ins\) \/ sizeof \(InsTab65816\.Ins\[0\]\)," +checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTabSweet16\.Ins\) \/ sizeof \(InsTabSweet16\.Ins\[0\]\)," +checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTabHuC6280\.Ins\) \/ sizeof \(InsTabHuC6280\.Ins\[0\]\)," + +checkarray_quoted_name ../../src/ca65/scanner.c "} DotKeywords \[\] = {" + +checkarray_quoted_name ../../src/cc65/codeinfo.c "static const FuncInfo FuncInfoTable\[\]" +checkarray_quoted_name ../../src/cc65/codeinfo.c "static const ZPInfo ZPInfoTable\[\]" +checkarray_quoted_name ../../src/cc65/codeoptutil.c "static const char\* const Tab\[\]" + +checkarray_quoted_name ../../src/cc65/coptstop.c "static const OptFuncDesc FuncTable\[\]" +checkarray_quoted_name ../../src/cc65/coptstop.c "static const OptFuncDesc FuncRegATable\[\]" + +checkopcodes_quoted_name ../../src/cc65/opcodes.c "const OPCDesc OPCTable\[OP65_COUNT\] = {" +checkarray_quoted_name ../../src/cc65/pragma.c "} Pragmas\[\] = {" +checkarray_quoted_name ../../src/cc65/preproc.c "} PPDTypes\[\] = {" +checkarray_quoted_name ../../src/cc65/scanner.c "} Keywords \[\] = {" +checkarray_quoted_name ../../src/cc65/stdfunc.c "} StdFuncs\[\] = {" + +checkarray_quoted_name ../../src/common/filetype.c "static const FileId TypeTable\[\]" +checkarray_quoted_name ../../src/common/target.c "static const TargetEntry TargetMap\[\]" + +checkarray_quoted_name ../../src/dbginfo/dbginfo.c "} KeywordTable\[\] = {" + +checkarray_quoted_name ../../src/sp65/convert.c "static const ConverterMapEntry ConverterMap\[\]" +checkarray_quoted_name ../../src/sp65/input.c "static const FileId FormatTable\[\]" +checkarray_quoted_name ../../src/sp65/output.c "static const FileId FormatTable\[\]" +checkarray_quoted_name ../../src/sp65/palconv.c "static const PaletteMapEntry PaletteMap\[\]" + diff --git a/.github/checks/sorted_codeopt.sh b/.github/checks/sorted_codeopt.sh new file mode 100755 index 000000000..a248ebc07 --- /dev/null +++ b/.github/checks/sorted_codeopt.sh @@ -0,0 +1,42 @@ +#! /bin/bash +OLDCWD=`pwd` +SCRIPT_PATH=`dirname $0` +CHECK_FILE=../../src/cc65/codeopt.c + +SORT_OPT=-u + +grep "^static OptFunc " $CHECK_FILE | \ + sed -e 's:.*"\(.*\)",.*:\1:g' > .a.tmp + +if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then + echo "error: OptFunc table is empty" + exit -1 +fi + +LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp + +if cmp --silent -- .a.tmp .b.tmp; then + echo "static OptFunc definitions OK" +else + echo "error: static OptFunc definitions are not sorted." + diff -y .a.tmp .b.tmp + exit -1 +fi + +awk '/static OptFunc\* OptFuncs\[\] = {/{flag=1;next}/}/{flag=0}flag' $CHECK_FILE | \ + sed -e 's:.*&D\(.*\),:\1:g' > .a.tmp + +if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then + echo "error: OptFuncs table is empty" + exit -1 +fi + +if cmp --silent -- .a.tmp .b.tmp; then + echo "static OptFuncs* OptFuncs[] definitions OK" +else + echo "error: static OptFuncs* OptFuncs[] definitions are not sorted." + diff -y .a.tmp .b.tmp + exit -1 +fi + +rm -rf .a.tmp .b.tmp diff --git a/Makefile b/Makefile index 29fcbbf96..edfd8166c 100644 --- a/Makefile +++ b/Makefile @@ -50,6 +50,7 @@ test: # GNU "check" target, which runs all tests check: @$(MAKE) -C .github/checks checkstyle --no-print-directory + @$(MAKE) -C .github/checks sorted --no-print-directory @$(MAKE) test @$(MAKE) -C targettest platforms --no-print-directory @$(MAKE) -C samples platforms --no-print-directory From 58ff844d04361332d3d37886eb11e3ceebc6d1a5 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 9 Jun 2025 18:42:52 +0200 Subject: [PATCH 473/707] add to GHA --- .github/workflows/build-on-pull-request.yml | 3 +++ .github/workflows/snapshot-on-push-master.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 7b762844b..3cb628529 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -24,6 +24,9 @@ jobs: - name: Do some simple style checks shell: bash run: make -j2 checkstyle + - name: Check bsearch tables + shell: bash + run: make -j2 sorted - name: Build the tools. shell: bash run: make -j2 bin USER_CFLAGS=-Werror diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index 42794f10b..557ba24af 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -49,6 +49,9 @@ jobs: - name: Do some simple style checks shell: bash run: make -j2 checkstyle + - name: Check bsearch tables + shell: bash + run: make -j2 sorted - name: Build the tools. shell: bash run: | From 717e32ba6aab6f6eecfb87aa0b287efd4cc52dd1 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 9 Jun 2025 18:45:52 +0200 Subject: [PATCH 474/707] add "sorted" target --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index edfd8166c..0a12490fc 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,11 @@ util: # check the code style 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 test: From 1e80269c6b22371927a35ae19803f0b30be261e5 Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Mon, 9 Jun 2025 21:14:01 +0300 Subject: [PATCH 475/707] Add comment about why AppleSingle header is needed --- libsrc/agat/exehdr.s | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libsrc/agat/exehdr.s b/libsrc/agat/exehdr.s index 72ea390e9..3f3047bf9 100644 --- a/libsrc/agat/exehdr.s +++ b/libsrc/agat/exehdr.s @@ -4,6 +4,9 @@ ; 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 From 9afe980124a6ffe349664aa14e7413de1df80166 Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Mon, 9 Jun 2025 21:17:47 +0300 Subject: [PATCH 476/707] Add dash for naming consistency --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4c1003179..891c31e86 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ the [cc65 web site](https://cc65.github.io): | Dr. Jozo Dujmović | Picocomputer (RP6502) | | Watara | Watura/QuickShot Supervision | | Synertek | SYM-1 | -| USSR | Agat 7/9 | +| USSR | Agat-7/9 | A generic configuration to adapt cc65 to new targets is also around. From aaa1058d32fbb9a67fed7d707fe03fd37304f731 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 9 Jun 2025 21:48:20 +0200 Subject: [PATCH 477/707] use explicit markers (comments) for the bsearch table checking, simplifies the scripts and makes them more robust too :) --- .github/checks/Makefile | 3 +- .github/checks/sorted.sh | 105 +++++-------------------------- .github/checks/sorted_codeopt.sh | 77 ++++++++++++++--------- .github/checks/sorted_opcodes.sh | 42 +++++++++++++ src/ca65/instr.c | 18 ++++++ src/ca65/scanner.c | 2 + src/cc65/codeinfo.c | 4 ++ src/cc65/codeopt.c | 4 ++ src/cc65/codeoptutil.c | 2 + src/cc65/coptstop.c | 4 ++ src/cc65/opcodes.c | 3 + src/cc65/pragma.c | 2 + src/cc65/preproc.c | 2 + src/cc65/scanner.c | 2 + src/cc65/stdfunc.c | 2 + src/common/filetype.c | 3 +- src/common/target.c | 2 + src/dbginfo/dbginfo.c | 2 + src/sp65/convert.c | 2 + src/sp65/input.c | 3 +- src/sp65/output.c | 3 +- src/sp65/palconv.c | 2 + 22 files changed, 165 insertions(+), 124 deletions(-) create mode 100755 .github/checks/sorted_opcodes.sh diff --git a/.github/checks/Makefile b/.github/checks/Makefile index 8245958c1..ee373d53d 100644 --- a/.github/checks/Makefile +++ b/.github/checks/Makefile @@ -35,8 +35,9 @@ spaces: spaces.sh noexec: noexec.sh @./noexec.sh -sorted: sorted.sh sorted_codeopt.sh +sorted: sorted.sh sorted_codeopt.sh sorted_opcodes.sh @./sorted.sh @./sorted_codeopt.sh + @./sorted_opcodes.sh endif diff --git a/.github/checks/sorted.sh b/.github/checks/sorted.sh index 4311225cd..58d82ed67 100755 --- a/.github/checks/sorted.sh +++ b/.github/checks/sorted.sh @@ -2,116 +2,39 @@ OLDCWD=`pwd` SCRIPT_PATH=`dirname $0` +CHECK_DIR=../../src + SORT_OPT=-u function checkarray_quoted_name { CHECK_FILE="$1" + START="\\/\\* BEGIN SORTED.SH \\*\\/" + END="\\/\\* END SORTED.SH \\*\\/" - awk '/'"$2"'/{flag=1;next}/};/{flag=0}flag' "$CHECK_FILE" | \ - sed -e 's:.*\"\(.*\)\".*:\1:g' | \ - sed '/^\s*$/d' > .a.tmp + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \ + sed -e 's:\(.*\) ##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then - echo "error: "$2" table is empty" + echo "error: "$1" table is empty" + rm -rf .a.tmp exit -1 fi LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp if cmp --silent -- .a.tmp .b.tmp; then - echo ""$2" definitions OK" + echo ""$1" tables OK" else - echo "error: "$2" definitions are not sorted." + echo "error: "$1" tables are not sorted." diff -y .a.tmp .b.tmp + rm -rf .a.tmp .b.tmp exit -1 fi rm -rf .a.tmp .b.tmp } -function checkinstr_quoted_name -{ - CHECK_FILE="$1" - - awk '/'"$2"'/{flag=1;next}/};/{flag=0}flag' "$CHECK_FILE" | \ - sed -e 's:^ *{$::g' | \ - sed -e 's:^ *}$::g' | \ - sed -e 's:.*\"\(.*\)\".*:\1:g' | \ - sed '/^\s*$/d' > .a.tmp - - if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then - echo "error: "$2" table is empty" - exit -1 - fi - - LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp - - if cmp --silent -- .a.tmp .b.tmp; then - echo ""$2" definitions OK" - else - echo "error: "$2" definitions are not sorted." - diff -y .a.tmp .b.tmp - exit -1 - fi - rm -rf .a.tmp .b.tmp -} - -function checkopcodes_quoted_name -{ - CHECK_FILE="$1" - - awk '/'"$2"'/{flag=1;next}/};/{flag=0}flag' "$CHECK_FILE" | \ - grep "^ *\".*\"," | \ - sed '/^\s*$/d' > .a.tmp - - if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then - echo "error: "$2" table is empty" - exit -1 - fi - - LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp - - if cmp --silent -- .a.tmp .b.tmp; then - echo ""$2" definitions OK" - else - echo "error: "$2" definitions are not sorted." - diff -y .a.tmp .b.tmp - exit -1 - fi - rm -rf .a.tmp .b.tmp -} - -checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab6502\.Ins\) \/ sizeof \(InsTab6502\.Ins\[0\]\)," -checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab6502X\.Ins\) \/ sizeof \(InsTab6502X\.Ins\[0\]\)," -checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab6502DTV\.Ins\) \/ sizeof \(InsTab6502DTV\.Ins\[0\]\)," -checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab65C02\.Ins\) \/ sizeof \(InsTab65C02\.Ins\[0\]\)," -checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab4510\.Ins\) \/ sizeof \(InsTab4510\.Ins\[0\]\)," -checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTab65816\.Ins\) \/ sizeof \(InsTab65816\.Ins\[0\]\)," -checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTabSweet16\.Ins\) \/ sizeof \(InsTabSweet16\.Ins\[0\]\)," -checkinstr_quoted_name ../../src/ca65/instr.c "sizeof \(InsTabHuC6280\.Ins\) \/ sizeof \(InsTabHuC6280\.Ins\[0\]\)," - -checkarray_quoted_name ../../src/ca65/scanner.c "} DotKeywords \[\] = {" - -checkarray_quoted_name ../../src/cc65/codeinfo.c "static const FuncInfo FuncInfoTable\[\]" -checkarray_quoted_name ../../src/cc65/codeinfo.c "static const ZPInfo ZPInfoTable\[\]" -checkarray_quoted_name ../../src/cc65/codeoptutil.c "static const char\* const Tab\[\]" - -checkarray_quoted_name ../../src/cc65/coptstop.c "static const OptFuncDesc FuncTable\[\]" -checkarray_quoted_name ../../src/cc65/coptstop.c "static const OptFuncDesc FuncRegATable\[\]" - -checkopcodes_quoted_name ../../src/cc65/opcodes.c "const OPCDesc OPCTable\[OP65_COUNT\] = {" -checkarray_quoted_name ../../src/cc65/pragma.c "} Pragmas\[\] = {" -checkarray_quoted_name ../../src/cc65/preproc.c "} PPDTypes\[\] = {" -checkarray_quoted_name ../../src/cc65/scanner.c "} Keywords \[\] = {" -checkarray_quoted_name ../../src/cc65/stdfunc.c "} StdFuncs\[\] = {" - -checkarray_quoted_name ../../src/common/filetype.c "static const FileId TypeTable\[\]" -checkarray_quoted_name ../../src/common/target.c "static const TargetEntry TargetMap\[\]" - -checkarray_quoted_name ../../src/dbginfo/dbginfo.c "} KeywordTable\[\] = {" - -checkarray_quoted_name ../../src/sp65/convert.c "static const ConverterMapEntry ConverterMap\[\]" -checkarray_quoted_name ../../src/sp65/input.c "static const FileId FormatTable\[\]" -checkarray_quoted_name ../../src/sp65/output.c "static const FileId FormatTable\[\]" -checkarray_quoted_name ../../src/sp65/palconv.c "static const PaletteMapEntry PaletteMap\[\]" +for N in `grep -rl "BEGIN SORTED.SH" "$CHECK_DIR"`; do + checkarray_quoted_name $N +done diff --git a/.github/checks/sorted_codeopt.sh b/.github/checks/sorted_codeopt.sh index a248ebc07..f15295990 100755 --- a/.github/checks/sorted_codeopt.sh +++ b/.github/checks/sorted_codeopt.sh @@ -1,42 +1,61 @@ #! /bin/bash OLDCWD=`pwd` SCRIPT_PATH=`dirname $0` -CHECK_FILE=../../src/cc65/codeopt.c + +CHECK_DIR=../../src SORT_OPT=-u -grep "^static OptFunc " $CHECK_FILE | \ - sed -e 's:.*"\(.*\)",.*:\1:g' > .a.tmp +function checkarray +{ + CHECK_FILE="$1" + START="\\/\\* BEGIN DECL SORTED_CODEOPT.SH \\*\\/" + END="\\/\\* END DECL SORTED_CODEOPT.SH \\*\\/" -if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then - echo "error: OptFunc table is empty" - exit -1 -fi + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \ + sed -e 's:\(.*##\).*"\(.*\)",.*:\1\2:g' > .a.tmp -LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp + if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then + echo "error: "$1" table is empty" + rm -rf .a.tmp + exit -1 + fi -if cmp --silent -- .a.tmp .b.tmp; then - echo "static OptFunc definitions OK" -else - echo "error: static OptFunc definitions are not sorted." - diff -y .a.tmp .b.tmp - exit -1 -fi + LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp -awk '/static OptFunc\* OptFuncs\[\] = {/{flag=1;next}/}/{flag=0}flag' $CHECK_FILE | \ - sed -e 's:.*&D\(.*\),:\1:g' > .a.tmp + if cmp --silent -- .a.tmp .b.tmp; then + echo ""$1" decls OK" + else + echo "error: "$1" decls are not sorted." + diff -y .a.tmp .b.tmp + rm -rf .a.tmp .b.tmp + exit -1 + fi -if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then - echo "error: OptFuncs table is empty" - exit -1 -fi + START="\\/\\* BEGIN SORTED_CODEOPT.SH \\*\\/" + END="\\/\\* END SORTED_CODEOPT.SH \\*\\/" + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \ + sed -e 's:\(.*##\).*&D\(.*\),.*:\1\2:g' > .a.tmp -if cmp --silent -- .a.tmp .b.tmp; then - echo "static OptFuncs* OptFuncs[] definitions OK" -else - echo "error: static OptFuncs* OptFuncs[] definitions are not sorted." - diff -y .a.tmp .b.tmp - exit -1 -fi + if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then + echo "error: "$1" table is empty" + rm -rf .a.tmp + exit -1 + fi -rm -rf .a.tmp .b.tmp + if cmp --silent -- .a.tmp .b.tmp; then + echo ""$1" tables OK" + else + echo "error: "$1" tables are not sorted." + 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 diff --git a/.github/checks/sorted_opcodes.sh b/.github/checks/sorted_opcodes.sh new file mode 100755 index 000000000..a1f8fcbfa --- /dev/null +++ b/.github/checks/sorted_opcodes.sh @@ -0,0 +1,42 @@ +#! /bin/bash +OLDCWD=`pwd` +SCRIPT_PATH=`dirname $0` + +CHECK_DIR=../../src + +SORT_OPT=-u + +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 {print 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 + + LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp + + if cmp --silent -- .a.tmp .b.tmp; then + echo ""$1" tables OK" + else + echo "error: "$1" tables are not sorted." + 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 SORTED_OPCODES.SH" "$CHECK_DIR"`; do + checkarray_quoted_name $N +done + diff --git a/src/ca65/instr.c b/src/ca65/instr.c index f1d8d706a..c7a68006c 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -172,6 +172,7 @@ static const struct { /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab6502.Ins) / sizeof (InsTab6502.Ins[0]), { +/* BEGIN SORTED.SH */ { "ADC", 0x080A26C, 0x60, 0, PutAll }, { "AND", 0x080A26C, 0x20, 0, PutAll }, { "ASL", 0x000006e, 0x02, 1, PutAll }, @@ -228,6 +229,7 @@ static const struct { { "TXA", 0x0000001, 0x8a, 0, PutAll }, { "TXS", 0x0000001, 0x9a, 0, PutAll }, { "TYA", 0x0000001, 0x98, 0, PutAll } +/* END SORTED.SH */ } }; @@ -239,6 +241,7 @@ static const struct { /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab6502X.Ins) / sizeof (InsTab6502X.Ins[0]), { +/* BEGIN SORTED.SH */ { "ADC", 0x080A26C, 0x60, 0, PutAll }, { "ALR", 0x0800000, 0x4B, 0, PutAll }, /* X */ { "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X */ @@ -314,6 +317,7 @@ static const struct { { "TXA", 0x0000001, 0x8a, 0, PutAll }, { "TXS", 0x0000001, 0x9a, 0, PutAll }, { "TYA", 0x0000001, 0x98, 0, PutAll } +/* END SORTED.SH */ } }; @@ -329,6 +333,7 @@ static const struct { /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab6502DTV.Ins) / sizeof (InsTab6502DTV.Ins[0]), { +/* BEGIN SORTED.SH */ { "ADC", 0x080A26C, 0x60, 0, PutAll }, { "ALR", 0x0800000, 0x4B, 0, PutAll }, /* X */ { "ANC", 0x0800000, 0x0B, 0, PutAll }, /* X */ @@ -400,6 +405,7 @@ static const struct { { "TXA", 0x0000001, 0x8a, 0, PutAll }, { "TXS", 0x0000001, 0x9a, 0, PutAll }, { "TYA", 0x0000001, 0x98, 0, PutAll } +/* END SORTED.SH */ } }; @@ -411,6 +417,7 @@ static const struct { /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab65SC02.Ins) / sizeof (InsTab65SC02.Ins[0]), { +/* BEGIN SORTED.SH */ { "ADC", 0x080A66C, 0x60, 0, PutAll }, { "AND", 0x080A66C, 0x20, 0, PutAll }, { "ASL", 0x000006e, 0x02, 1, PutAll }, @@ -477,6 +484,7 @@ static const struct { { "TXA", 0x0000001, 0x8a, 0, PutAll }, { "TXS", 0x0000001, 0x9a, 0, PutAll }, { "TYA", 0x0000001, 0x98, 0, PutAll } +/* END SORTED.SH */ } }; @@ -488,6 +496,7 @@ static const struct { /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab65C02.Ins) / sizeof (InsTab65C02.Ins[0]), { +/* BEGIN SORTED.SH */ { "ADC", 0x080A66C, 0x60, 0, PutAll }, { "AND", 0x080A66C, 0x20, 0, PutAll }, { "ASL", 0x000006e, 0x02, 1, PutAll }, @@ -588,6 +597,7 @@ static const struct { { "TXS", 0x0000001, 0x9a, 0, PutAll }, { "TYA", 0x0000001, 0x98, 0, PutAll }, { "WAI", 0x0000001, 0xcb, 0, PutAll } +/* END SORTED.SH */ } }; @@ -599,6 +609,7 @@ static const struct { /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab4510.Ins) / sizeof (InsTab4510.Ins[0]), { +/* BEGIN SORTED.SH */ { "ADC", 0x080A66C, 0x60, 0, PutAll }, { "AND", 0x080A66C, 0x20, 0, PutAll }, { "ASL", 0x000006e, 0x02, 1, PutAll }, @@ -732,6 +743,7 @@ static const struct { { "TYA", 0x0000001, 0x98, 0, PutAll }, { "TYS", 0x0000001, 0x2b, 0, PutAll }, { "TZA", 0x0000001, 0x6b, 0, PutAll }, +/* END SORTED.SH */ } }; @@ -743,6 +755,7 @@ static const struct { /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab65816.Ins) / sizeof (InsTab65816.Ins[0]), { +/* BEGIN SORTED.SH */ { "ADC", 0x0b8f6fc, 0x60, 0, PutAll }, { "AND", 0x0b8f6fc, 0x20, 0, PutAll }, { "ASL", 0x000006e, 0x02, 1, PutAll }, @@ -843,6 +856,7 @@ static const struct { { "WDM", 0x0800004, 0x42, 6, PutAll }, { "XBA", 0x0000001, 0xeb, 0, PutAll }, { "XCE", 0x0000001, 0xfb, 0, PutAll } +/* END SORTED.SH */ } }; @@ -854,6 +868,7 @@ static const struct { /* CAUTION: table must be sorted for bsearch */ sizeof (InsTabSweet16.Ins) / sizeof (InsTabSweet16.Ins[0]), { +/* BEGIN SORTED.SH */ { "ADD", AMSW16_REG, 0xA0, 0, PutSweet16 }, { "BC", AMSW16_BRA, 0x03, 0, PutSweet16Branch }, { "BK", AMSW16_IMP, 0x0A, 0, PutSweet16 }, @@ -880,6 +895,7 @@ static const struct { { "STD", AMSW16_IND, 0x70, 0, PutSweet16 }, { "STP", AMSW16_IND, 0x90, 0, PutSweet16 }, { "SUB", AMSW16_REG, 0xB0, 0, PutSweet16 }, +/* END SORTED.SH */ } }; @@ -891,6 +907,7 @@ static const struct { /* CAUTION: table must be sorted for bsearch */ sizeof (InsTabHuC6280.Ins) / sizeof (InsTabHuC6280.Ins[0]), { +/* BEGIN SORTED.SH */ { "ADC", 0x080A66C, 0x60, 0, PutAll }, { "AND", 0x080A66C, 0x20, 0, PutAll }, { "ASL", 0x000006e, 0x02, 1, PutAll }, @@ -1026,6 +1043,7 @@ static const struct { { "TXA", 0x0000001, 0x8a, 0, PutAll }, { "TXS", 0x0000001, 0x9a, 0, PutAll }, { "TYA", 0x0000001, 0x98, 0, PutAll } +/* END SORTED.SH */ } }; diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 11beb4d63..94c84d897 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -136,6 +136,7 @@ struct DotKeyword { const char* Key; /* MUST be first field */ token_t Tok; } DotKeywords [] = { +/* BEGIN SORTED.SH */ { ".A16", TOK_A16 }, { ".A8", TOK_A8 }, { ".ADDR", TOK_ADDR }, @@ -307,6 +308,7 @@ struct DotKeyword { { ".XMATCH", TOK_XMATCH }, { ".XOR", TOK_BOOLXOR }, { ".ZEROPAGE", TOK_ZEROPAGE }, +/* END SORTED.SH */ }; diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 8396ecfd5..29f18cb78 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -92,6 +92,7 @@ struct FuncInfo { */ /* CAUTION: table must be sorted for bsearch */ static const FuncInfo FuncInfoTable[] = { +/* BEGIN SORTED.SH */ { "addeq0sp", SLV_TOP | REG_AX, PSTATE_ALL | REG_AXY }, { "addeqysp", SLV_IND | REG_AXY, PSTATE_ALL | REG_AXY }, { "addysp", REG_SP | REG_Y, PSTATE_ALL | REG_SP }, @@ -377,12 +378,14 @@ static const FuncInfo FuncInfoTable[] = { { "tosxoreax", SLV_TOP | REG_EAX, PSTATE_ALL | REG_SP | REG_EAXY | REG_TMP1 }, { "tsteax", REG_EAX, PSTATE_ALL | REG_Y }, { "utsteax", REG_EAX, PSTATE_ALL | REG_Y }, +/* END SORTED.SH */ }; #define FuncInfoCount (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0])) /* Table with names of zero page locations used by the compiler */ /* CAUTION: table must be sorted for bsearch */ static const ZPInfo ZPInfoTable[] = { +/* BEGIN SORTED.SH */ { 0, "ptr1", 2, REG_PTR1_LO, REG_PTR1 }, { 0, "ptr1+1", 1, REG_PTR1_HI, REG_PTR1 }, { 0, "ptr2", 2, REG_PTR2_LO, REG_PTR2 }, @@ -400,6 +403,7 @@ static const ZPInfo ZPInfoTable[] = { { 0, "tmp2", 1, REG_NONE, REG_NONE }, { 0, "tmp3", 1, REG_NONE, REG_NONE }, { 0, "tmp4", 1, REG_NONE, REG_NONE }, +/* END SORTED.SH */ }; #define ZPInfoCount (sizeof(ZPInfoTable) / sizeof(ZPInfoTable[0])) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 9de2ab7ba..c8d7d2ce9 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -103,6 +103,7 @@ struct OptFunc { /* 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 DOpt65C02Ind = { Opt65C02Ind, "Opt65C02Ind", 100, 0, 0, 0, 0, 0 }; static OptFunc DOpt65C02Stores = { Opt65C02Stores, "Opt65C02Stores", 100, 0, 0, 0, 0, 0 }; @@ -215,11 +216,13 @@ static OptFunc DOptTransfers3 = { OptTransfers3, "OptTransfers3", 65, 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 DOptUnusedStores = { OptUnusedStores, "OptUnusedStores", 0, 0, 0, 0, 0, 0 }; +/* END DECL SORTED_CODEOPT.SH */ /* Table containing all the steps in alphabetical order */ /* CAUTION: table must be sorted for bsearch */ static OptFunc* OptFuncs[] = { +/* BEGIN SORTED_CODEOPT.SH */ &DOpt65C02BitOps, &DOpt65C02Ind, &DOpt65C02Stores, @@ -332,6 +335,7 @@ static OptFunc* OptFuncs[] = { &DOptTransfers4, &DOptUnusedLoads, &DOptUnusedStores, +/* END SORTED_CODEOPT.SH */ }; #define OPTFUNC_COUNT (sizeof(OptFuncs) / sizeof(OptFuncs[0])) diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index c18ccf18b..7547ef5ba 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -1227,7 +1227,9 @@ 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) diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 90ab78c50..e5d686d1a 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1466,6 +1466,7 @@ static unsigned Opt_a_tosxor (StackOpData* D) /* CAUTION: table must be sorted for bsearch */ static const OptFuncDesc FuncTable[] = { +/* BEGIN SORTED.SH */ { "___bzero", Opt___bzero, REG_NONE, OP_X_ZERO | OP_A_KNOWN }, { "staspidx", Opt_staspidx, REG_NONE, OP_NONE }, { "staxspidx", Opt_staxspidx, REG_AX, OP_NONE }, @@ -1486,10 +1487,12 @@ static const OptFuncDesc FuncTable[] = { { "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 }, { "tosxorax", Opt_tosxorax, REG_NONE, OP_NONE }, +/* END SORTED.SH */ }; /* CAUTION: table must be sorted for bsearch */ static const OptFuncDesc FuncRegATable[] = { +/* BEGIN SORTED.SH */ { "tosandax", Opt_a_tosand, REG_NONE, OP_RHS_REMOVE_DIRECT | OP_RHS_LOAD_DIRECT }, { "toseqax", Opt_a_toseq, REG_NONE, OP_NONE }, { "tosgeax", Opt_a_tosuge, REG_NONE, OP_NONE }, @@ -1505,6 +1508,7 @@ static const OptFuncDesc FuncRegATable[] = { { "tosuleax", Opt_a_tosule, 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 }, +/* END SORTED.SH */ }; #define FUNC_COUNT(Table) (sizeof(Table) / sizeof(Table[0])) diff --git a/src/cc65/opcodes.c b/src/cc65/opcodes.c index c591c4ea3..49363769e 100644 --- a/src/cc65/opcodes.c +++ b/src/cc65/opcodes.c @@ -59,6 +59,8 @@ const OPCDesc OPCTable[OP65_COUNT] = { /* 65XX opcodes */ + +/* BEGIN SORTED_OPCODES.SH */ { OP65_ADC, /* opcode */ "adc", /* mnemonic */ 0, /* size */ @@ -587,6 +589,7 @@ const OPCDesc OPCTable[OP65_COUNT] = { REG_Y, /* use */ REG_A | PSTATE_ZN /* chg */ }, +/* END SORTED_OPCODES.SH */ }; diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 5de4c8dfc..c9fdefd9b 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -94,6 +94,7 @@ static const struct Pragma { const char* Key; /* Keyword */ pragma_t Tok; /* Token */ } Pragmas[] = { +/* BEGIN SORTED.SH */ { "align", PRAGMA_ALIGN }, { "allow-eager-inline", PRAGMA_ALLOW_EAGER_INLINE }, { "allow_eager_inline", PRAGMA_ALLOW_EAGER_INLINE }, @@ -128,6 +129,7 @@ static const struct Pragma { { "writable-strings", PRAGMA_WRITABLE_STRINGS }, { "writable_strings", PRAGMA_WRITABLE_STRINGS }, { "zpsym", PRAGMA_ZPSYM }, +/* END SORTED.SH */ }; #define PRAGMA_COUNT (sizeof (Pragmas) / sizeof (Pragmas[0])) diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index d70c28147..96fa565f2 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -221,6 +221,7 @@ static const struct PPDType { const char* Tok; /* Token */ ppdirective_t Type; /* Type */ } PPDTypes[] = { +/* BEGIN SORTED.SH */ { "define", PPD_DEFINE }, { "elif", PPD_ELIF }, { "else", PPD_ELSE }, @@ -234,6 +235,7 @@ static const struct PPDType { { "pragma", PPD_PRAGMA }, { "undef", PPD_UNDEF }, { "warning", PPD_WARNING }, +/* END SORTED.SH */ }; /* Number of preprocessor directive types */ diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 1549b51bd..dda857f07 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -93,6 +93,7 @@ static const struct Keyword { unsigned char Tok; /* The token */ unsigned char Std; /* Token supported in which standards? */ } Keywords [] = { +/* BEGIN SORTED.SH */ { "_Pragma", TOK_PRAGMA, TT_C89 | TT_C99 | TT_CC65 }, /* !! */ { "_Static_assert", TOK_STATIC_ASSERT, TT_CC65 }, /* C11 */ { "__AX__", TOK_AX, TT_C89 | TT_C99 | TT_CC65 }, @@ -146,6 +147,7 @@ static const struct Keyword { { "void", TOK_VOID, TT_C89 | TT_C99 | TT_CC65 }, { "volatile", TOK_VOLATILE, 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])) diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 3bd3f3552..3f33cdcce 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -85,11 +85,13 @@ static struct StdFuncDesc { const char* Name; void (*Handler) (FuncDesc*, ExprDesc*); } StdFuncs[] = { +/* BEGIN SORTED.SH */ { "memcpy", StdFunc_memcpy }, { "memset", StdFunc_memset }, { "strcmp", StdFunc_strcmp }, { "strcpy", StdFunc_strcpy }, { "strlen", StdFunc_strlen }, +/* END SORTED.SH */ }; #define FUNC_COUNT (sizeof (StdFuncs) / sizeof (StdFuncs[0])) diff --git a/src/common/filetype.c b/src/common/filetype.c index 4aececa78..074f8800a 100644 --- a/src/common/filetype.c +++ b/src/common/filetype.c @@ -51,6 +51,7 @@ /* CAUTION: table must be sorted for bsearch */ static const FileId TypeTable[] = { /* Upper case stuff for obsolete operating systems */ +/* BEGIN SORTED.SH */ { "A", FILETYPE_LIB }, { "A65", FILETYPE_ASM }, { "ASM", FILETYPE_ASM }, @@ -66,7 +67,6 @@ static const FileId TypeTable[] = { { "S", FILETYPE_ASM }, { "SER", FILETYPE_O65 }, { "TGI", FILETYPE_O65 }, - { "a", FILETYPE_LIB }, { "a65", FILETYPE_ASM }, { "asm", FILETYPE_ASM }, @@ -82,6 +82,7 @@ static const FileId TypeTable[] = { { "s", FILETYPE_ASM }, { "ser", FILETYPE_O65 }, { "tgi", FILETYPE_O65 }, +/* END SORTED.SH */ }; #define FILETYPE_COUNT (sizeof (TypeTable) / sizeof (TypeTable[0])) diff --git a/src/common/target.c b/src/common/target.c index 18da67b00..24e9f4495 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -143,6 +143,7 @@ struct TargetEntry { ** CAUTION: must be alphabetically for bsearch(). */ static const TargetEntry TargetMap[] = { +/* BEGIN SORTED.SH */ { "apple2", TGT_APPLE2 }, { "apple2enh", TGT_APPLE2ENH }, { "atari", TGT_ATARI }, @@ -181,6 +182,7 @@ static const TargetEntry TargetMap[] = { { "sym1", TGT_SYM1 }, { "telestrat", TGT_TELESTRAT }, { "vic20", TGT_VIC20 }, +/* END SORTED.SH */ }; #define MAP_ENTRY_COUNT (sizeof (TargetMap) / sizeof (TargetMap[0])) diff --git a/src/dbginfo/dbginfo.c b/src/dbginfo/dbginfo.c index 4fe7a37ec..896043cb6 100644 --- a/src/dbginfo/dbginfo.c +++ b/src/dbginfo/dbginfo.c @@ -2531,6 +2531,7 @@ static void NextToken (InputData* D) const char Keyword[12]; Token Tok; } KeywordTable[] = { +/* BEGIN SORTED.SH */ { "abs", TOK_ABSOLUTE }, { "addrsize", TOK_ADDRSIZE }, { "auto", TOK_AUTO }, @@ -2579,6 +2580,7 @@ static void NextToken (InputData* D) { "var", TOK_VAR }, { "version", TOK_VERSION }, { "zp", TOK_ZEROPAGE }, +/* END SORTED.SH */ }; diff --git a/src/sp65/convert.c b/src/sp65/convert.c index 71c9d09a6..3ffdbab7d 100644 --- a/src/sp65/convert.c +++ b/src/sp65/convert.c @@ -64,12 +64,14 @@ struct ConverterMapEntry { /* Converter table */ /* CAUTION: table must be alphabetically sorted for bsearch */ static const ConverterMapEntry ConverterMap[] = { +/* BEGIN SORTED.SH */ { "geos-bitmap", GenGeosBitmap }, { "geos-icon", GenGeosIcon }, { "koala", GenKoala }, { "lynx-sprite", GenLynxSprite }, { "raw", GenRaw }, { "vic2-sprite", GenVic2Sprite }, +/* END SORTED.SH */ }; diff --git a/src/sp65/input.c b/src/sp65/input.c index 22cfb1678..ac3aeaf99 100644 --- a/src/sp65/input.c +++ b/src/sp65/input.c @@ -73,9 +73,10 @@ static InputFormatDesc InputFormatTable[ifCount] = { /* CAUTION: table must be alphabetically sorted for bsearch */ static const FileId FormatTable[] = { /* Upper case stuff for obsolete operating systems */ +/* BEGIN SORTED.SH */ { "PCX", ifPCX }, - { "pcx", ifPCX }, +/* END SORTED.SH */ }; diff --git a/src/sp65/output.c b/src/sp65/output.c index 8b569502b..0c8fa59a7 100644 --- a/src/sp65/output.c +++ b/src/sp65/output.c @@ -82,19 +82,20 @@ static OutputFormatDesc OutputFormatTable[ofCount] = { /* CAUTION: table must be alphabetically sorted for bsearch */ static const FileId FormatTable[] = { /* Upper case stuff for obsolete operating systems */ +/* BEGIN SORTED.SH */ { "A", ofAsm }, { "ASM", ofAsm }, { "BIN", ofBin }, { "C", ofC }, { "INC", ofAsm }, { "S", ofAsm }, - { "a", ofAsm }, { "asm", ofAsm }, { "bin", ofBin }, { "c", ofC }, { "inc", ofAsm }, { "s", ofAsm }, +/* END SORTED.SH */ }; diff --git a/src/sp65/palconv.c b/src/sp65/palconv.c index ff5891b99..42adb1b33 100644 --- a/src/sp65/palconv.c +++ b/src/sp65/palconv.c @@ -59,7 +59,9 @@ struct PaletteMapEntry { /* Converter table */ /* CAUTION: table must be alphabetically sorted for bsearch */ static const PaletteMapEntry PaletteMap[] = { +/* BEGIN SORTED.SH */ { "lynx-palette", GenLynxPalette }, +/* END SORTED.SH */ }; From d1def100ddfebe54eb2dd000b4f239646a805dbd Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 9 Jun 2025 22:28:19 +0200 Subject: [PATCH 478/707] use sort -c --- .github/checks/sorted.sh | 12 +++++------- .github/checks/sorted_codeopt.sh | 31 +++++++++++++++++++------------ .github/checks/sorted_opcodes.sh | 12 +++++------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/.github/checks/sorted.sh b/.github/checks/sorted.sh index 58d82ed67..0a4a90db7 100755 --- a/.github/checks/sorted.sh +++ b/.github/checks/sorted.sh @@ -4,8 +4,9 @@ SCRIPT_PATH=`dirname $0` CHECK_DIR=../../src -SORT_OPT=-u +SORT_OPT="-u -c" +# $1: filename function checkarray_quoted_name { CHECK_FILE="$1" @@ -21,17 +22,14 @@ function checkarray_quoted_name exit -1 fi - LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp - - if cmp --silent -- .a.tmp .b.tmp; then + if `LC_COLLATE=C sort $SORT_OPT .a.tmp`; then echo ""$1" tables OK" else echo "error: "$1" tables are not sorted." - diff -y .a.tmp .b.tmp - rm -rf .a.tmp .b.tmp + rm -rf .a.tmp exit -1 fi - rm -rf .a.tmp .b.tmp + rm -rf .a.tmp } diff --git a/.github/checks/sorted_codeopt.sh b/.github/checks/sorted_codeopt.sh index f15295990..e90e32b4a 100755 --- a/.github/checks/sorted_codeopt.sh +++ b/.github/checks/sorted_codeopt.sh @@ -4,8 +4,9 @@ SCRIPT_PATH=`dirname $0` CHECK_DIR=../../src -SORT_OPT=-u +SORT_OPT="-u -c" +# $1: filename function checkarray { CHECK_FILE="$1" @@ -21,32 +22,38 @@ function checkarray exit -1 fi - LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp - - if cmp --silent -- .a.tmp .b.tmp; then - echo ""$1" decls OK" + if `LC_COLLATE=C sort $SORT_OPT .a.tmp`; then + echo ""$1" decls sorted." else echo "error: "$1" decls are not sorted." - diff -y .a.tmp .b.tmp - rm -rf .a.tmp .b.tmp + 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 {print count,"##",$0}' "$CHECK_FILE" | \ - sed -e 's:\(.*##\).*&D\(.*\),.*:\1\2:g' > .a.tmp - if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print 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 + 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 not sorted." + echo "error: "$1" tables are different." diff -y .a.tmp .b.tmp rm -rf .a.tmp .b.tmp exit -1 diff --git a/.github/checks/sorted_opcodes.sh b/.github/checks/sorted_opcodes.sh index a1f8fcbfa..b18b841c8 100755 --- a/.github/checks/sorted_opcodes.sh +++ b/.github/checks/sorted_opcodes.sh @@ -4,8 +4,9 @@ SCRIPT_PATH=`dirname $0` CHECK_DIR=../../src -SORT_OPT=-u +SORT_OPT="-u -c" +# $1: filename function checkarray_quoted_name { CHECK_FILE="$1" @@ -23,17 +24,14 @@ function checkarray_quoted_name exit -1 fi - LC_COLLATE=C sort $SORT_OPT .a.tmp > .b.tmp - - if cmp --silent -- .a.tmp .b.tmp; then + if `LC_COLLATE=C sort $SORT_OPT .a.tmp`; then echo ""$1" tables OK" else echo "error: "$1" tables are not sorted." - diff -y .a.tmp .b.tmp - rm -rf .a.tmp .b.tmp + rm -rf .a.tmp exit -1 fi - rm -rf .a.tmp .b.tmp + rm -rf .a.tmp } for N in `grep -rl "BEGIN SORTED_OPCODES.SH" "$CHECK_DIR"`; do From 51da666210db583b18aea8d325a83ba102cae056 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Wed, 11 Jun 2025 02:21:39 +0000 Subject: [PATCH 479/707] fixes #2608 --- src/cc65/pragma.c | 7 +------ test/val/bug2151.c | 5 +++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index ee71b42d8..b7384e2f1 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -433,12 +433,7 @@ static void ApplySegNamePragma (pragma_t Token, int PushPop, const char* Name, u SetSegAddrSize (Name, AddrSize); } - /* BSS variables are output at the end of the compilation. Don't - ** bother to change their segment, now. - */ - if (Seg != SEG_BSS) { - g_segname (Seg); - } + g_segname (Seg); } diff --git a/test/val/bug2151.c b/test/val/bug2151.c index 25f145506..1277961ef 100644 --- a/test/val/bug2151.c +++ b/test/val/bug2151.c @@ -47,10 +47,11 @@ _Pragma _Pragma ( #pragma bss-name("BSS") { extern int y; -#pragma bss-name("BSS2") +#pragma bss-name("BSS") // used to be BSS2, but fix for #2608 means + // that now causes ld65 to fail, so we use BSS instead static #pragma zpsym ("y") - int x; // TODO: currently in "BSS", but supposed to be in "BSS2"? + int x; x = 0; if (memcmp(str, "aBC", 3)) From ccdc5b9fea5840ee233e371ec26f5146e4606a19 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 11 Jun 2025 20:50:04 +0200 Subject: [PATCH 480/707] massaged repro case from #2608 into a test --- test/todo/bug2608.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 test/todo/bug2608.c diff --git a/test/todo/bug2608.c b/test/todo/bug2608.c new file mode 100644 index 000000000..c0685d28c --- /dev/null +++ b/test/todo/bug2608.c @@ -0,0 +1,40 @@ + +/* bug #2608: "zp_bss" is placed in BSS and NOT placed in ZEROPAGE as expected. */ + +#include <stdlib.h> +#include <stdio.h> + +int err = 0; + +int is_zeropage(void *p) +{ + if (/*(p >= ((void*)0)) &&*/ + (p <= ((void*)0xff))) { + return 1; + } + return 0; +} + +void foo(void) { +#pragma bss-name(push,"ZEROPAGE") +#pragma data-name(push,"ZEROPAGE") + static int zp_data = 5; + static char zp_bss; +#pragma bss-name(pop) +#pragma data-name(pop) + printf("zp_data at 0x%04x (%szp)\n", &zp_data, is_zeropage(&zp_data) ? "" : "NOT "); + printf("zp_bss at 0x%04x (%szp)\n", &zp_bss, is_zeropage(&zp_bss) ? "" : "NOT "); + if (!is_zeropage(&zp_data)) { + err++; + } + if (!is_zeropage(&zp_bss)) { + err++; + } +} + +int main(void) +{ + foo(); + printf("errors: %d\n", err); + return err; +} From 3b79c92f394cf84e21d4e29dbbca8340c83c0adf Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Wed, 11 Jun 2025 21:06:58 +0200 Subject: [PATCH 481/707] Update pragma.c just retrigger the checks From cd769b3a9f077e5a9bd8c4be78a1fa4def94bc5f Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Thu, 12 Jun 2025 00:32:09 +0200 Subject: [PATCH 482/707] Update cbm264.h - TGI_COLOR defines should be indices into the default palette --- include/cbm264.h | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/include/cbm264.h b/include/cbm264.h index e017a7bf3..82ecdc4d8 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -110,24 +110,25 @@ #define COLOR_LIGHTBLUE (BCOLOR_LIGHTBLUE | CATTR_LUMA7) #define COLOR_GRAY3 (BCOLOR_WHITE | CATTR_LUMA5) -/* TGI color defines */ -#define TGI_COLOR_BLACK COLOR_BLACK -#define TGI_COLOR_WHITE COLOR_WHITE -#define TGI_COLOR_RED COLOR_RED -#define TGI_COLOR_CYAN COLOR_CYAN -#define TGI_COLOR_VIOLET COLOR_VIOLET -#define TGI_COLOR_PURPLE COLOR_PURPLE -#define TGI_COLOR_GREEN COLOR_GREEN -#define TGI_COLOR_BLUE COLOR_BLUE -#define TGI_COLOR_YELLOW COLOR_YELLOW -#define TGI_COLOR_ORANGE COLOR_ORANGE -#define TGI_COLOR_BROWN COLOR_BROWN -#define TGI_COLOR_LIGHTRED COLOR_LIGHTRED -#define TGI_COLOR_GRAY1 COLOR_GRAY1 -#define TGI_COLOR_GRAY2 COLOR_GRAY2 -#define TGI_COLOR_LIGHTGREEN COLOR_LIGHTGREEN -#define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE -#define TGI_COLOR_GRAY3 COLOR_GRAY3 +/* TGI color defines (these are indices into the default palette) */ +#define TGI_COLOR_BLACK 0 +#define TGI_COLOR_WHITE 1 +/* +#define TGI_COLOR_RED 2 +#define TGI_COLOR_CYAN 3 +#define TGI_COLOR_PURPLE 4 +#define TGI_COLOR_GREEN 5 +#define TGI_COLOR_BLUE 6 +#define TGI_COLOR_YELLOW 7 +#define TGI_COLOR_ORANGE 8 +#define TGI_COLOR_BROWN 9 +#define TGI_COLOR_LIGHTRED 10 +#define TGI_COLOR_GRAY1 11 +#define TGI_COLOR_GRAY2 12 +#define TGI_COLOR_LIGHTGREEN 13 +#define TGI_COLOR_LIGHTBLUE 14 +#define TGI_COLOR_GRAY3 15 +*/ /* Masks for joy_read */ #define JOY_UP_MASK 0x01 From 1c71d4c609c7f650ad3a3524b2afc132d8e0f7fa Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Thu, 12 Jun 2025 00:35:29 +0200 Subject: [PATCH 483/707] Update tgidemo.c TGI color defines should be indices into the default palette --- samples/tgidemo.c | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/samples/tgidemo.c b/samples/tgidemo.c index 8a7ce2bfb..d6ae545dc 100644 --- a/samples/tgidemo.c +++ b/samples/tgidemo.c @@ -12,8 +12,11 @@ # define DYN_DRV 1 #endif -#define COLOR_BACK 0 -#define COLOR_FORE 1 + +/* TGI colors are indices into the default palette. So keep in mind that, if + you redefine the palette, those names may no more match the actual colors. */ +#define COLOR_BACK TGI_COLOR_BLACK +#define COLOR_FORE TGI_COLOR_WHITE /*****************************************************************************/ @@ -65,17 +68,36 @@ static void DoWarning (void) #endif +/* + * Note that everywhere else in the TGI API, colors are referred to via TGI_COLOR_ + * color indices, which in turn refer to the default TGI palette. + * + * Redefining the colors (changing the palette) is a target dependend operation, + * and the colors/values in the palette itself are not portable. + * + * That said, for some (perhaps most?) targets, the COLOR_ values may work here. + */ +static void DoPalette (int n) +{ + static const unsigned char Palette[4][2] = { +/* FIXME: add some ifdefs with proper values for targets that need it */ + { COLOR_BLACK, COLOR_BLUE }, + { COLOR_WHITE, COLOR_BLACK }, + { COLOR_RED, COLOR_BLACK }, + { COLOR_BLACK, COLOR_BLACK } + }; + tgi_setpalette (Palette[n]); +} + static void DoCircles (void) { - static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLUE }; unsigned char I; unsigned char Color = COLOR_BACK; const unsigned X = MaxX / 2; const unsigned Y = MaxY / 2; const unsigned Limit = (X < Y) ? Y : X; - tgi_setpalette (Palette); tgi_setcolor (COLOR_FORE); tgi_clear (); tgi_line (0, 0, MaxX, MaxY); @@ -95,11 +117,9 @@ static void DoCircles (void) static void DoCheckerboard (void) { - static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK }; unsigned X, Y; unsigned char Color = COLOR_BACK; - tgi_setpalette (Palette); tgi_clear (); while (1) { @@ -123,13 +143,11 @@ static void DoCheckerboard (void) static void DoDiagram (void) { - static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK }; int XOrigin, YOrigin; int Amp; int X, Y; unsigned I; - tgi_setpalette (Palette); tgi_setcolor (COLOR_FORE); tgi_clear (); @@ -167,11 +185,9 @@ static void DoDiagram (void) static void DoLines (void) { - static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK }; unsigned X; const unsigned Min = (MaxX < MaxY) ? MaxX : MaxY; - tgi_setpalette (Palette); tgi_setcolor (COLOR_FORE); tgi_clear (); @@ -216,10 +232,12 @@ int main (void) Border = bordercolor (COLOR_BLACK); /* Do graphics stuff */ + + /* first uses the default palette */ DoCircles (); - DoCheckerboard (); - DoDiagram (); - DoLines (); + DoPalette (0); DoCheckerboard (); + DoPalette (1); DoDiagram (); + DoPalette (2); DoLines (); #if DYN_DRV /* Unload the driver */ From 2f16defd6fed0dfa0fd00671ed30e26508897600 Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Thu, 12 Jun 2025 00:45:17 +0200 Subject: [PATCH 484/707] Update tgidemo.c - apple2 fix --- samples/tgidemo.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/samples/tgidemo.c b/samples/tgidemo.c index d6ae545dc..9fa81fa82 100644 --- a/samples/tgidemo.c +++ b/samples/tgidemo.c @@ -81,15 +81,23 @@ 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__) { COLOR_BLACK, COLOR_BLUE }, { COLOR_WHITE, COLOR_BLACK }, { COLOR_RED, COLOR_BLACK }, { COLOR_BLACK, COLOR_BLACK } +#else + { COLOR_WHITE, COLOR_BLACK }, + { COLOR_BLACK, COLOR_BLACK }, + { COLOR_WHITE, COLOR_BLACK }, + { COLOR_BLACK, COLOR_BLACK } +#endif }; tgi_setpalette (Palette[n]); } + static void DoCircles (void) { unsigned char I; From c3defc1b1c48b2f8db7719aa30e7bc7c9136e7cd Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Thu, 12 Jun 2025 01:00:17 +0200 Subject: [PATCH 485/707] Update tgidemo.c - i really like BLACK but that was a bit much :) --- samples/tgidemo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/tgidemo.c b/samples/tgidemo.c index 9fa81fa82..132697182 100644 --- a/samples/tgidemo.c +++ b/samples/tgidemo.c @@ -85,12 +85,12 @@ static void DoPalette (int n) { COLOR_BLACK, COLOR_BLUE }, { COLOR_WHITE, COLOR_BLACK }, { COLOR_RED, COLOR_BLACK }, - { COLOR_BLACK, COLOR_BLACK } + { COLOR_BLACK, COLOR_WHITE } #else { COLOR_WHITE, COLOR_BLACK }, - { COLOR_BLACK, COLOR_BLACK }, + { COLOR_BLACK, COLOR_WHITE }, { COLOR_WHITE, COLOR_BLACK }, - { COLOR_BLACK, COLOR_BLACK } + { COLOR_BLACK, COLOR_WHITE } #endif }; tgi_setpalette (Palette[n]); From 880322a5ae936c868398bd4233866b2fcbb5f436 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Thu, 12 Jun 2025 06:06:52 +0000 Subject: [PATCH 486/707] renamed test as requested. --- test/{todo => val}/bug2608.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{todo => val}/bug2608.c (100%) diff --git a/test/todo/bug2608.c b/test/val/bug2608.c similarity index 100% rename from test/todo/bug2608.c rename to test/val/bug2608.c From ace81bd36a5c6df0880a2722a1fe34112ce1e1e7 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 12 Jun 2025 14:42:38 +0200 Subject: [PATCH 487/707] Add macros to check for CPU type and supported instruction set. --- doc/cc65.sgml | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ src/cc65/main.c | 84 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 172 insertions(+), 2 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 6793603d5..55b84ed5c 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1154,6 +1154,96 @@ The compiler defines several macros at startup: <item><tt/__CC65_STD_CC65__/ </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> This macro is defined if the target is the Commander X16 (-t cx16). diff --git a/src/cc65/main.c b/src/cc65/main.c index 47435757c..a0c4848c9 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -317,6 +317,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) /* Handle an option that remembers a file name for later */ { @@ -477,7 +552,9 @@ static void OptCreateFullDep (const char* Opt attribute ((unused)), static void OptCPU (const char* Opt, const char* Arg) /* 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); if (CPU != CPU_6502 && CPU != CPU_6502X && CPU != CPU_65SC02 && CPU != CPU_65C02 && CPU != CPU_65816 && CPU != CPU_HUC6280 && @@ -1063,7 +1140,9 @@ int main (int argc, char* argv[]) /* Create the output file name if it was not explicitly given */ 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 (Target != TGT_UNKNOWN) { CPU = GetTargetProperties (Target)->DefaultCPU; @@ -1071,6 +1150,7 @@ int main (int argc, char* argv[]) CPU = CPU_6502; } } + DefineCpuMacros (); /* If no memory model was given, use the default */ if (MemoryModel == MMODEL_UNKNOWN) { From ffd667c2c9d20682b5c4ebb41d2a5102ee9b727c Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Tue, 10 Jun 2025 19:40:18 +0200 Subject: [PATCH 488/707] Fix temporary file name creation. Use the original name as template for readability in the map file, and use the process PID instead of platform-dependant or deprecated random filename functions to make unique temporary filenames. Also, create these temporary files in the output directory. --- src/cl65/main.c | 15 ++++++++--- src/common/fname.c | 65 +++++++++++++++++++++++++++++----------------- src/common/fname.h | 10 ++++--- 3 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 42126e6d7..528e64e56 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -122,6 +122,11 @@ static int DoAssemble = 1; /* The name of the output file, NULL if none given */ 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 */ static const char* LinkerConfig = 0; @@ -555,7 +560,7 @@ static void AssembleFile (const char* File, const char* TmpFile, unsigned ArgCou if (TmpFile) { ObjName = MakeFilename (TmpFile, ".o"); } else { - ObjName = MakeTmpFilename (".o"); + ObjName = MakeTmpFilename (OutputDirectory, File, ".o"); } CmdSetOutput (&CA65, ObjName); CmdAddFile (&LD65, ObjName); @@ -684,7 +689,7 @@ static void Compile (const char* File) if (DoAssemble) { /* set a temporary output file name */ - TmpFile = MakeTmpFilename(".s"); + TmpFile = MakeTmpFilename(OutputDirectory, File, ".s"); CmdSetOutput (&CC65, TmpFile); } @@ -729,7 +734,7 @@ static void CompileRes (const char* File) ** BEFORE adding the file */ if (DoAssemble && DoLink) { - AsmName = MakeTmpFilename(".s"); + AsmName = MakeTmpFilename(OutputDirectory, File, ".s"); CmdSetAsmOutput(&GRC, AsmName); } @@ -1623,6 +1628,7 @@ int main (int argc, char* argv []) case 'o': /* Name the output file */ OutputName = GetArg (&I, 2); + OutputDirectory = GetFileDirectory(OutputName); break; case 'r': @@ -1713,6 +1719,9 @@ int main (int argc, char* argv []) } RemoveTempFiles (); + if (OutputDirectory != NULL) { + xfree(OutputDirectory); + } /* Return an apropriate exit code */ return EXIT_SUCCESS; diff --git a/src/common/fname.c b/src/common/fname.c index e67470b33..d835ee7a0 100644 --- a/src/common/fname.c +++ b/src/common/fname.c @@ -33,8 +33,17 @@ +#include <errno.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> +#include <time.h> + +#if defined(_MSC_VER) +# include <process.h> +#else +# include <unistd.h> +#endif #include "xmalloc.h" #include "fname.h" @@ -93,7 +102,28 @@ const char* FindName (const char* Path) 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) /* Make a new file name from Origin and Ext. If Origin has an extension, it @@ -119,35 +149,22 @@ char* MakeFilename (const char* Origin, const char* Ext) -char* MakeTmpFilename (const char* Ext) -/* Make a new temporary file name from Ext. tmpnam(3) is called -** and Ext is appended to generate the filename. +char* MakeTmpFilename (const char *Directory, const char *Origin, const char* Ext) +/* Make a new temporary file name from Origin and Ext. ** The result is placed in a malloc'ed buffer and returned. */ { char* Out; - char Buffer[L_tmpnam * 2]; /* a lazy way to ensure we have space for Ext */ + size_t Len = 0; - /* - ** gcc emits the following warning here: - ** - ** 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); - strcpy (Out, Buffer); + /* Allocate template */ + if (Directory != NULL) { + Len = strlen (Directory); + } + Len += strlen (Origin) + strlen (".2147483648") + strlen (Ext) + 1; + Out = xmalloc (Len); + snprintf (Out, Len, "%s%s.%u%s", (Directory != NULL ? Directory : ""), + FindName(Origin), getpid(), Ext); return Out; } diff --git a/src/common/fname.h b/src/common/fname.h index 852c4ae56..ede34152d 100644 --- a/src/common/fname.h +++ b/src/common/fname.h @@ -52,6 +52,9 @@ const char* FindName (const char* Path); ** 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); /* 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 @@ -59,9 +62,10 @@ char* MakeFilename (const char* Origin, const char* Ext); ** The function may be used to create "foo.o" from "foo.s". */ -char* MakeTmpFilename (const char* Ext); -/* Make a new temporary file name from Ext. tmpnam(3) is called -** and Ext is appended to generate the filename. +char* MakeTmpFilename (const char *Directory, const char *Origin, const char* Ext); +/* Make a new temporary file name from Directory, Origin, and Ext. +** 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. */ From 149b2b69efc46935a55903bbe225a7b0df84c1a0 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Thu, 12 Jun 2025 19:21:57 +0200 Subject: [PATCH 489/707] Use new CPU macro to optimize ntohs on 65c02 --- include/arpa/inet.h | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/include/arpa/inet.h b/include/arpa/inet.h index cd353a2bb..3d715766f 100644 --- a/include/arpa/inet.h +++ b/include/arpa/inet.h @@ -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) int __fastcall__ ntohs (int val); @@ -56,12 +70,12 @@ int __fastcall__ htons (int val); ) #define htons(x) ntohs(x) -#endif +#endif /* __OPT_i__ < 200 */ + +#endif /* __CPU__ & __CPU_ISET_65SC02__ */ long __fastcall__ ntohl (long val); long __fastcall__ htonl (long val); - - /* End of arpa/inet.h */ #endif From 86cf60d0e62da6889e863a1ee90700ef1da6758f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 12 Jun 2025 20:53:55 +0200 Subject: [PATCH 490/707] add dbginfo to src/Makefile, add building dbginfo example to CI. Fixes #2681, supersedes #2682 --- .github/workflows/build-on-pull-request.yml | 3 +++ Makefile | 1 + src/Makefile | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 7b762844b..9158f7731 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -27,6 +27,9 @@ jobs: - name: Build the tools. shell: bash run: make -j2 bin USER_CFLAGS=-Werror + - name: Build the dbginfo example + shell: bash + run: make -j2 src dbginfo - name: Build the utilities. shell: bash run: make -j2 util diff --git a/Makefile b/Makefile index 29fcbbf96..0eb18f94b 100644 --- a/Makefile +++ b/Makefile @@ -50,6 +50,7 @@ test: # GNU "check" target, which runs all tests check: @$(MAKE) -C .github/checks checkstyle --no-print-directory + @$(MAKE) -C src dbginfo --no-print-directory @$(MAKE) test @$(MAKE) -C targettest platforms --no-print-directory @$(MAKE) -C samples platforms --no-print-directory diff --git a/src/Makefile b/src/Makefile index 034a2230f..27724028c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -21,7 +21,7 @@ PROGS = ar65 \ sim65 \ sp65 -.PHONY: all mostlyclean clean install zip avail unavail bin $(PROGS) +.PHONY: all mostlyclean clean install zip avail unavail bin $(PROGS) dbginfo .SUFFIXES: @@ -168,4 +168,7 @@ $(eval $(call OBJS_template,common)) $(foreach prog,$(PROGS),$(eval $(call PROG_template,$(prog)))) +dbginfo: +$(eval $(call PROG_template,dbginfo)) + -include $(DEPS) From b2616eac0dc80d277e99e99cb2b542a84a1799e5 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 12 Jun 2025 20:58:36 +0200 Subject: [PATCH 491/707] use -C correctly :) --- .github/workflows/build-on-pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 9158f7731..376dc9560 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -29,7 +29,7 @@ jobs: run: make -j2 bin USER_CFLAGS=-Werror - name: Build the dbginfo example shell: bash - run: make -j2 src dbginfo + run: make -j2 -C src dbginfo - name: Build the utilities. shell: bash run: make -j2 util From 505160f169859a270675d45850a740c4b17e9adb Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:31:05 +0200 Subject: [PATCH 492/707] a bit cleaner, also build dbgsh --- .github/workflows/build-on-pull-request.yml | 2 +- Makefile | 2 +- src/Makefile | 18 +++++++++++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 376dc9560..8f68b024c 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -29,7 +29,7 @@ jobs: run: make -j2 bin USER_CFLAGS=-Werror - name: Build the dbginfo example shell: bash - run: make -j2 -C src dbginfo + run: make -j2 -C src test - name: Build the utilities. shell: bash run: make -j2 util diff --git a/Makefile b/Makefile index 0eb18f94b..9e30d2bb4 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ test: # GNU "check" target, which runs all tests check: @$(MAKE) -C .github/checks checkstyle --no-print-directory - @$(MAKE) -C src dbginfo --no-print-directory + @$(MAKE) -C src test --no-print-directory @$(MAKE) test @$(MAKE) -C targettest platforms --no-print-directory @$(MAKE) -C samples platforms --no-print-directory diff --git a/src/Makefile b/src/Makefile index 27724028c..c5d91ce5a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -21,7 +21,7 @@ PROGS = ar65 \ sim65 \ sp65 -.PHONY: all mostlyclean clean install zip avail unavail bin $(PROGS) dbginfo +.PHONY: all mostlyclean clean install zip avail unavail bin $(PROGS) .SUFFIXES: @@ -168,7 +168,19 @@ $(eval $(call OBJS_template,common)) $(foreach prog,$(PROGS),$(eval $(call PROG_template,$(prog)))) -dbginfo: -$(eval $(call PROG_template,dbginfo)) + +.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) From a6b94ebba240d9263b2e328a13abc9d800bde660 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:50:20 +0200 Subject: [PATCH 493/707] Implement -dD, -dM and -dN command line switches to output macro definitions. --- doc/cc65.sgml | 23 +++++++++++ src/cc65/compile.c | 11 +++++ src/cc65/global.c | 5 ++- src/cc65/global.h | 5 ++- src/cc65/macrotab.c | 99 ++++++++++++++++++++++++++++++++++++++++++--- src/cc65/macrotab.h | 16 ++++++-- src/cc65/main.c | 31 +++++++++++++- src/cc65/preproc.c | 2 +- 8 files changed, 179 insertions(+), 13 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 55b84ed5c..b53007e46 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -63,6 +63,9 @@ Short options: -V Print the compiler version number -W [-+]warning[,...] Control warnings ('-' disables, '+' enables) -d Debug mode + -dD Output all macro definitions (needs -E) + -dM Output user defined macros (needs -E) + -dN Output user defined macro names (needs -E) -g Add debug info to object file -h Help (this text) -j Default characters are signed @@ -199,6 +202,26 @@ Here is a description of all the command line options: Enables debug mode, for debugging the behavior of cc65. + <label id="option-dD"> + <tag><tt>-dD</tt></tag> + + Like <tt/<ref id="option-dM" name="-dM">/ but does not include the predefined + macros. + + + <label id="option-dM"> + <tag><tt>-dM</tt></tag> + + When used with -E, will output <tt>#define</tt> directives for all the macros + defined during execution of the preprocessor, including predefined macros. + + + <tag><tt>-dN</tt></tag> + + Like <tt/<ref id="option-dD" name="-dD">/ but will only output the macro names, + not their definitions. + + <tag><tt>--debug-tables name</tt></tag> Writes symbol table information to a file, which includes details on structs, unions diff --git a/src/cc65/compile.c b/src/cc65/compile.c index e08a829e6..5b9ef1551 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -496,6 +496,17 @@ void Compile (const char* FileName) while (PreprocessNextLine ()) { /* Nothing */ } + /* Output macros if requested by the user */ + if (DumpAllMacrosFull) { + OutputAllMacrosFull (); + } + if (DumpUserMacros) { + OutputUserMacros (); + } + if (DumpUserMacrosFull) { + OutputUserMacrosFull (); + } + /* Close the output file */ CloseOutputFile (); diff --git a/src/cc65/global.c b/src/cc65/global.c index b2c3ef0a0..6fcc5d9d7 100644 --- a/src/cc65/global.c +++ b/src/cc65/global.c @@ -44,12 +44,15 @@ unsigned char AddSource = 0; /* Add source lines as comments */ +unsigned char AllowNewComments = 0; /* Allow new style comments in C89 mode */ unsigned char AutoCDecl = 0; /* Make functions default to __cdecl__ */ unsigned char DebugInfo = 0; /* Add debug info to the obj */ +unsigned char DumpAllMacrosFull = 0; /* Output all macro defs */ +unsigned char DumpUserMacros = 0; /* Output user macro names */ +unsigned char DumpUserMacrosFull= 0; /* Output user macro defs */ unsigned char PreprocessOnly = 0; /* Just preprocess the input */ unsigned char DebugOptOutput = 0; /* Output debug stuff */ unsigned RegisterSpace = 6; /* Space available for register vars */ -unsigned AllowNewComments = 0; /* Allow new style comments in C89 mode */ /* Stackable options */ IntStack WritableStrings = INTSTACK(0); /* Literal strings are r/w */ diff --git a/src/cc65/global.h b/src/cc65/global.h index ba7105130..d475c73e5 100644 --- a/src/cc65/global.h +++ b/src/cc65/global.h @@ -52,12 +52,15 @@ /* Options */ extern unsigned char AddSource; /* Add source lines as comments */ +extern unsigned char AllowNewComments; /* Allow new style comments in C89 mode */ extern unsigned char AutoCDecl; /* Make functions default to __cdecl__ */ extern unsigned char DebugInfo; /* Add debug info to the obj */ +extern unsigned char DumpAllMacrosFull; /* Output all macro defs */ +extern unsigned char DumpUserMacros; /* Output user macro names */ +extern unsigned char DumpUserMacrosFull; /* Output user macro defs */ extern unsigned char PreprocessOnly; /* Just preprocess the input */ extern unsigned char DebugOptOutput; /* Output debug stuff */ extern unsigned RegisterSpace; /* Space available for register vars */ -extern unsigned AllowNewComments; /* Allow new style comments in C89 mode */ /* Stackable options */ extern IntStack WritableStrings; /* Literal strings are r/w */ diff --git a/src/cc65/macrotab.c b/src/cc65/macrotab.c index 3bfae0811..41345db8a 100644 --- a/src/cc65/macrotab.c +++ b/src/cc65/macrotab.c @@ -1,4 +1,4 @@ -/*****************************************************************************/ + /* */ /* macrotab.h */ /* */ @@ -42,6 +42,7 @@ /* cc65 */ #include "error.h" +#include "output.h" #include "preproc.h" #include "macrotab.h" @@ -60,6 +61,67 @@ static Macro* MacroTab[MACRO_TAB_SIZE]; /* The undefined macros list head */ static Macro* UndefinedMacrosListHead; +/* Some defines for better readability when calling OutputMacros() */ +#define ALL_MACROS 0 +#define USER_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 UserOnly, int Full) +/* Output macros to the output file depending on the flags given */ +{ + unsigned I; + for (I = 0; I < MACRO_TAB_SIZE; ++I) { + const Macro* M = MacroTab [I]; + while (M) { + if (!UserOnly || !M->Predefined) { + OutputMacro (M, Full); + } + M = M->Next; + } + } +} + /*****************************************************************************/ @@ -68,7 +130,7 @@ static Macro* UndefinedMacrosListHead; -Macro* NewMacro (const char* Name) +Macro* NewMacro (const char* Name, unsigned char Predefined) /* Allocate a macro structure with the given name. The structure is not ** inserted into the macro table. */ @@ -84,6 +146,7 @@ Macro* NewMacro (const char* Name) M->ParamCount = -1; /* Flag: Not a function-like macro */ InitCollection (&M->Params); SB_Init (&M->Replacement); + M->Predefined = Predefined; M->Variadic = 0; memcpy (M->Name, Name, Len+1); @@ -116,7 +179,7 @@ Macro* CloneMacro (const Macro* M) ** Use FreeMacro for that. */ { - Macro* New = NewMacro (M->Name); + Macro* New = NewMacro (M->Name, M->Predefined); unsigned I; for (I = 0; I < CollCount (&M->Params); ++I) { @@ -134,7 +197,7 @@ Macro* CloneMacro (const Macro* M) void DefineNumericMacro (const char* Name, long Val) -/* Define a macro for a numeric constant */ +/* Define a predefined macro for a numeric constant */ { char Buf[64]; @@ -148,10 +211,10 @@ void DefineNumericMacro (const char* Name, long Val) void DefineTextMacro (const char* Name, const char* Val) -/* Define a macro for a textual constant */ +/* Define a predefined macro for a textual constant */ { /* Create a new macro */ - Macro* M = NewMacro (Name); + Macro* M = NewMacro (Name, 1); /* Set the value as replacement text */ SB_CopyStr (&M->Replacement, Val); @@ -350,3 +413,27 @@ void PrintMacroStats (FILE* F) } } } + + + +void OutputAllMacrosFull (void) +/* Output all macros to the output file */ +{ + OutputMacros (ALL_MACROS, FULL_DEFINITION); +} + + + +void OutputUserMacros (void) +/* Output the names of all user defined macros to the output file */ +{ + OutputMacros (USER_MACROS, NAME_ONLY); +} + + + +void OutputUserMacrosFull (void) +/* Output all user defined macros to the output file */ +{ + OutputMacros (USER_MACROS, FULL_DEFINITION); +} diff --git a/src/cc65/macrotab.h b/src/cc65/macrotab.h index 52b812b2f..8d2a04755 100644 --- a/src/cc65/macrotab.h +++ b/src/cc65/macrotab.h @@ -58,6 +58,7 @@ struct Macro { int ParamCount; /* Number of parameters, -1 = no parens */ Collection Params; /* Parameter list (char*) */ StrBuf Replacement; /* Replacement text */ + unsigned char Predefined; /* True if this is a predefined macro */ unsigned char Variadic; /* C99 variadic macro */ char Name[1]; /* Name, dynamically allocated */ }; @@ -70,7 +71,7 @@ struct Macro { -Macro* NewMacro (const char* Name); +Macro* NewMacro (const char* Name, unsigned char Predefined); /* Allocate a macro structure with the given name. The structure is not ** inserted into the macro table. */ @@ -87,10 +88,10 @@ Macro* CloneMacro (const Macro* M); */ void DefineNumericMacro (const char* Name, long Val); -/* Define a macro for a numeric constant */ +/* Define a predefined macro for a numeric constant */ void DefineTextMacro (const char* Name, const char* Val); -/* Define a macro for a textual constant */ +/* Define a predefined macro for a textual constant */ void InsertMacro (Macro* M); /* Insert the given macro into the macro table. */ @@ -132,6 +133,15 @@ int MacroCmp (const Macro* M1, const Macro* M2); void PrintMacroStats (FILE* F); /* Print macro statistics to the given text file. */ +void OutputAllMacrosFull (void); +/* Output all macros to the output file */ + +void OutputUserMacros (void); +/* Output the names of all user defined macros to the output file */ + +void OutputUserMacrosFull (void); +/* Output all user defined macros to the output file */ + /* End of macrotab.h */ diff --git a/src/cc65/main.c b/src/cc65/main.c index a0c4848c9..72a7ebd82 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -93,6 +93,9 @@ static void Usage (void) " -V\t\t\t\tPrint the compiler version number\n" " -W [-+]warning[,...]\t\tControl warnings ('-' disables, '+' enables)\n" " -d\t\t\t\tDebug mode\n" + " -dD\t\t\t\tOutput all macro definitions (needs -E)\n" + " -dM\t\t\t\tOutput user defined macros (needs -E)\n" + " -dN\t\t\t\tOutput user defined macro names (needs -E)\n" " -g\t\t\t\tAdd debug info to object file\n" " -h\t\t\t\tHelp (this text)\n" " -j\t\t\t\tDefault characters are signed\n" @@ -1022,7 +1025,26 @@ int main (int argc, char* argv[]) break; case 'd': - OptDebug (Arg, 0); + switch (Arg[2]) { + case '\0': + OptDebug (Arg, 0); + break; + case 'D': + DumpUserMacrosFull = 1; + break; + case 'M': + DumpAllMacrosFull = 1; + break; + case 'N': + DumpUserMacros = 1; + break; + default: + UnknownOption (Arg); + break; + } + if (Arg[2] && Arg[3]) { + UnknownOption (Arg); + } break; case 'h': @@ -1134,6 +1156,13 @@ int main (int argc, char* argv[]) AbEnd ("No input files"); } + /* The options to output macros can only be used with -E */ + if (DumpAllMacrosFull || DumpUserMacros || DumpUserMacrosFull) { + if (!PreprocessOnly) { + AbEnd ("Preprocessor macro output can only be used together with -E"); + } + } + /* Add the default include search paths. */ FinishIncludePaths (); diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index d70c28147..feba933cf 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -2573,7 +2573,7 @@ static void DoDefine (void) CheckForBadIdent (Ident, Std, 0); /* Create a new macro definition */ - M = NewMacro (Ident); + M = NewMacro (Ident, 0); /* Check if this is a function-like macro */ if (CurC == '(') { From 40aced6d6d5331072986c9ae6f9a583909a32b44 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 12 Jun 2025 22:02:35 +0200 Subject: [PATCH 494/707] Command line switches -dD and -Dm were swapped in the usage information. --- doc/cc65.sgml | 8 ++++---- src/cc65/main.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index b53007e46..368d3269c 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -63,8 +63,8 @@ Short options: -V Print the compiler version number -W [-+]warning[,...] Control warnings ('-' disables, '+' enables) -d Debug mode - -dD Output all macro definitions (needs -E) - -dM Output user defined macros (needs -E) + -dD Output user defined macros (needs -E) + -dM Output all macro definitions (needs -E) -dN Output user defined macro names (needs -E) -g Add debug info to object file -h Help (this text) @@ -200,13 +200,13 @@ Here is a description of all the command line options: <tag><tt>-d, --debug</tt></tag> Enables debug mode, for debugging the behavior of cc65. - + <label id="option-dD"> <tag><tt>-dD</tt></tag> Like <tt/<ref id="option-dM" name="-dM">/ but does not include the predefined - macros. + macros. <label id="option-dM"> diff --git a/src/cc65/main.c b/src/cc65/main.c index 72a7ebd82..4ff17ada9 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -93,8 +93,8 @@ static void Usage (void) " -V\t\t\t\tPrint the compiler version number\n" " -W [-+]warning[,...]\t\tControl warnings ('-' disables, '+' enables)\n" " -d\t\t\t\tDebug mode\n" - " -dD\t\t\t\tOutput all macro definitions (needs -E)\n" - " -dM\t\t\t\tOutput user defined macros (needs -E)\n" + " -dD\t\t\t\tOutput user defined macros (needs -E)\n" + " -dM\t\t\t\tOutput all macro definitions (needs -E)\n" " -dN\t\t\t\tOutput user defined macro names (needs -E)\n" " -g\t\t\t\tAdd debug info to object file\n" " -h\t\t\t\tHelp (this text)\n" From b7a5ec86c53fbf4d360541d862dfd207cc003025 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 12 Jun 2025 22:09:53 +0200 Subject: [PATCH 495/707] Remove trailing spaces. --- doc/cc65.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 368d3269c..a78f1a00a 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -200,13 +200,13 @@ Here is a description of all the command line options: <tag><tt>-d, --debug</tt></tag> Enables debug mode, for debugging the behavior of cc65. - + <label id="option-dD"> <tag><tt>-dD</tt></tag> Like <tt/<ref id="option-dM" name="-dM">/ but does not include the predefined - macros. + macros. <label id="option-dM"> From c28bafa581b6f3b498b9f02868955bee8b4b7723 Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Fri, 13 Jun 2025 12:50:39 +0300 Subject: [PATCH 496/707] add chline, cvline functions --- include/agat.h | 9 +++++++-- libsrc/agat/chline.s | 33 +++++++++++++++++++++++++++++++++ libsrc/agat/cputc.s | 19 +++++++++++++++---- libsrc/agat/cvline.s | 29 +++++++++++++++++++++++++++++ libsrc/agat/home.s | 2 +- 5 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 libsrc/agat/chline.s create mode 100644 libsrc/agat/cvline.s diff --git a/include/agat.h b/include/agat.h index 2cdf24ae6..04ec16984 100644 --- a/include/agat.h +++ b/include/agat.h @@ -32,7 +32,12 @@ #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 @@ -68,4 +73,4 @@ void rebootafterexit (void); /* End of agat.h */ -#endif //_AGAT_H +#endif diff --git a/libsrc/agat/chline.s b/libsrc/agat/chline.s new file mode 100644 index 000000000..bc95b2a16 --- /dev/null +++ b/libsrc/agat/chline.s @@ -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 + diff --git a/libsrc/agat/cputc.s b/libsrc/agat/cputc.s index b8d99aaea..b82ce22e6 100644 --- a/libsrc/agat/cputc.s +++ b/libsrc/agat/cputc.s @@ -1,12 +1,13 @@ ; ; 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 + .export _cputcxy, _cputc, newline, putchar,putchardirect .import gotoxy, VTABZ .include "agat.inc" @@ -15,20 +16,21 @@ _cputcxy: jsr gotoxy pla _cputc: - cmp #$0D + cmp #$0D ; Test for \r = carriage return bne notleft ldy #$00 sty CH rts notleft: - cmp #$0A + cmp #$0A ; Test for \n = line feed beq newline + putchar: ldy CH sta (BASL),Y iny lda TATTR - bmi wch + bmi wch ; Skip if t64 sta (BASL),Y iny wch: @@ -47,3 +49,12 @@ newline: : jmp VTABZ noend: rts + +putchardirect: + ldy CH + sta (BASL),Y + lda TATTR + bmi :+ + iny + sta (BASL),Y +: rts diff --git a/libsrc/agat/cvline.s b/libsrc/agat/cvline.s new file mode 100644 index 000000000..63c0d4daf --- /dev/null +++ b/libsrc/agat/cvline.s @@ -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 diff --git a/libsrc/agat/home.s b/libsrc/agat/home.s index 5067a782a..a0434c9bb 100644 --- a/libsrc/agat/home.s +++ b/libsrc/agat/home.s @@ -11,5 +11,5 @@ HOME: lda #$8C - jsr COUT + jmp COUT rts From 8202b520b262cc0f27a4fa48eddc93e07d6d6042 Mon Sep 17 00:00:00 2001 From: Konstantin <sintechs@gmail.com> Date: Fri, 13 Jun 2025 12:51:41 +0300 Subject: [PATCH 497/707] add Agat to samples --- include/target.h | 2 ++ libsrc/agat/_scrsize.s | 12 +++++++++--- samples/Makefile | 6 ++++++ samples/sieve.c | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/target.h b/include/target.h index 7663a39dd..5f9d8859c 100644 --- a/include/target.h +++ b/include/target.h @@ -37,6 +37,8 @@ # include <apple2enh.h> #elif defined(__APPLE2__) # include <apple2.h> +#elif defined(__AGAT__) +# include <agat.h> #elif defined(__ATARI__) # include <atari.h> #elif defined(__ATARI2600__) diff --git a/libsrc/agat/_scrsize.s b/libsrc/agat/_scrsize.s index f9d7c3785..09d7e879f 100644 --- a/libsrc/agat/_scrsize.s +++ b/libsrc/agat/_scrsize.s @@ -1,5 +1,6 @@ ; ; Ullrich von Bassewitz, 26.10.2000 +; Konstantin Fedorov, 12.06.2025 ; ; Screen size variables ; @@ -9,9 +10,14 @@ .include "agat.inc" screensize: - ldx WNDWDTH - lda WNDBTM + lda WNDWDTH + bit TATTR + bmi t64 + lsr +t64: + tax + lda WNDBTM sec - sbc WNDTOP + sbc WNDTOP tay rts diff --git a/samples/Makefile b/samples/Makefile index 3680f542c..295b6883d 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -158,6 +158,11 @@ DIRLIST = tutorial geos atari2600 atari5200 apple2 gamate lynx supervision sym1 # -------------------------------------------------------------------------- # Lists of executables +EXELIST_agat = \ + ascii \ + checkversion \ + hello \ + sieve EXELIST_apple2 = \ ascii \ @@ -390,6 +395,7 @@ all: # -------------------------------------------------------------------------- # List of every supported platform TARGETS := \ + agat \ apple2 \ apple2enh \ atari \ diff --git a/samples/sieve.c b/samples/sieve.c index 7c3b9cd75..5ffc97b62 100644 --- a/samples/sieve.c +++ b/samples/sieve.c @@ -12,7 +12,7 @@ /* Workaround missing clock stuff */ -#ifdef __APPLE2__ +#if defined(__APPLE2__) || defined(__AGAT__) # define clock() 0 # define CLOCKS_PER_SEC 1 #endif From 215f51a23033f68e5b23d1839fec8d13eb588985 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Fri, 13 Jun 2025 13:55:05 +0200 Subject: [PATCH 498/707] Fix temporary filenames again. Outputting temp files in the output directory means we have to distinguish source files in different source directories that happen to have the same name. --- src/common/fname.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/common/fname.c b/src/common/fname.c index d835ee7a0..7c52869e2 100644 --- a/src/common/fname.c +++ b/src/common/fname.c @@ -156,15 +156,22 @@ char* MakeTmpFilename (const char *Directory, const char *Origin, const char* Ex { char* Out; size_t Len = 0; + static unsigned int Counter = 0; - /* Allocate template */ + /* Allocate enough for the directory, ... */ if (Directory != NULL) { Len = strlen (Directory); } - Len += strlen (Origin) + strlen (".2147483648") + strlen (Ext) + 1; + + /* ... plus the the original name, the maximum length of the PID, the + * 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%s", (Directory != NULL ? Directory : ""), - FindName(Origin), getpid(), Ext); + snprintf (Out, Len, "%s%s.%u%u%s", (Directory != NULL ? Directory : ""), + FindName(Origin), getpid(), Counter, Ext); + Counter++; + return Out; } From 2f55eeb6125c52c4d6a86d291474e44b5cb9fc50 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Sat, 14 Jun 2025 01:11:39 +0000 Subject: [PATCH 499/707] sp -> c_sp for agat/crt0.s --- libsrc/agat/crt0.s | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libsrc/agat/crt0.s b/libsrc/agat/crt0.s index 41f03b24d..eaca89308 100644 --- a/libsrc/agat/crt0.s +++ b/libsrc/agat/crt0.s @@ -31,7 +31,7 @@ exit: bpl :- ldx #zpspace-1 : lda zpsave,x - sta sp,x + sta c_sp,x dex bpl :- ldx #$FF @@ -44,7 +44,7 @@ exit: init: ldx #zpspace-1 -: lda sp,x +: lda c_sp,x sta zpsave,x dex bpl :- @@ -57,8 +57,8 @@ init: lda HIMEM ldx HIMEM+1 - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 ldx #<_exit lda #>_exit jsr reset From e3f9a5f05267fb24433d0868c39b5ac0e8f2030d Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Sat, 14 Jun 2025 13:02:28 +0200 Subject: [PATCH 500/707] Make sure pid and counter don't interfere --- src/common/fname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/fname.c b/src/common/fname.c index 7c52869e2..10d38f38a 100644 --- a/src/common/fname.c +++ b/src/common/fname.c @@ -169,7 +169,7 @@ char* MakeTmpFilename (const char *Directory, const char *Origin, const char* Ex Len += strlen (Origin) + (strlen (".2147483648") * 2) + strlen (Ext) + 1; Out = xmalloc (Len); - snprintf (Out, Len, "%s%s.%u%u%s", (Directory != NULL ? Directory : ""), + snprintf (Out, Len, "%s%s.%u.%u%s", (Directory != NULL ? Directory : ""), FindName(Origin), getpid(), Counter, Ext); Counter++; From 1ac8a51c580870a43e79eb9d6733d9b92c891df4 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 14 Jun 2025 21:39:00 +0200 Subject: [PATCH 501/707] added repro cases from #2172 as tests --- test/todo/bug2172_invalid_code.c | 56 +++++++++++++++++++++++++++++++ test/todo/bug2172b_invalid_code.c | 51 ++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 test/todo/bug2172_invalid_code.c create mode 100644 test/todo/bug2172b_invalid_code.c diff --git a/test/todo/bug2172_invalid_code.c b/test/todo/bug2172_invalid_code.c new file mode 100644 index 000000000..74522c029 --- /dev/null +++ b/test/todo/bug2172_invalid_code.c @@ -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; +} diff --git a/test/todo/bug2172b_invalid_code.c b/test/todo/bug2172b_invalid_code.c new file mode 100644 index 000000000..13d983123 --- /dev/null +++ b/test/todo/bug2172b_invalid_code.c @@ -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; +} From 7620e551eedf13ec0f21defd868d4f71ed79af94 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 14 Jun 2025 22:40:29 +0200 Subject: [PATCH 502/707] add test --- test/standard/null.c | 162 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 test/standard/null.c diff --git a/test/standard/null.c b/test/standard/null.c new file mode 100644 index 000000000..cd4bd0a44 --- /dev/null +++ b/test/standard/null.c @@ -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; +} From 5be4c4697c33b1e9780122a43cb564b151bf0fd8 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 15 Jun 2025 18:25:01 +0200 Subject: [PATCH 503/707] original patch --- cfg/m740.cfg | 37 +++++++++++ src/ca65/instr.c | 156 +++++++++++++++++++++++++++++++++++++++++++-- src/ca65/instr.h | 67 ++++++++++--------- src/da65/handler.c | 15 +++++ src/da65/handler.h | 1 + src/da65/opcm740.c | 32 +++++----- 6 files changed, 256 insertions(+), 52 deletions(-) create mode 100644 cfg/m740.cfg diff --git a/cfg/m740.cfg b/cfg/m740.cfg new file mode 100644 index 000000000..e68bff0f5 --- /dev/null +++ b/cfg/m740.cfg @@ -0,0 +1,37 @@ +FEATURES { + STARTADDRESS: default = $8000; +} +SYMBOLS { + __STACKSIZE__: type = weak, value = $0000; # 2k stack + __STACKSTART__: type = weak, value = $100; + __ZPSTART__: type = weak, value = $0000; +} +MEMORY { + ZP: file = "", define = yes, start = __ZPSTART__, size = $001F; + MAIN: file = %O, start = %S, size = __STACKSTART__ - __STACKSIZE__ - %S; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + STARTUP: load = MAIN, type = ro, optional = yes; + LOWCODE: load = MAIN, type = ro, optional = yes; + ONCE: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = rw; + RODATA: load = MAIN, type = rw; + DATA: load = MAIN, type = rw; + BSS: load = MAIN, 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__; +} diff --git a/src/ca65/instr.c b/src/ca65/instr.c index c7a68006c..ddbd12125 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -85,6 +85,12 @@ static void PutBlockTransfer (const InsDesc* Ins); static void PutBitBranch (const InsDesc* Ins); /* Handle 65C02 branch on bit condition */ +static void PutBitBranchm740 (const InsDesc* Ins); +/* Handle m740 branch on bit condition */ + +static void PutLDMm740 (const InsDesc* Ins); +/* Handle m740 LDM instruction */ + static void PutREP (const InsDesc* Ins); /* Emit a REP instruction, track register sizes */ @@ -1047,7 +1053,114 @@ static const struct { } }; - +/* Instruction table for the m740 CPU */ +static const struct { + unsigned Count; + InsDesc Ins[97]; +} InsTabm740 = { + sizeof (InsTabm740.Ins) / sizeof (InsTabm740.Ins[0]), + { +/* BEGIN SORTED.SH */ + { "ADC", 0x080A26C, 0x60, 0, PutAll }, + { "AND", 0x080A26C, 0x20, 0, PutAll }, + { "ASL", 0x000006e, 0x02, 1, PutAll }, + { "BBR0", 0x0000006, 0x13, 10, PutBitBranchm740 }, + { "BBR1", 0x0000006, 0x33, 10, PutBitBranchm740 }, + { "BBR2", 0x0000006, 0x53, 10, PutBitBranchm740 }, + { "BBR3", 0x0000006, 0x73, 10, PutBitBranchm740 }, + { "BBR4", 0x0000006, 0x93, 10, PutBitBranchm740 }, + { "BBR5", 0x0000006, 0xb3, 10, PutBitBranchm740 }, + { "BBR6", 0x0000006, 0xd3, 10, PutBitBranchm740 }, + { "BBR7", 0x0000006, 0xf3, 10, PutBitBranchm740 }, + { "BBS0", 0x0000006, 0x03, 10, PutBitBranchm740 }, + { "BBS1", 0x0000006, 0x23, 10, PutBitBranchm740 }, + { "BBS2", 0x0000006, 0x43, 10, PutBitBranchm740 }, + { "BBS3", 0x0000006, 0x63, 10, PutBitBranchm740 }, + { "BBS4", 0x0000006, 0x83, 10, PutBitBranchm740 }, + { "BBS5", 0x0000006, 0xa3, 10, PutBitBranchm740 }, + { "BBS6", 0x0000006, 0xc3, 10, PutBitBranchm740 }, + { "BBS7", 0x0000006, 0xe3, 10, PutBitBranchm740 }, + { "BCC", 0x0020000, 0x90, 0, PutPCRel8 }, + { "BCS", 0x0020000, 0xb0, 0, PutPCRel8 }, + { "BEQ", 0x0020000, 0xf0, 0, PutPCRel8 }, + { "BIT", 0x000000C, 0x00, 2, PutAll }, + { "BMI", 0x0020000, 0x30, 0, PutPCRel8 }, + { "BNE", 0x0020000, 0xd0, 0, PutPCRel8 }, + { "BPL", 0x0020000, 0x10, 0, PutPCRel8 }, + { "BRA", 0x0020000, 0x80, 0, PutPCRel8 }, + { "BRK", 0x0000001, 0x00, 0, PutAll }, + { "BVC", 0x0020000, 0x50, 0, PutPCRel8 }, + { "BVS", 0x0020000, 0x70, 0, PutPCRel8 }, + { "CLC", 0x0000001, 0x18, 0, PutAll }, + { "CLD", 0x0000001, 0xd8, 0, PutAll }, + { "CLI", 0x0000001, 0x58, 0, PutAll }, + { "CLT", 0x0000001, 0x12, 0, PutAll }, + { "CLV", 0x0000001, 0xb8, 0, PutAll }, + { "CMP", 0x080A26C, 0xc0, 0, PutAll }, + { "COM", 0x0000004, 0x44, 1, PutAll }, + { "CPX", 0x080000C, 0xe0, 1, PutAll }, + { "CPY", 0x080000C, 0xc0, 1, PutAll }, + { "DEC", 0x000006F, 0x00, 3, PutAll }, + { "DEX", 0x0000001, 0xca, 0, PutAll }, + { "DEY", 0x0000001, 0x88, 0, PutAll }, + { "EOR", 0x080A26C, 0x40, 0, PutAll }, + { "FST", 0x0000001, 0xe2, 0, PutAll }, + { "INC", 0x000006f, 0x00, 4, PutAll }, + { "INX", 0x0000001, 0xe8, 0, PutAll }, + { "INY", 0x0000001, 0xc8, 0, PutAll }, + { "JMP", 0x0000C08, 0x00, 12, PutAll }, + { "JSR", 0x0080808, 0x00, 13, PutAll }, + { "LDA", 0x080A26C, 0xa0, 0, PutAll }, + { "LDM", 0x0000004, 0x3c, 6, PutLDMm740 }, + { "LDX", 0x080030C, 0xa2, 1, PutAll }, + { "LDY", 0x080006C, 0xa0, 1, PutAll }, + { "LSR", 0x000006F, 0x42, 1, PutAll }, + { "NOP", 0x0000001, 0xea, 0, PutAll }, + { "ORA", 0x080A26C, 0x00, 0, PutAll }, + { "PHA", 0x0000001, 0x48, 0, PutAll }, + { "PHP", 0x0000001, 0x08, 0, PutAll }, + { "PLA", 0x0000001, 0x68, 0, PutAll }, + { "PLP", 0x0000001, 0x28, 0, PutAll }, + { "RMB0", 0x0000006, 0x1b, 10, PutAll }, + { "RMB1", 0x0000006, 0x3b, 10, PutAll }, + { "RMB2", 0x0000006, 0x5b, 10, PutAll }, + { "RMB3", 0x0000006, 0x7b, 10, PutAll }, + { "RMB4", 0x0000006, 0x9b, 10, PutAll }, + { "RMB5", 0x0000006, 0xbb, 10, PutAll }, + { "RMB6", 0x0000006, 0xdb, 10, PutAll }, + { "RMB7", 0x0000006, 0xfb, 10, PutAll }, + { "ROL", 0x000006F, 0x22, 1, PutAll }, + { "ROR", 0x000006F, 0x62, 1, PutAll }, + { "RRF", 0x0000004, 0x82, 6, PutAll }, + { "RTI", 0x0000001, 0x40, 0, PutAll }, + { "RTS", 0x0000001, 0x60, 0, PutAll }, + { "SBC", 0x080A26C, 0xe0, 0, PutAll }, + { "SEC", 0x0000001, 0x38, 0, PutAll }, + { "SED", 0x0000001, 0xf8, 0, PutAll }, + { "SEI", 0x0000001, 0x78, 0, PutAll }, + { "SET", 0x0000001, 0x32, 0, PutAll }, + { "SLW", 0x0000001, 0xC2, 0, PutAll }, + { "SMB0", 0x0000006, 0x0b, 10, PutAll }, + { "SMB1", 0x0000006, 0x2b, 10, PutAll }, + { "SMB2", 0x0000006, 0x4b, 10, PutAll }, + { "SMB3", 0x0000006, 0x6b, 10, PutAll }, + { "SMB4", 0x0000006, 0x8b, 10, PutAll }, + { "SMB5", 0x0000006, 0xab, 10, PutAll }, + { "SMB6", 0x0000006, 0xcb, 10, PutAll }, + { "SMB7", 0x0000006, 0xeb, 10, PutAll }, + { "STA", 0x000A26C, 0x80, 0, PutAll }, + { "STP", 0x0000001, 0x42, 0, PutAll }, + { "STX", 0x000010c, 0x82, 1, PutAll }, + { "STY", 0x000002c, 0x80, 1, PutAll }, + { "TAX", 0x0000001, 0xaa, 0, PutAll }, + { "TAY", 0x0000001, 0xa8, 0, PutAll }, + { "TSX", 0x0000001, 0xba, 0, PutAll }, + { "TXA", 0x0000001, 0x8a, 0, PutAll }, + { "TXS", 0x0000001, 0x9a, 0, PutAll }, + { "TYA", 0x0000001, 0x98, 0, PutAll } +/* END SORTED.SH */ + } +}; /* An array with instruction tables */ static const InsTable* InsTabs[CPU_COUNT] = { @@ -1060,7 +1173,7 @@ static const InsTable* InsTabs[CPU_COUNT] = { (const InsTable*) &InsTab65816, (const InsTable*) &InsTabSweet16, (const InsTable*) &InsTabHuC6280, - 0, /* Mitsubishi 740 */ + (const InsTable*) &InsTabm740, /* Mitsubishi 740 */ (const InsTable*) &InsTab4510, }; const InsTable* InsTab = (const InsTable*) &InsTab6502; @@ -1068,7 +1181,7 @@ const InsTable* InsTab = (const InsTable*) &InsTab6502; /* Table to build the effective 65xx opcode from a base opcode and an ** addressing mode. (The value in the table is ORed with the base opcode) */ -static unsigned char EATab[12][AM65I_COUNT] = { +static unsigned char EATab[14][AM65I_COUNT] = { { /* Table 0 */ 0x00, 0x00, 0x05, 0x0D, 0x0F, 0x15, 0x1D, 0x1F, 0x00, 0x19, 0x12, 0x00, 0x07, 0x11, 0x17, 0x01, @@ -1141,6 +1254,18 @@ static unsigned char EATab[12][AM65I_COUNT] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x00 }, + { /* Table 12 m740 JMP */ + 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb2, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }, + { /* Table 13 m740 JSR */ + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }, }; /* Table to build the effective SWEET16 opcode from a base opcode and an @@ -1361,6 +1486,12 @@ static void EmitCode (EffAddr* A) } +static void PutLDMm740 (const InsDesc* Ins) +{ + + Emit0 (Ins->BaseCode); + EmitWord (Expression ()); +} static long PutImmed8 (const InsDesc* Ins) /* Parse and emit an immediate 8 bit instruction. Return the value of the @@ -1481,6 +1612,22 @@ static void PutBitBranch (const InsDesc* Ins) EmitSigned (GenBranchExpr (1), 1); } +static void PutBitBranchm740 (const InsDesc* Ins) +/* Handle 65C02 branch on bit condition */ +{ + EffAddr A; + + /* HACK: hardcoded for zp addressing mode, this doesn't work all the time */ + A.AddrMode = 2; + + A.Opcode = Ins->BaseCode | EATab[Ins->ExtCode][A.AddrMode]; + /* Evaluate the addressing mode used */ + /* No error, output code */ + Emit0 (A.Opcode); + EmitByte (Expression ()); + ConsumeComma (); + EmitSigned (GenBranchExpr (1), 1); +} static void PutREP (const InsDesc* Ins) @@ -1584,7 +1731,6 @@ static void PutTMAn (const InsDesc* Ins) ** an immediate argument. */ { - /* Emit the TMA opcode itself */ Emit0 (0x43); /* Emit the argument, which is the opcode from the table */ @@ -1640,10 +1786,8 @@ static void PutJMP (const InsDesc* Ins) */ { EffAddr A; - /* Evaluate the addressing mode used */ if (EvalEA (Ins, &A)) { - /* Check for indirect addressing */ if ((A.AddrModeBit & AM65_ABS_IND) && (CPU < CPU_65SC02) && (RelaxChecks == 0)) { diff --git a/src/ca65/instr.h b/src/ca65/instr.h index fe18d2110..823aa5659 100644 --- a/src/ca65/instr.h +++ b/src/ca65/instr.h @@ -58,53 +58,60 @@ ** When assembling for the 6502 or 65C02, all addressing modes that are not ** available on these CPUs are removed before doing any checks. */ -#define AM65_IMPLICIT 0x00000003UL -#define AM65_ACCU 0x00000002UL -#define AM65_DIR 0x00000004UL -#define AM65_ABS 0x00000008UL -#define AM65_ABS_LONG 0x00000010UL -#define AM65_DIR_X 0x00000020UL -#define AM65_ABS_X 0x00000040UL -#define AM65_ABS_LONG_X 0x00000080UL -#define AM65_DIR_Y 0x00000100UL -#define AM65_ABS_Y 0x00000200UL -#define AM65_DIR_IND 0x00000400UL -#define AM65_ABS_IND 0x00000800UL -#define AM65_DIR_IND_LONG 0x00001000UL -#define AM65_DIR_IND_Y 0x00002000UL -#define AM65_DIR_IND_LONG_Y 0x00004000UL -#define AM65_DIR_X_IND 0x00008000UL -#define AM65_ABS_X_IND 0x00010000UL -#define AM65_REL 0x00020000UL -#define AM65_REL_LONG 0x00040000UL -#define AM65_STACK_REL 0x00080000UL -#define AM65_STACK_REL_IND_Y 0x00100000UL +#define AM65_IMPLICIT 0x00000003UL /* IMP */ +#define AM65_ACCU 0x00000002UL /* A, BIT, A */ +#define AM65_DIR 0x00000004UL /* ZP, BIT, ZP */ +#define AM65_ABS 0x00000008UL /* ABS */ +#define AM65_ABS_LONG 0x00000010UL /* -- */ +#define AM65_DIR_X 0x00000020UL /* ZP,X */ +#define AM65_ABS_X 0x00000040UL /* ABS, X */ +#define AM65_ABS_LONG_X 0x00000080UL /* -- */ +#define AM65_DIR_Y 0x00000100UL /* ZP, Y */ +#define AM65_ABS_Y 0x00000200UL /* ABS, Y */ +#define AM65_DIR_IND 0x00000400UL /* ZP, IND */ +#define AM65_ABS_IND 0x00000800UL /* IND */ +#define AM65_DIR_IND_LONG 0x00001000UL /* -- */ +#define AM65_DIR_IND_Y 0x00002000UL /* IND, Y */ +#define AM65_DIR_IND_LONG_Y 0x00004000UL /* -- */ +#define AM65_DIR_X_IND 0x00008000UL /* IND, X */ +#define AM65_ABS_X_IND 0x00010000UL /* -- */ +#define AM65_REL 0x00020000UL /* REL */ +#define AM65_REL_LONG 0x00040000UL /* -- */ +#define AM65_STACK_REL 0x00080000UL /* SP ? */ +#define AM65_STACK_REL_IND_Y 0x00100000UL /* ? */ #define AM65_IMM_ACCU 0x00200000UL #define AM65_IMM_INDEX 0x00400000UL -#define AM65_IMM_IMPLICIT 0x00800000UL -#define AM65_BLOCKMOVE 0x01000000UL -#define AM65_BLOCKXFER 0x02000000UL -#define AM65_ABS_IND_LONG 0x04000000UL +#define AM65_IMM_IMPLICIT 0x00800000UL /* IMM */ +#define AM65_BLOCKMOVE 0x01000000UL /* -- */ +#define AM65_BLOCKXFER 0x02000000UL /* -- */ +#define AM65_ABS_IND_LONG 0x04000000UL /* -- */ #define AM65_IMM_IMPLICIT_WORD 0x08000000UL /* PHW #$1234 (4510 only) */ /* Bitmask for all ZP operations that have correspondent ABS ops */ +/* $8524 */ #define AM65_SET_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND) - + /*$4 $20 $100 $400 $8000 */ /* Bitmask for all ABS operations that have correspondent FAR ops */ +/* $48 */ #define AM65_SET_ABS (AM65_ABS | AM65_ABS_X) - +/* $8 $40 */ /* Bitmask for all ZP operations */ +/* $8524 */ #define AM65_ALL_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND) - + /*$4 $20 $100 $400 $8000 */ /* Bitmask for all ABS operations */ +/* $10a48 */ #define AM65_ALL_ABS (AM65_ABS | AM65_ABS_X | AM65_ABS_Y | AM65_ABS_IND | AM65_ABS_X_IND) - +/* $8 $40 $200 $800 $10000 */ /* Bitmask for all FAR operations */ +/* $90 */ #define AM65_ALL_FAR (AM65_ABS_LONG | AM65_ABS_LONG_X) + /* $10 $80 */ /* Bitmask for all immediate operations */ +/* $8e00 000 */ #define AM65_ALL_IMM (AM65_IMM_ACCU | AM65_IMM_INDEX | AM65_IMM_IMPLICIT | AM65_IMM_IMPLICIT_WORD) - +/* $200000 $400000 $800000 $8000000 */ /* Bit numbers and count */ #define AM65I_IMM_ACCU 21 #define AM65I_IMM_INDEX 22 diff --git a/src/da65/handler.c b/src/da65/handler.c index 79b3192de..3e448635d 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -531,7 +531,22 @@ void OH_BitBranch (const OpcDesc* D) xfree (BranchLabel); } +void OH_BitBranchm740 (const OpcDesc* D) +{ + unsigned Bit = GetCodeByte (PC) >> 5; + unsigned Addr = GetCodeByte (PC+1); + signed char BranchOffs = GetCodeByte (PC+2); + /* Calculate the target address for the branch */ + unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; + + /* Generate a label in pass 1 */ + GenerateLabel (D->Flags, Addr); + GenerateLabel (flLabel, BranchAddr); + + /* Output the line */ + OneLine (D, "%01X,%s,%s", Bit, GetAddrArg (D->Flags, Addr), GetAddrArg (flLabel, BranchAddr)); +} void OH_ImmediateDirect (const OpcDesc* D) { diff --git a/src/da65/handler.h b/src/da65/handler.h index ee9b18bbc..7688ff1c8 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -78,6 +78,7 @@ void OH_DirectXIndirect (const OpcDesc*); void OH_AbsoluteIndirect (const OpcDesc*); void OH_BitBranch (const OpcDesc*); +void OH_BitBranchm740 (const OpcDesc*); void OH_ImmediateDirect (const OpcDesc*); void OH_ImmediateDirectX (const OpcDesc*); diff --git a/src/da65/opcm740.c b/src/da65/opcm740.c index 67a36b48c..791f7f7a8 100644 --- a/src/da65/opcm740.c +++ b/src/da65/opcm740.c @@ -55,7 +55,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $04 */ { "ora", 2, flUseLabel, OH_Direct }, /* $05 */ { "asl", 2, flUseLabel, OH_Direct }, /* $06 */ - { "bbs", 3, flUseLabel, OH_ZeroPageBit }, /* $07 */ + { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $07 */ { "php", 1, flNone, OH_Implicit }, /* $08 */ { "ora", 2, flNone, OH_Immediate }, /* $09 */ { "asl", 1, flNone, OH_Accumulator }, /* $0a */ @@ -71,7 +71,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $14 */ { "ora", 2, flUseLabel, OH_DirectX }, /* $15 */ { "asl", 2, flUseLabel, OH_DirectX }, /* $16 */ - { "bbc", 3, flUseLabel, OH_ZeroPageBit }, /* $17 */ + { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $17 */ { "clc", 1, flNone, OH_Implicit }, /* $18 */ { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */ { "dec", 1, flNone, OH_Accumulator }, /* $1a */ @@ -87,7 +87,7 @@ const OpcDesc OpcTable_M740[256] = { { "bit", 2, flUseLabel, OH_Direct }, /* $24 */ { "and", 2, flUseLabel, OH_Direct }, /* $25 */ { "rol", 2, flUseLabel, OH_Direct }, /* $26 */ - { "bbs", 3, flUseLabel, OH_ZeroPageBit }, /* $27 */ + { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $27 */ { "plp", 1, flNone, OH_Implicit }, /* $28 */ { "and", 2, flNone, OH_Immediate }, /* $29 */ { "rol", 1, flNone, OH_Accumulator }, /* $2a */ @@ -103,7 +103,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $34 */ { "and", 2, flUseLabel, OH_DirectX }, /* $35 */ { "rol", 2, flUseLabel, OH_DirectX }, /* $36 */ - { "bbc", 3, flUseLabel, OH_ZeroPageBit }, /* $37 */ + { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $37 */ { "sec", 1, flNone, OH_Implicit }, /* $38 */ { "and", 3, flUseLabel, OH_AbsoluteY }, /* $39 */ { "inc", 1, flNone, OH_Accumulator }, /* $3a */ @@ -119,7 +119,7 @@ const OpcDesc OpcTable_M740[256] = { { "com", 2, flUseLabel, OH_Direct }, /* $44 */ { "eor", 2, flUseLabel, OH_Direct }, /* $45 */ { "lsr", 2, flUseLabel, OH_Direct }, /* $46 */ - { "bbs", 3, flUseLabel, OH_ZeroPageBit }, /* $47 */ + { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $47 */ { "pha", 1, flNone, OH_Implicit }, /* $48 */ { "eor", 2, flNone, OH_Immediate }, /* $49 */ { "lsr", 1, flNone, OH_Accumulator }, /* $4a */ @@ -135,7 +135,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $54 */ { "eor", 2, flUseLabel, OH_DirectX }, /* $55 */ { "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */ - { "bbc", 3, flUseLabel, OH_ZeroPageBit }, /* $57 */ + { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $57 */ { "cli", 1, flNone, OH_Implicit }, /* $58 */ { "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */ { "", 1, flIllegal, OH_Illegal }, /* $5a */ @@ -151,7 +151,7 @@ const OpcDesc OpcTable_M740[256] = { { "tst", 2, flUseLabel, OH_Direct }, /* $64 */ { "adc", 2, flUseLabel, OH_Direct }, /* $65 */ { "ror", 2, flUseLabel, OH_Direct }, /* $66 */ - { "bbs", 3, flUseLabel, OH_ZeroPageBit }, /* $67 */ + { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $67 */ { "pla", 1, flNone, OH_Implicit }, /* $68 */ { "adc", 2, flNone, OH_Immediate }, /* $69 */ { "ror", 1, flNone, OH_Accumulator }, /* $6a */ @@ -167,7 +167,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $74 */ { "adc", 2, flUseLabel, OH_DirectX }, /* $75 */ { "ror", 2, flUseLabel, OH_DirectX }, /* $76 */ - { "bbc", 3, flUseLabel, OH_ZeroPageBit }, /* $77 */ + { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $77 */ { "sei", 1, flNone, OH_Implicit }, /* $78 */ { "adc", 3, flUseLabel, OH_AbsoluteY }, /* $79 */ { "", 1, flIllegal, OH_Illegal }, /* $7a */ @@ -183,7 +183,7 @@ const OpcDesc OpcTable_M740[256] = { { "sty", 2, flUseLabel, OH_Direct }, /* $84 */ { "sta", 2, flUseLabel, OH_Direct }, /* $85 */ { "stx", 2, flUseLabel, OH_Direct }, /* $86 */ - { "bbs", 3, flUseLabel, OH_ZeroPageBit }, /* $87 */ + { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $87 */ { "dey", 1, flNone, OH_Implicit }, /* $88 */ { "", 1, flIllegal, OH_Illegal }, /* $89 */ { "txa", 1, flNone, OH_Implicit }, /* $8a */ @@ -199,7 +199,7 @@ const OpcDesc OpcTable_M740[256] = { { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */ { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */ { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */ - { "bbc", 3, flUseLabel, OH_ZeroPageBit }, /* $97 */ + { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $97 */ { "tya", 1, flNone, OH_Implicit }, /* $98 */ { "sta", 3, flUseLabel, OH_AbsoluteY }, /* $99 */ { "txs", 1, flNone, OH_Implicit }, /* $9a */ @@ -215,7 +215,7 @@ const OpcDesc OpcTable_M740[256] = { { "ldy", 2, flUseLabel, OH_Direct }, /* $a4 */ { "lda", 2, flUseLabel, OH_Direct }, /* $a5 */ { "ldx", 2, flUseLabel, OH_Direct }, /* $a6 */ - { "bbs", 3, flUseLabel, OH_ZeroPageBit }, /* $a7 */ + { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $a7 */ { "tay", 1, flNone, OH_Implicit }, /* $a8 */ { "lda", 2, flNone, OH_Immediate }, /* $a9 */ { "tax", 1, flNone, OH_Implicit }, /* $aa */ @@ -231,7 +231,7 @@ const OpcDesc OpcTable_M740[256] = { { "ldy", 2, flUseLabel, OH_DirectX }, /* $b4 */ { "lda", 2, flUseLabel, OH_DirectX }, /* $b5 */ { "ldx", 2, flUseLabel, OH_DirectY }, /* $b6 */ - { "bbc", 3, flUseLabel, OH_ZeroPageBit }, /* $b7 */ + { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $b7 */ { "clv", 1, flNone, OH_Implicit }, /* $b8 */ { "lda", 3, flUseLabel, OH_AbsoluteY }, /* $b9 */ { "tsx", 1, flNone, OH_Implicit }, /* $ba */ @@ -247,7 +247,7 @@ const OpcDesc OpcTable_M740[256] = { { "cpy", 2, flUseLabel, OH_Direct }, /* $c4 */ { "cmp", 2, flUseLabel, OH_Direct }, /* $c5 */ { "dec", 2, flUseLabel, OH_Direct }, /* $c6 */ - { "bbs", 3, flUseLabel, OH_ZeroPageBit }, /* $c7 */ + { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $c7 */ { "iny", 1, flNone, OH_Implicit }, /* $c8 */ { "cmp", 2, flNone, OH_Immediate }, /* $c9 */ { "dex", 1, flNone, OH_Implicit }, /* $ca */ @@ -263,7 +263,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $d4 */ { "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */ { "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */ - { "bbc", 3, flUseLabel, OH_ZeroPageBit }, /* $d7 */ + { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $d7 */ { "cld", 1, flNone, OH_Implicit }, /* $d8 */ { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */ { "", 1, flIllegal, OH_Illegal }, /* $da */ @@ -279,7 +279,7 @@ const OpcDesc OpcTable_M740[256] = { { "cpx", 2, flUseLabel, OH_Direct }, /* $e4 */ { "sbc", 2, flUseLabel, OH_Direct }, /* $e5 */ { "inc", 2, flUseLabel, OH_Direct }, /* $e6 */ - { "bbs", 3, flUseLabel, OH_ZeroPageBit }, /* $e7 */ + { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $e7 */ { "inx", 1, flNone, OH_Implicit }, /* $e8 */ { "sbc", 2, flNone, OH_Immediate }, /* $e9 */ { "nop", 1, flNone, OH_Implicit }, /* $ea */ @@ -295,7 +295,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $f4 */ { "sbc", 2, flUseLabel, OH_DirectX }, /* $f5 */ { "inc", 2, flUseLabel, OH_DirectX }, /* $f6 */ - { "bbc", 3, flUseLabel, OH_ZeroPageBit }, /* $f7 */ + { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $f7 */ { "sed", 1, flNone, OH_Implicit }, /* $f8 */ { "sbc", 3, flUseLabel, OH_AbsoluteY }, /* $f9 */ { "", 1, flIllegal, OH_Illegal }, /* $fa */ From 990d65e4e463d1dc95913bc7624369636861f7f5 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Thu, 12 Jun 2025 08:51:55 +0200 Subject: [PATCH 504/707] Apple2: Setup IRQ/RST vectors in LC if needed Programs running under DOS3.3 need to setup correct reset and IRQ vectors in the language card. --- asminc/apple2.inc | 2 ++ doc/apple2.sgml | 2 +- doc/apple2enh.sgml | 2 +- libsrc/apple2/crt0.s | 24 +++++++++++++++++++++++- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/asminc/apple2.inc b/asminc/apple2.inc index fb4a1b2f0..bde383882 100644 --- a/asminc/apple2.inc +++ b/asminc/apple2.inc @@ -24,6 +24,8 @@ DOSWARM := $03D0 ; DOS warmstart vector BRKVec := $03F0 ; Break vector SOFTEV := $03F2 ; Vector for warm start PWREDUP := $03F4 ; This must be = EOR #$A5 of SOFTEV+1 +ROM_RST := $FFFC ; 6502 reset vector +ROM_IRQ := $FFFE ; 6502 IRQ vector ;----------------------------------------------------------------------------- ; 80 column firmware diff --git a/doc/apple2.sgml b/doc/apple2.sgml index 719e799f4..ec9598d04 100644 --- a/doc/apple2.sgml +++ b/doc/apple2.sgml @@ -87,7 +87,7 @@ several useful settings: exit then a plain vanilla ProDOS 8 doesn't make use of the Language Card bank 2 at all. - <tag>LC address: $D000, LC size: $3000</tag> + <tag>LC address: $D000, LC size: $2FFC</tag> For plain vanilla DOS 3.3 which doesn't make use of the Language Card at all. </descrip><p> diff --git a/doc/apple2enh.sgml b/doc/apple2enh.sgml index 094ddd93e..1e94d3b60 100644 --- a/doc/apple2enh.sgml +++ b/doc/apple2enh.sgml @@ -88,7 +88,7 @@ several useful settings: exit then a plain vanilla ProDOS 8 doesn't make use of the Language Card bank 2 at all. - <tag>LC address: $D000, LC size: $3000</tag> + <tag>LC address: $D000, LC size: $2FFC</tag> For plain vanilla DOS 3.3 which doesn't make use of the Language Card at all. </descrip><p> diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index 628303687..ce14cc1e3 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -58,6 +58,7 @@ init: ldx #zpspace-1 ; Check for ProDOS. ldy $BF00 ; MLI call entry point cpy #$4C ; Is MLI present? (JMP opcode) + php ; Remember whether we're running ProDOS bne basic ; Check the ProDOS system bit map. @@ -99,7 +100,20 @@ basic: lda HIMEM bit $C081 bit $C081 - ; Set the source start address. + plp ; Are we running ProDOS? + beq :+ ; Yes, no need to patch vectors + + lda #<reset_6502 + ldx #>reset_6502 + sta ROM_RST + stx ROM_RST+1 + + lda #<irq_6502 + ldx #>irq_6502 + sta ROM_IRQ + stx ROM_IRQ+1 + +: ; Set the source start address. ; Aka __LC_LOAD__ iff segment LC exists. lda #<(__ONCE_LOAD__ + __ONCE_SIZE__) ldy #>(__ONCE_LOAD__ + __ONCE_SIZE__) @@ -144,6 +158,14 @@ quit: jsr $BF00 ; MLI call entry point .byte $65 ; Quit .word q_param +reset_6502: ; Used with DOS3.3 programs + bit $C082 ; Switch in ROM + jmp (ROM_RST) ; Jump to ROM's RESET vector + +irq_6502: ; Used with DOS3.3 programs + bit $C082 ; Switch in ROM + jmp (ROM_IRQ) ; Jump to ROM's IRQ/BRK vector + ; ------------------------------------------------------------------------ .rodata From 24b7d1fec754756a46943688aae37160494cf8f6 Mon Sep 17 00:00:00 2001 From: Oliver <ol.sc@web.de> Date: Sun, 15 Jun 2025 20:01:16 +0200 Subject: [PATCH 505/707] Make use of dynamic box drawing --- samples/diodemo.c | 1 + samples/hello.c | 1 + 2 files changed, 2 insertions(+) diff --git a/samples/diodemo.c b/samples/diodemo.c index 3e52f2fa9..46656246d 100644 --- a/samples/diodemo.c +++ b/samples/diodemo.c @@ -30,6 +30,7 @@ +#define DYN_BOX_DRAW #include <stddef.h> #include <stdlib.h> #include <limits.h> diff --git a/samples/hello.c b/samples/hello.c index 255dccd00..2eac0d8bb 100644 --- a/samples/hello.c +++ b/samples/hello.c @@ -7,6 +7,7 @@ +#define DYN_BOX_DRAW #include <stdlib.h> #include <string.h> #include <conio.h> From 7b12962eec45990b2e24b07f67d430d53c2325ab Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 16 Jun 2025 01:17:36 +0200 Subject: [PATCH 506/707] fix m740, survives disasm/asm roundtrip now, still needs some work though --- src/ca65/ea65.c | 4 +- src/ca65/instr.c | 137 +++++++++++++++++++++++++++------------------ src/ca65/instr.h | 3 + src/da65/handler.c | 33 +++++++++-- src/da65/handler.h | 2 +- src/da65/opcm740.c | 38 ++++++------- 6 files changed, 135 insertions(+), 82 deletions(-) diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c index 5bd2ba82b..965d15b2d 100644 --- a/src/ca65/ea65.c +++ b/src/ca65/ea65.c @@ -214,7 +214,9 @@ void GetEA (EffAddr* A) break; default: - Error ("Syntax error"); + /* FIXME: syntax error if not zp, ind */ + A->AddrModeSet = AM65_ZP_REL; + break; } diff --git a/src/ca65/instr.c b/src/ca65/instr.c index ddbd12125..1b33bcd7d 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -85,10 +85,10 @@ static void PutBlockTransfer (const InsDesc* Ins); static void PutBitBranch (const InsDesc* Ins); /* Handle 65C02 branch on bit condition */ -static void PutBitBranchm740 (const InsDesc* Ins); +static void PutBitBranch_m740 (const InsDesc* Ins); /* Handle m740 branch on bit condition */ -static void PutLDMm740 (const InsDesc* Ins); +static void PutLDM_m740 (const InsDesc* Ins); /* Handle m740 LDM instruction */ static void PutREP (const InsDesc* Ins); @@ -1056,41 +1056,49 @@ static const struct { /* Instruction table for the m740 CPU */ static const struct { unsigned Count; - InsDesc Ins[97]; + InsDesc Ins[106]; } InsTabm740 = { sizeof (InsTabm740.Ins) / sizeof (InsTabm740.Ins[0]), { /* BEGIN SORTED.SH */ - { "ADC", 0x080A26C, 0x60, 0, PutAll }, - { "AND", 0x080A26C, 0x20, 0, PutAll }, - { "ASL", 0x000006e, 0x02, 1, PutAll }, - { "BBR0", 0x0000006, 0x13, 10, PutBitBranchm740 }, - { "BBR1", 0x0000006, 0x33, 10, PutBitBranchm740 }, - { "BBR2", 0x0000006, 0x53, 10, PutBitBranchm740 }, - { "BBR3", 0x0000006, 0x73, 10, PutBitBranchm740 }, - { "BBR4", 0x0000006, 0x93, 10, PutBitBranchm740 }, - { "BBR5", 0x0000006, 0xb3, 10, PutBitBranchm740 }, - { "BBR6", 0x0000006, 0xd3, 10, PutBitBranchm740 }, - { "BBR7", 0x0000006, 0xf3, 10, PutBitBranchm740 }, - { "BBS0", 0x0000006, 0x03, 10, PutBitBranchm740 }, - { "BBS1", 0x0000006, 0x23, 10, PutBitBranchm740 }, - { "BBS2", 0x0000006, 0x43, 10, PutBitBranchm740 }, - { "BBS3", 0x0000006, 0x63, 10, PutBitBranchm740 }, - { "BBS4", 0x0000006, 0x83, 10, PutBitBranchm740 }, - { "BBS5", 0x0000006, 0xa3, 10, PutBitBranchm740 }, - { "BBS6", 0x0000006, 0xc3, 10, PutBitBranchm740 }, - { "BBS7", 0x0000006, 0xe3, 10, PutBitBranchm740 }, - { "BCC", 0x0020000, 0x90, 0, PutPCRel8 }, - { "BCS", 0x0020000, 0xb0, 0, PutPCRel8 }, - { "BEQ", 0x0020000, 0xf0, 0, PutPCRel8 }, - { "BIT", 0x000000C, 0x00, 2, PutAll }, - { "BMI", 0x0020000, 0x30, 0, PutPCRel8 }, - { "BNE", 0x0020000, 0xd0, 0, PutPCRel8 }, - { "BPL", 0x0020000, 0x10, 0, PutPCRel8 }, - { "BRA", 0x0020000, 0x80, 0, PutPCRel8 }, - { "BRK", 0x0000001, 0x00, 0, PutAll }, - { "BVC", 0x0020000, 0x50, 0, PutPCRel8 }, - { "BVS", 0x0020000, 0x70, 0, PutPCRel8 }, + { "ADC", 0x0080A26C, 0x60, 0, PutAll }, + { "AND", 0x0080A26C, 0x20, 0, PutAll }, + { "ASL", 0x0000006e, 0x02, 1, PutAll }, + { "BBC0", 0x10000002, 0x13, 10, PutBitBranch_m740 }, + { "BBC1", 0x10000002, 0x33, 10, PutBitBranch_m740 }, + { "BBC2", 0x10000002, 0x53, 10, PutBitBranch_m740 }, + { "BBC3", 0x10000002, 0x73, 10, PutBitBranch_m740 }, + { "BBC4", 0x10000002, 0x93, 10, PutBitBranch_m740 }, + { "BBC5", 0x10000002, 0xb3, 10, PutBitBranch_m740 }, + { "BBC6", 0x10000002, 0xd3, 10, PutBitBranch_m740 }, + { "BBC7", 0x10000002, 0xf3, 10, PutBitBranch_m740 }, + { "BBS0", 0x10000002, 0x03, 10, PutBitBranch_m740 }, + { "BBS1", 0x10000002, 0x23, 10, PutBitBranch_m740 }, + { "BBS2", 0x10000002, 0x43, 10, PutBitBranch_m740 }, + { "BBS3", 0x10000002, 0x63, 10, PutBitBranch_m740 }, + { "BBS4", 0x10000002, 0x83, 10, PutBitBranch_m740 }, + { "BBS5", 0x10000002, 0xa3, 10, PutBitBranch_m740 }, + { "BBS6", 0x10000002, 0xc3, 10, PutBitBranch_m740 }, + { "BBS7", 0x10000002, 0xe3, 10, PutBitBranch_m740 }, + { "BCC", 0x00020000, 0x90, 0, PutPCRel8 }, + { "BCS", 0x00020000, 0xb0, 0, PutPCRel8 }, + { "BEQ", 0x00020000, 0xf0, 0, PutPCRel8 }, + { "BIT", 0x0000000C, 0x00, 2, PutAll }, + { "BMI", 0x00020000, 0x30, 0, PutPCRel8 }, + { "BNE", 0x00020000, 0xd0, 0, PutPCRel8 }, + { "BPL", 0x00020000, 0x10, 0, PutPCRel8 }, + { "BRA", 0x00020000, 0x80, 0, PutPCRel8 }, + { "BRK", 0x00000001, 0x00, 0, PutAll }, + { "BVC", 0x00020000, 0x50, 0, PutPCRel8 }, + { "BVS", 0x00020000, 0x70, 0, PutPCRel8 }, + { "CLB0", 0x0000006, 0x1b, 10, PutAll }, + { "CLB1", 0x0000006, 0x3b, 10, PutAll }, + { "CLB2", 0x0000006, 0x5b, 10, PutAll }, + { "CLB3", 0x0000006, 0x7b, 10, PutAll }, + { "CLB4", 0x0000006, 0x9b, 10, PutAll }, + { "CLB5", 0x0000006, 0xbb, 10, PutAll }, + { "CLB6", 0x0000006, 0xdb, 10, PutAll }, + { "CLB7", 0x0000006, 0xfb, 10, PutAll }, { "CLC", 0x0000001, 0x18, 0, PutAll }, { "CLD", 0x0000001, 0xd8, 0, PutAll }, { "CLI", 0x0000001, 0x58, 0, PutAll }, @@ -1111,7 +1119,7 @@ static const struct { { "JMP", 0x0000C08, 0x00, 12, PutAll }, { "JSR", 0x0080808, 0x00, 13, PutAll }, { "LDA", 0x080A26C, 0xa0, 0, PutAll }, - { "LDM", 0x0000004, 0x3c, 6, PutLDMm740 }, + { "LDM", 0x10000000, 0x3c, 0, PutLDM_m740 }, { "LDX", 0x080030C, 0xa2, 1, PutAll }, { "LDY", 0x080006C, 0xa0, 1, PutAll }, { "LSR", 0x000006F, 0x42, 1, PutAll }, @@ -1135,25 +1143,26 @@ static const struct { { "RTI", 0x0000001, 0x40, 0, PutAll }, { "RTS", 0x0000001, 0x60, 0, PutAll }, { "SBC", 0x080A26C, 0xe0, 0, PutAll }, + { "SEB0", 0x0000006, 0x0b, 10, PutAll }, + { "SEB1", 0x0000006, 0x2b, 10, PutAll }, + { "SEB2", 0x0000006, 0x4b, 10, PutAll }, + { "SEB3", 0x0000006, 0x6b, 10, PutAll }, + { "SEB4", 0x0000006, 0x8b, 10, PutAll }, + { "SEB5", 0x0000006, 0xab, 10, PutAll }, + { "SEB6", 0x0000006, 0xcb, 10, PutAll }, + { "SEB7", 0x0000006, 0xeb, 10, PutAll }, { "SEC", 0x0000001, 0x38, 0, PutAll }, { "SED", 0x0000001, 0xf8, 0, PutAll }, { "SEI", 0x0000001, 0x78, 0, PutAll }, { "SET", 0x0000001, 0x32, 0, PutAll }, { "SLW", 0x0000001, 0xC2, 0, PutAll }, - { "SMB0", 0x0000006, 0x0b, 10, PutAll }, - { "SMB1", 0x0000006, 0x2b, 10, PutAll }, - { "SMB2", 0x0000006, 0x4b, 10, PutAll }, - { "SMB3", 0x0000006, 0x6b, 10, PutAll }, - { "SMB4", 0x0000006, 0x8b, 10, PutAll }, - { "SMB5", 0x0000006, 0xab, 10, PutAll }, - { "SMB6", 0x0000006, 0xcb, 10, PutAll }, - { "SMB7", 0x0000006, 0xeb, 10, PutAll }, { "STA", 0x000A26C, 0x80, 0, PutAll }, { "STP", 0x0000001, 0x42, 0, PutAll }, { "STX", 0x000010c, 0x82, 1, PutAll }, { "STY", 0x000002c, 0x80, 1, PutAll }, { "TAX", 0x0000001, 0xaa, 0, PutAll }, { "TAY", 0x0000001, 0xa8, 0, PutAll }, + { "TST", 0x0000004, 0x64, 0, PutAll }, { "TSX", 0x0000001, 0xba, 0, PutAll }, { "TXA", 0x0000001, 0x8a, 0, PutAll }, { "TXS", 0x0000001, 0x9a, 0, PutAll }, @@ -1486,13 +1495,21 @@ static void EmitCode (EffAddr* A) } -static void PutLDMm740 (const InsDesc* Ins) +static void PutLDM_m740 (const InsDesc* Ins) { - + EffAddr A; + /* Evaluate the addressing mode */ + if (EvalEA (Ins, &A) == 0) { + /* An error occurred */ + return; + } Emit0 (Ins->BaseCode); - EmitWord (Expression ()); + EmitByte (A.Expr); + Consume (TOK_HASH, "'#' expected"); + EmitByte (Expression ()); } + static long PutImmed8 (const InsDesc* Ins) /* Parse and emit an immediate 8 bit instruction. Return the value of the ** operand if it's available and const. @@ -1612,21 +1629,29 @@ static void PutBitBranch (const InsDesc* Ins) EmitSigned (GenBranchExpr (1), 1); } -static void PutBitBranchm740 (const InsDesc* Ins) -/* Handle 65C02 branch on bit condition */ +static void PutBitBranch_m740 (const InsDesc* Ins) +/* Handle m740 branch on bit condition */ { EffAddr A; - /* HACK: hardcoded for zp addressing mode, this doesn't work all the time */ - A.AddrMode = 2; - - A.Opcode = Ins->BaseCode | EATab[Ins->ExtCode][A.AddrMode]; /* Evaluate the addressing mode used */ - /* No error, output code */ - Emit0 (A.Opcode); - EmitByte (Expression ()); - ConsumeComma (); - EmitSigned (GenBranchExpr (1), 1); + GetEA(&A); + + A.AddrMode = 2; /* HACK */ + A.Opcode = Ins->BaseCode; + + if (A.AddrModeSet == 0x00000002) { + /* Accu */ + Emit0 (A.Opcode); + ConsumeComma (); + EmitSigned (GenBranchExpr (1), 1); + } else if (A.AddrModeSet == 0x10000000) { + A.Opcode += 0x04; + /* Zeropage */ + Emit0 (A.Opcode); + EmitByte (A.Expr); + EmitSigned (GenBranchExpr (1), 1); + } } diff --git a/src/ca65/instr.h b/src/ca65/instr.h index 823aa5659..fff5a0f34 100644 --- a/src/ca65/instr.h +++ b/src/ca65/instr.h @@ -86,6 +86,9 @@ #define AM65_BLOCKXFER 0x02000000UL /* -- */ #define AM65_ABS_IND_LONG 0x04000000UL /* -- */ #define AM65_IMM_IMPLICIT_WORD 0x08000000UL /* PHW #$1234 (4510 only) */ +#define AM65_ZP_REL 0x10000000UL /* ZP, REL (m740) */ + + /* Bitmask for all ZP operations that have correspondent ABS ops */ /* $8524 */ diff --git a/src/da65/handler.c b/src/da65/handler.c index 3e448635d..674769369 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -92,6 +92,29 @@ static void OneLine (const OpcDesc* D, const char* Arg, ...) LineFeed (); } +static void OneLineNoIndent (const OpcDesc* D, const char* Arg, ...) attribute ((format(printf, 2, 3))); +static void OneLineNoIndent (const OpcDesc* D, const char* Arg, ...) +/* Output one line with the given mnemonic and argument */ +{ + char Buf [256]; + va_list ap; + + /* Mnemonic */ + Mnemonic (D->Mnemo); + + /* Argument */ + va_start (ap, Arg); + xvsprintf (Buf, sizeof (Buf), Arg, ap); + va_end (ap); + + Output ("%s", Buf); + + /* Add the code stuff as comment */ + LineComment (PC, D->Size); + + /* End the line */ + LineFeed (); +} static const char* GetAbsOverride (unsigned Flags, unsigned Addr) @@ -531,7 +554,7 @@ void OH_BitBranch (const OpcDesc* D) xfree (BranchLabel); } -void OH_BitBranchm740 (const OpcDesc* D) +void OH_BitBranch_m740 (const OpcDesc* D) { unsigned Bit = GetCodeByte (PC) >> 5; unsigned Addr = GetCodeByte (PC+1); @@ -545,7 +568,7 @@ void OH_BitBranchm740 (const OpcDesc* D) GenerateLabel (flLabel, BranchAddr); /* Output the line */ - OneLine (D, "%01X,%s,%s", Bit, GetAddrArg (D->Flags, Addr), GetAddrArg (flLabel, BranchAddr)); + OneLineNoIndent (D, "%01X %s,%s", Bit, GetAddrArg (D->Flags, Addr), GetAddrArg (flLabel, BranchAddr)); } void OH_ImmediateDirect (const OpcDesc* D) @@ -743,7 +766,7 @@ void OH_ZeroPageBit (const OpcDesc* D) GenerateLabel (D->Flags, Addr); /* Output the line */ - OneLine (D, "%01X,%s", Bit, GetAddrArg (D->Flags, Addr)); + OneLineNoIndent (D, "%01X %s", Bit, GetAddrArg (D->Flags, Addr)); } @@ -753,7 +776,7 @@ void OH_AccumulatorBit (const OpcDesc* D) unsigned Bit = GetCodeByte (PC) >> 5; /* Output the line */ - OneLine (D, "%01X,a", Bit); + OneLineNoIndent (D, "%01X a", Bit); } @@ -770,7 +793,7 @@ void OH_AccumulatorBitBranch (const OpcDesc* D) GenerateLabel (flLabel, BranchAddr); /* Output the line */ - OneLine (D, "%01X,a,%s", Bit, GetAddrArg (flLabel, BranchAddr)); + OneLineNoIndent (D, "%01X a, %s", Bit, GetAddrArg (flLabel, BranchAddr)); } diff --git a/src/da65/handler.h b/src/da65/handler.h index 7688ff1c8..fb0c40200 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -78,7 +78,7 @@ void OH_DirectXIndirect (const OpcDesc*); void OH_AbsoluteIndirect (const OpcDesc*); void OH_BitBranch (const OpcDesc*); -void OH_BitBranchm740 (const OpcDesc*); +void OH_BitBranch_m740 (const OpcDesc*); void OH_ImmediateDirect (const OpcDesc*); void OH_ImmediateDirectX (const OpcDesc*); diff --git a/src/da65/opcm740.c b/src/da65/opcm740.c index 791f7f7a8..e4bd3370f 100644 --- a/src/da65/opcm740.c +++ b/src/da65/opcm740.c @@ -55,7 +55,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $04 */ { "ora", 2, flUseLabel, OH_Direct }, /* $05 */ { "asl", 2, flUseLabel, OH_Direct }, /* $06 */ - { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $07 */ + { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $07 */ { "php", 1, flNone, OH_Implicit }, /* $08 */ { "ora", 2, flNone, OH_Immediate }, /* $09 */ { "asl", 1, flNone, OH_Accumulator }, /* $0a */ @@ -71,7 +71,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $14 */ { "ora", 2, flUseLabel, OH_DirectX }, /* $15 */ { "asl", 2, flUseLabel, OH_DirectX }, /* $16 */ - { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $17 */ + { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $17 */ { "clc", 1, flNone, OH_Implicit }, /* $18 */ { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */ { "dec", 1, flNone, OH_Accumulator }, /* $1a */ @@ -87,7 +87,7 @@ const OpcDesc OpcTable_M740[256] = { { "bit", 2, flUseLabel, OH_Direct }, /* $24 */ { "and", 2, flUseLabel, OH_Direct }, /* $25 */ { "rol", 2, flUseLabel, OH_Direct }, /* $26 */ - { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $27 */ + { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $27 */ { "plp", 1, flNone, OH_Implicit }, /* $28 */ { "and", 2, flNone, OH_Immediate }, /* $29 */ { "rol", 1, flNone, OH_Accumulator }, /* $2a */ @@ -103,7 +103,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $34 */ { "and", 2, flUseLabel, OH_DirectX }, /* $35 */ { "rol", 2, flUseLabel, OH_DirectX }, /* $36 */ - { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $37 */ + { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $37 */ { "sec", 1, flNone, OH_Implicit }, /* $38 */ { "and", 3, flUseLabel, OH_AbsoluteY }, /* $39 */ { "inc", 1, flNone, OH_Accumulator }, /* $3a */ @@ -119,7 +119,7 @@ const OpcDesc OpcTable_M740[256] = { { "com", 2, flUseLabel, OH_Direct }, /* $44 */ { "eor", 2, flUseLabel, OH_Direct }, /* $45 */ { "lsr", 2, flUseLabel, OH_Direct }, /* $46 */ - { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $47 */ + { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $47 */ { "pha", 1, flNone, OH_Implicit }, /* $48 */ { "eor", 2, flNone, OH_Immediate }, /* $49 */ { "lsr", 1, flNone, OH_Accumulator }, /* $4a */ @@ -135,7 +135,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $54 */ { "eor", 2, flUseLabel, OH_DirectX }, /* $55 */ { "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */ - { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $57 */ + { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $57 */ { "cli", 1, flNone, OH_Implicit }, /* $58 */ { "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */ { "", 1, flIllegal, OH_Illegal }, /* $5a */ @@ -146,12 +146,12 @@ const OpcDesc OpcTable_M740[256] = { { "clb", 2, flUseLabel, OH_ZeroPageBit }, /* $5f */ { "rts", 1, flNone, OH_Rts }, /* $60 */ { "adc", 2, flUseLabel, OH_DirectXIndirect }, /* $61 */ - { "mul", 2, flUseLabel, OH_DirectX }, /* $62 */ + { "", 1, flIllegal, OH_Illegal }, /* $62 */ { "bbs", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $63 */ { "tst", 2, flUseLabel, OH_Direct }, /* $64 */ { "adc", 2, flUseLabel, OH_Direct }, /* $65 */ { "ror", 2, flUseLabel, OH_Direct }, /* $66 */ - { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $67 */ + { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $67 */ { "pla", 1, flNone, OH_Implicit }, /* $68 */ { "adc", 2, flNone, OH_Immediate }, /* $69 */ { "ror", 1, flNone, OH_Accumulator }, /* $6a */ @@ -167,7 +167,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $74 */ { "adc", 2, flUseLabel, OH_DirectX }, /* $75 */ { "ror", 2, flUseLabel, OH_DirectX }, /* $76 */ - { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $77 */ + { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $77 */ { "sei", 1, flNone, OH_Implicit }, /* $78 */ { "adc", 3, flUseLabel, OH_AbsoluteY }, /* $79 */ { "", 1, flIllegal, OH_Illegal }, /* $7a */ @@ -183,7 +183,7 @@ const OpcDesc OpcTable_M740[256] = { { "sty", 2, flUseLabel, OH_Direct }, /* $84 */ { "sta", 2, flUseLabel, OH_Direct }, /* $85 */ { "stx", 2, flUseLabel, OH_Direct }, /* $86 */ - { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $87 */ + { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $87 */ { "dey", 1, flNone, OH_Implicit }, /* $88 */ { "", 1, flIllegal, OH_Illegal }, /* $89 */ { "txa", 1, flNone, OH_Implicit }, /* $8a */ @@ -199,7 +199,7 @@ const OpcDesc OpcTable_M740[256] = { { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */ { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */ { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */ - { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $97 */ + { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $97 */ { "tya", 1, flNone, OH_Implicit }, /* $98 */ { "sta", 3, flUseLabel, OH_AbsoluteY }, /* $99 */ { "txs", 1, flNone, OH_Implicit }, /* $9a */ @@ -215,7 +215,7 @@ const OpcDesc OpcTable_M740[256] = { { "ldy", 2, flUseLabel, OH_Direct }, /* $a4 */ { "lda", 2, flUseLabel, OH_Direct }, /* $a5 */ { "ldx", 2, flUseLabel, OH_Direct }, /* $a6 */ - { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $a7 */ + { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $a7 */ { "tay", 1, flNone, OH_Implicit }, /* $a8 */ { "lda", 2, flNone, OH_Immediate }, /* $a9 */ { "tax", 1, flNone, OH_Implicit }, /* $aa */ @@ -231,7 +231,7 @@ const OpcDesc OpcTable_M740[256] = { { "ldy", 2, flUseLabel, OH_DirectX }, /* $b4 */ { "lda", 2, flUseLabel, OH_DirectX }, /* $b5 */ { "ldx", 2, flUseLabel, OH_DirectY }, /* $b6 */ - { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $b7 */ + { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $b7 */ { "clv", 1, flNone, OH_Implicit }, /* $b8 */ { "lda", 3, flUseLabel, OH_AbsoluteY }, /* $b9 */ { "tsx", 1, flNone, OH_Implicit }, /* $ba */ @@ -242,12 +242,12 @@ const OpcDesc OpcTable_M740[256] = { { "clb", 2, flUseLabel, OH_ZeroPageBit }, /* $bf */ { "cpy", 2, flNone, OH_Immediate }, /* $c0 */ { "cmp", 2, flUseLabel, OH_DirectXIndirect }, /* $c1 */ - { "wit", 1, flNone, OH_Implicit, }, /* $c2 */ + { "slw", 1, flNone, OH_Implicit, }, /* $c2 */ { "bbs", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $c3 */ { "cpy", 2, flUseLabel, OH_Direct }, /* $c4 */ { "cmp", 2, flUseLabel, OH_Direct }, /* $c5 */ { "dec", 2, flUseLabel, OH_Direct }, /* $c6 */ - { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $c7 */ + { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $c7 */ { "iny", 1, flNone, OH_Implicit }, /* $c8 */ { "cmp", 2, flNone, OH_Immediate }, /* $c9 */ { "dex", 1, flNone, OH_Implicit }, /* $ca */ @@ -263,7 +263,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $d4 */ { "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */ { "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */ - { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $d7 */ + { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $d7 */ { "cld", 1, flNone, OH_Implicit }, /* $d8 */ { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */ { "", 1, flIllegal, OH_Illegal }, /* $da */ @@ -274,12 +274,12 @@ const OpcDesc OpcTable_M740[256] = { { "clb", 2, flUseLabel, OH_ZeroPageBit }, /* $df */ { "cpx", 2, flNone, OH_Immediate }, /* $e0 */ { "sbc", 2, flUseLabel, OH_DirectXIndirect }, /* $e1 */ - { "div", 2, flUseLabel, OH_DirectX }, /* $e2 */ + { "fst", 1, flNone, OH_Implicit }, /* $e2 */ { "bbs", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $e3 */ { "cpx", 2, flUseLabel, OH_Direct }, /* $e4 */ { "sbc", 2, flUseLabel, OH_Direct }, /* $e5 */ { "inc", 2, flUseLabel, OH_Direct }, /* $e6 */ - { "bbs", 3, flUseLabel, OH_BitBranchm740 }, /* $e7 */ + { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $e7 */ { "inx", 1, flNone, OH_Implicit }, /* $e8 */ { "sbc", 2, flNone, OH_Immediate }, /* $e9 */ { "nop", 1, flNone, OH_Implicit }, /* $ea */ @@ -295,7 +295,7 @@ const OpcDesc OpcTable_M740[256] = { { "", 1, flIllegal, OH_Illegal }, /* $f4 */ { "sbc", 2, flUseLabel, OH_DirectX }, /* $f5 */ { "inc", 2, flUseLabel, OH_DirectX }, /* $f6 */ - { "bbc", 3, flUseLabel, OH_BitBranchm740 }, /* $f7 */ + { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $f7 */ { "sed", 1, flNone, OH_Implicit }, /* $f8 */ { "sbc", 3, flUseLabel, OH_AbsoluteY }, /* $f9 */ { "", 1, flIllegal, OH_Illegal }, /* $fa */ From ef33c4b71ddf2bae73566fce92fca1c667070c53 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 16 Jun 2025 01:35:23 +0200 Subject: [PATCH 507/707] fix script to deal with more than 9 tables --- .github/checks/sorted.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/checks/sorted.sh b/.github/checks/sorted.sh index 0a4a90db7..4f53b0484 100755 --- a/.github/checks/sorted.sh +++ b/.github/checks/sorted.sh @@ -13,8 +13,8 @@ function checkarray_quoted_name START="\\/\\* BEGIN SORTED.SH \\*\\/" END="\\/\\* END SORTED.SH \\*\\/" - awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \ - sed -e 's:\(.*\) ##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \ + sed -e 's:\(.*\)##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then echo "error: "$1" table is empty" From c0a0ba1483f92199dfa6e01b99406a1f13add588 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Mon, 16 Jun 2025 02:46:10 +0000 Subject: [PATCH 508/707] added reporting of fatal/error/warning/note location generation with "-d" --- src/cc65/error.c | 76 +++++++++++++++++++++++++++++++++++++++++------- src/cc65/error.h | 33 ++++++++++++++------- 2 files changed, 87 insertions(+), 22 deletions(-) diff --git a/src/cc65/error.c b/src/cc65/error.c index db0debf8c..90577c0ad 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -39,6 +39,7 @@ /* common */ #include "coll.h" +#include "debugflag.h" #include "print.h" #include "strbuf.h" @@ -183,11 +184,15 @@ static unsigned GetDiagnosticLineNum (void) -void Fatal (const char* Format, ...) +void _Fatal (const char *file, int line, const char* Format, ...) /* Print a message about a fatal error and die */ { va_list ap; + if (Debug) { + fprintf(stderr, "[%s:%d] ", file, line); + } + fprintf (stderr, "%s:%u: Fatal: ", GetDiagnosticFileName (), GetDiagnosticLineNum ()); va_start (ap, Format); @@ -203,11 +208,15 @@ void Fatal (const char* Format, ...) -void Internal (const char* Format, ...) +void _Internal (const char *file, int line, const char* Format, ...) /* Print a message about an internal compiler error and die */ { va_list ap; + if (Debug) { + fprintf(stderr, "[%s:%d] ", file, line); + } + fprintf (stderr, "%s:%u: Internal compiler error:\n", GetDiagnosticFileName (), GetDiagnosticLineNum ()); @@ -270,10 +279,15 @@ static void IntError (errcat_t EC, LineInfo* LI, const char* Msg, va_list ap) -void LIError (errcat_t EC, LineInfo* LI, const char* Format, ...) +void _LIError (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) /* Print an error message with the line info given explicitly */ { va_list ap; + + if (Debug) { + fprintf(stderr, "[%s:%d] ", file, line); + } + va_start (ap, Format); IntError (EC, LI, Format, ap); va_end (ap); @@ -281,10 +295,15 @@ void LIError (errcat_t EC, LineInfo* LI, const char* Format, ...) -void Error (const char* Format, ...) +void _Error (const char *file, int line, const char* Format, ...) /* Print an error message */ { va_list ap; + + if (Debug) { + fprintf(stderr, "[%s:%d] ", file, line); + } + va_start (ap, Format); IntError (EC_PARSER, GetDiagnosticLI (), Format, ap); va_end (ap); @@ -292,10 +311,15 @@ void Error (const char* Format, ...) -void PPError (const char* Format, ...) +void _PPError (const char *file, int line, const char* Format, ...) /* Print an error message. For use within the preprocessor */ { va_list ap; + + if (Debug) { + fprintf(stderr, "[%s:%d] ", file, line); + } + va_start (ap, Format); IntError (EC_PP, GetCurLineInfo (), Format, ap); va_end (ap); @@ -346,10 +370,15 @@ static void IntWarning (errcat_t EC, LineInfo* LI, const char* Msg, va_list ap) -void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...) +void _LIWarning (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) /* Print a warning message with the line info given explicitly */ { va_list ap; + + if (Debug) { + fprintf(stderr, "[%s:%d] ", file, line); + } + va_start (ap, Format); IntWarning (EC, LI, Format, ap); va_end (ap); @@ -357,10 +386,15 @@ void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...) -void Warning (const char* Format, ...) +void _Warning (const char *file, int line, const char* Format, ...) /* Print a warning message */ { va_list ap; + + if (Debug) { + fprintf(stderr, "[%s:%d] ", file, line); + } + va_start (ap, Format); IntWarning (EC_PARSER, GetDiagnosticLI (), Format, ap); va_end (ap); @@ -368,10 +402,15 @@ void Warning (const char* Format, ...) -void PPWarning (const char* Format, ...) +void _PPWarning (const char *file, int line, const char* Format, ...) /* Print a warning message. For use within the preprocessor */ { va_list ap; + + if (Debug) { + fprintf(stderr, "[%s:%d] ", file, line); + } + va_start (ap, Format); IntWarning (EC_PP, GetCurLineInfo (), Format, ap); va_end (ap); @@ -436,10 +475,15 @@ static void IntNote (const LineInfo* LI, const char* Msg, va_list ap) -void LINote (const LineInfo* LI, const char* Format, ...) +void _LINote (const char *file, int line, const LineInfo* LI, const char* Format, ...) /* Print a note message with the line info given explicitly */ { va_list ap; + + if (Debug) { + fprintf(stderr, "[%s:%d] ", file, line); + } + va_start (ap, Format); IntNote (LI, Format, ap); va_end (ap); @@ -447,10 +491,15 @@ void LINote (const LineInfo* LI, const char* Format, ...) -void Note (const char* Format, ...) +void _Note (const char *file, int line, const char* Format, ...) /* Print a note message */ { va_list ap; + + if (Debug) { + fprintf(stderr, "[%s:%d] ", file, line); + } + va_start (ap, Format); IntNote (GetDiagnosticLI (), Format, ap); va_end (ap); @@ -458,10 +507,15 @@ void Note (const char* Format, ...) -void PPNote (const char* Format, ...) +void _PPNote (const char *file, int line, const char* Format, ...) /* Print a note message. For use within the preprocessor */ { va_list ap; + + if (Debug) { + fprintf(stderr, "[%s:%d] ", file, line); + } + va_start (ap, Format); IntNote (GetDiagnosticLI (), Format, ap); va_end (ap); diff --git a/src/cc65/error.h b/src/cc65/error.h index b3cdc49ab..63158b3bd 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -103,28 +103,36 @@ struct StrBuf; void PrintFileInclusionInfo (const LineInfo* LI); /* Print hierarchy of file inclusion */ -void Fatal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2))); +void _Fatal (const char *file, int line, const char* Format, ...) attribute ((noreturn, format (printf, 3, 4))); +#define Fatal(...) _Fatal(__FILE__, __LINE__, __VA_ARGS__) /* Print a message about a fatal error and die */ -void Internal (const char* Format, ...) attribute ((noreturn, format (printf, 1, 2))); +void _Internal (const char *file, int line, const char* Format, ...) attribute ((noreturn, format (printf, 3, 4))); +#define Internal(...) _Internal(__FILE__, __LINE__, __VA_ARGS__) /* Print a message about an internal compiler error and die */ -void Error (const char* Format, ...) attribute ((format (printf, 1, 2))); +void _Error (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define Error(...) _Error(__FILE__, __LINE__, __VA_ARGS__) /* Print an error message */ -void LIError (errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4))); +void _LIError (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 5, 6))); +#define LIError(...) _LIError(__FILE__, __LINE__, __VA_ARGS__) /* Print an error message with the line info given explicitly */ -void PPError (const char* Format, ...) attribute ((format (printf, 1, 2))); +void _PPError (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define PPError(...) _PPError(__FILE__, __LINE__, __VA_ARGS__) /* Print an error message. For use within the preprocessor */ -void Warning (const char* Format, ...) attribute ((format (printf, 1, 2))); +void _Warning (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define Warning(...) _Warning(__FILE__, __LINE__, __VA_ARGS__) /* Print a warning message */ -void LIWarning (errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 3, 4))); +void _LIWarning (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 5, 6))); +#define LIWarning(...) _LIWarning(__FILE__, __LINE__, __VA_ARGS__) /* Print a warning message with the line info given explicitly */ -void PPWarning (const char* Format, ...) attribute ((format (printf, 1, 2))); +void _PPWarning (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define PPWarning(...) _PPWarning(__FILE__, __LINE__, __VA_ARGS__) /* Print a warning message. For use within the preprocessor */ void UnreachableCodeWarning (void); @@ -140,13 +148,16 @@ IntStack* FindWarning (const char* Name); void ListWarnings (FILE* F); /* Print a list of warning types/names to the given file */ -void Note (const char* Format, ...) attribute ((format (printf, 1, 2))); +void _Note (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define Note(...) _Note(__FILE__, __LINE__, __VA_ARGS__) /* Print a note message */ -void LINote (const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 2, 3))); +void _LINote (const char *file, int line, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 4, 5))); +#define LINote(...) _LINote(__FILE__, __LINE__, __VA_ARGS__) /* Print a note message with the line info given explicitly */ -void PPNote (const char* Format, ...) attribute ((format (printf, 1, 2))); +void _PPNote (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define PPNote(...) _PPNote(__FILE__, __LINE__, __VA_ARGS__) /* Print a note message. For use within the preprocessor */ unsigned GetTotalErrors (void); From adc9ddc2807597290ab9e0e36951cb9cc360b3e6 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Mon, 16 Jun 2025 11:16:13 +0200 Subject: [PATCH 509/707] Change the available options to -dM and -dP. The former prints user macros, the latter predefined macros. Can be combined by using -dMP or -dPM. --- doc/cc65.sgml | 31 +++++++++++++++-------------- src/cc65/compile.c | 7 ++----- src/cc65/global.c | 5 ++--- src/cc65/global.h | 5 ++--- src/cc65/macrotab.c | 27 +++++++++++-------------- src/cc65/macrotab.h | 7 ++----- src/cc65/main.c | 48 +++++++++++++++++++++------------------------ 7 files changed, 57 insertions(+), 73 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index a78f1a00a..383a6dd6a 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -63,9 +63,8 @@ Short options: -V Print the compiler version number -W [-+]warning[,...] Control warnings ('-' disables, '+' enables) -d Debug mode - -dD Output user defined macros (needs -E) - -dM Output all macro definitions (needs -E) - -dN Output user defined macro names (needs -E) + -dM Output all user macros (needs -E) + -dP Output all predefined macros (needs -E) -g Add debug info to object file -h Help (this text) -j Default characters are signed @@ -202,24 +201,26 @@ Here is a description of all the command line options: Enables debug mode, for debugging the behavior of cc65. - <label id="option-dD"> - <tag><tt>-dD</tt></tag> - - Like <tt/<ref id="option-dM" name="-dM">/ but does not include the predefined - macros. - <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 during execution of the preprocessor, including predefined macros. + defined by the compiler itself. This does not include any user defined macros. - - <tag><tt>-dN</tt></tag> - - Like <tt/<ref id="option-dD" name="-dD">/ but will only output the macro names, - not their definitions. + Note: Can be combined with <tt/<ref id="option-dM" name="-dM">/ by using + <tt/-dMP/. <tag><tt>--debug-tables name</tt></tag> diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 5b9ef1551..9083891aa 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -497,15 +497,12 @@ void Compile (const char* FileName) { /* Nothing */ } /* Output macros if requested by the user */ - if (DumpAllMacrosFull) { - OutputAllMacrosFull (); + if (DumpPredefMacros) { + OutputPredefMacros (); } if (DumpUserMacros) { OutputUserMacros (); } - if (DumpUserMacrosFull) { - OutputUserMacrosFull (); - } /* Close the output file */ CloseOutputFile (); diff --git a/src/cc65/global.c b/src/cc65/global.c index 6fcc5d9d7..64278df77 100644 --- a/src/cc65/global.c +++ b/src/cc65/global.c @@ -47,9 +47,8 @@ unsigned char AddSource = 0; /* Add source lines as comments */ unsigned char AllowNewComments = 0; /* Allow new style comments in C89 mode */ unsigned char AutoCDecl = 0; /* Make functions default to __cdecl__ */ unsigned char DebugInfo = 0; /* Add debug info to the obj */ -unsigned char DumpAllMacrosFull = 0; /* Output all macro defs */ -unsigned char DumpUserMacros = 0; /* Output user macro names */ -unsigned char DumpUserMacrosFull= 0; /* Output user macro defs */ +unsigned char DumpPredefMacros = 0; /* Output predefined macros */ +unsigned char DumpUserMacros = 0; /* Output user macros */ unsigned char PreprocessOnly = 0; /* Just preprocess the input */ unsigned char DebugOptOutput = 0; /* Output debug stuff */ unsigned RegisterSpace = 6; /* Space available for register vars */ diff --git a/src/cc65/global.h b/src/cc65/global.h index d475c73e5..c781f6de4 100644 --- a/src/cc65/global.h +++ b/src/cc65/global.h @@ -55,9 +55,8 @@ extern unsigned char AddSource; /* Add source lines as comments extern unsigned char AllowNewComments; /* Allow new style comments in C89 mode */ extern unsigned char AutoCDecl; /* Make functions default to __cdecl__ */ extern unsigned char DebugInfo; /* Add debug info to the obj */ -extern unsigned char DumpAllMacrosFull; /* Output all macro defs */ -extern unsigned char DumpUserMacros; /* Output user macro names */ -extern unsigned char DumpUserMacrosFull; /* Output user macro defs */ +extern unsigned char DumpPredefMacros; /* Output predefined macros */ +extern unsigned char DumpUserMacros; /* Output user macros */ extern unsigned char PreprocessOnly; /* Just preprocess the input */ extern unsigned char DebugOptOutput; /* Output debug stuff */ extern unsigned RegisterSpace; /* Space available for register vars */ diff --git a/src/cc65/macrotab.c b/src/cc65/macrotab.c index 41345db8a..2817403c1 100644 --- a/src/cc65/macrotab.c +++ b/src/cc65/macrotab.c @@ -62,8 +62,8 @@ static Macro* MacroTab[MACRO_TAB_SIZE]; static Macro* UndefinedMacrosListHead; /* Some defines for better readability when calling OutputMacros() */ -#define ALL_MACROS 0 -#define USER_MACROS 1 +#define USER_MACROS 0 +#define PREDEF_MACROS 1 #define NAME_ONLY 0 #define FULL_DEFINITION 1 @@ -107,14 +107,17 @@ static void OutputMacro (const Macro* M, int Full) -static void OutputMacros (int UserOnly, int Full) -/* Output macros to the output file depending on the flags given */ +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 (!UserOnly || !M->Predefined) { + if ((Predefined != 0) == (M->Predefined != 0)) { OutputMacro (M, Full); } M = M->Next; @@ -416,23 +419,15 @@ void PrintMacroStats (FILE* F) -void OutputAllMacrosFull (void) -/* Output all macros to the output file */ +void OutputPredefMacros (void) +/* Output all predefined macros to the output file */ { - OutputMacros (ALL_MACROS, FULL_DEFINITION); + OutputMacros (PREDEF_MACROS, FULL_DEFINITION); } void OutputUserMacros (void) -/* Output the names of all user defined macros to the output file */ -{ - OutputMacros (USER_MACROS, NAME_ONLY); -} - - - -void OutputUserMacrosFull (void) /* Output all user defined macros to the output file */ { OutputMacros (USER_MACROS, FULL_DEFINITION); diff --git a/src/cc65/macrotab.h b/src/cc65/macrotab.h index 8d2a04755..00fb1d55a 100644 --- a/src/cc65/macrotab.h +++ b/src/cc65/macrotab.h @@ -133,13 +133,10 @@ int MacroCmp (const Macro* M1, const Macro* M2); void PrintMacroStats (FILE* F); /* Print macro statistics to the given text file. */ -void OutputAllMacrosFull (void); -/* Output all macros to the output file */ +void OutputPredefMacros (void); +/* Output all predefined macros to the output file */ void OutputUserMacros (void); -/* Output the names of all user defined macros to the output file */ - -void OutputUserMacrosFull (void); /* Output all user defined macros to the output file */ diff --git a/src/cc65/main.c b/src/cc65/main.c index 4ff17ada9..0500a52f3 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -93,9 +93,8 @@ static void Usage (void) " -V\t\t\t\tPrint the compiler version number\n" " -W [-+]warning[,...]\t\tControl warnings ('-' disables, '+' enables)\n" " -d\t\t\t\tDebug mode\n" - " -dD\t\t\t\tOutput user defined macros (needs -E)\n" - " -dM\t\t\t\tOutput all macro definitions (needs -E)\n" - " -dN\t\t\t\tOutput user defined macro names (needs -E)\n" + " -dM\t\t\t\tOutput all user macros (needs -E)\n" + " -dP\t\t\t\tOutput all predefined macros (needs -E)\n" " -g\t\t\t\tAdd debug info to object file\n" " -h\t\t\t\tHelp (this text)\n" " -j\t\t\t\tDefault characters are signed\n" @@ -1025,25 +1024,24 @@ int main (int argc, char* argv[]) break; case 'd': - switch (Arg[2]) { - case '\0': - OptDebug (Arg, 0); - break; - case 'D': - DumpUserMacrosFull = 1; - break; - case 'M': - DumpAllMacrosFull = 1; - break; - case 'N': - DumpUserMacros = 1; - break; - default: - UnknownOption (Arg); - break; - } - if (Arg[2] && Arg[3]) { - UnknownOption (Arg); + 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; @@ -1157,10 +1155,8 @@ int main (int argc, char* argv[]) } /* The options to output macros can only be used with -E */ - if (DumpAllMacrosFull || DumpUserMacros || DumpUserMacrosFull) { - if (!PreprocessOnly) { - AbEnd ("Preprocessor macro output can only be used together with -E"); - } + if ((DumpPredefMacros || DumpUserMacros) && !PreprocessOnly) { + AbEnd ("Preprocessor macro output can only be used together with -E"); } /* Add the default include search paths. */ From e4b610994c586715d3a36ed30d54c1b974d5f97f Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Mon, 16 Jun 2025 16:01:56 +0200 Subject: [PATCH 510/707] Fix #2694. Also reformatting of long comments and refactoring of a small piece of code. --- src/ld65/config.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/ld65/config.c b/src/ld65/config.c index 947302e98..cb55fae69 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -2107,7 +2107,9 @@ unsigned CfgProcess (void) FillLevel - M->Size, (FillLevel - M->Size == 1) ? "" : "s"); } if (FillLevel > M->FillLevel) { - /* Regular segments increase FillLevel. Overwrite segments may increase but not decrease FillLevel. */ + /* Regular segments increase FillLevel. Overwrite segments may + ** increase but not decrease FillLevel. + */ FillAdded = FillLevel - M->FillLevel; M->FillLevel = FillLevel; } @@ -2127,15 +2129,18 @@ unsigned CfgProcess (void) /* Calculate the new address */ Addr += S->Seg->Size; - /* If this segment will go out to the file, or its place - ** in the file will be filled, then increase the file size. - ** An OVERWRITE segment will only increase the size if it overlapped some of the fill area. + /* If this segment will go out to the file, or its place in the + ** file will be filled, then increase the file size. An OVERWRITE + ** segment will only increase the size if it overlapped some of + ** the fill area. */ if (S->Load == M && ((S->Flags & SF_BSS) == 0 || (M->Flags & MF_FILL) != 0)) { - M->F->Size += (!(S->Flags & SF_OVERWRITE)) ? - (Addr - StartAddr) : - FillAdded; + if ((S->Flags & SF_OVERWRITE) == 0) { + M->F->Size += Addr - StartAddr; + } else { + M->F->Size += FillAdded; + } } } @@ -2173,7 +2178,7 @@ unsigned CfgProcess (void) ** area, account for that in the file size. */ if ((M->Flags & MF_OVERFLOW) == 0 && (M->Flags & MF_FILL) != 0) { - M->F->Size += (M->Size - M->FillLevel); + M->F->Size = M->FileOffs + M->Size; } } From 2184ba80c7d5b116e86f490791e61e8be5c41164 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 16 Jun 2025 17:39:23 +0200 Subject: [PATCH 511/707] make <bit> part of the instruction, like in the huc6280 --- src/da65/handler.c | 48 ++++++----------- src/da65/opcm740.c | 128 ++++++++++++++++++++++----------------------- 2 files changed, 80 insertions(+), 96 deletions(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index 674769369..356e84429 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -92,29 +92,6 @@ static void OneLine (const OpcDesc* D, const char* Arg, ...) LineFeed (); } -static void OneLineNoIndent (const OpcDesc* D, const char* Arg, ...) attribute ((format(printf, 2, 3))); -static void OneLineNoIndent (const OpcDesc* D, const char* Arg, ...) -/* Output one line with the given mnemonic and argument */ -{ - char Buf [256]; - va_list ap; - - /* Mnemonic */ - Mnemonic (D->Mnemo); - - /* Argument */ - va_start (ap, Arg); - xvsprintf (Buf, sizeof (Buf), Arg, ap); - va_end (ap); - - Output ("%s", Buf); - - /* Add the code stuff as comment */ - LineComment (PC, D->Size); - - /* End the line */ - LineFeed (); -} static const char* GetAbsOverride (unsigned Flags, unsigned Addr) @@ -554,9 +531,11 @@ void OH_BitBranch (const OpcDesc* D) xfree (BranchLabel); } +/* <bit> zp, rel */ +/* NOTE: currently <bit> is part of the instruction */ void OH_BitBranch_m740 (const OpcDesc* D) { - unsigned Bit = GetCodeByte (PC) >> 5; + /* unsigned Bit = GetCodeByte (PC) >> 5; */ unsigned Addr = GetCodeByte (PC+1); signed char BranchOffs = GetCodeByte (PC+2); @@ -568,7 +547,7 @@ void OH_BitBranch_m740 (const OpcDesc* D) GenerateLabel (flLabel, BranchAddr); /* Output the line */ - OneLineNoIndent (D, "%01X %s,%s", Bit, GetAddrArg (D->Flags, Addr), GetAddrArg (flLabel, BranchAddr)); + OneLine (D, "%s, %s", GetAddrArg (D->Flags, Addr), GetAddrArg (flLabel, BranchAddr)); } void OH_ImmediateDirect (const OpcDesc* D) @@ -757,33 +736,38 @@ void OH_DirectImmediate (const OpcDesc* D) +/* <bit> zp */ +/* NOTE: currently <bit> is part of the instruction */ void OH_ZeroPageBit (const OpcDesc* D) { - unsigned Bit = GetCodeByte (PC) >> 5; + /* unsigned Bit = GetCodeByte (PC) >> 5; */ unsigned Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); /* Output the line */ - OneLineNoIndent (D, "%01X %s", Bit, GetAddrArg (D->Flags, Addr)); + OneLine (D, "%s", GetAddrArg (D->Flags, Addr)); } +/* <bit> A */ +/* NOTE: currently <bit> is part of the instruction */ void OH_AccumulatorBit (const OpcDesc* D) { - unsigned Bit = GetCodeByte (PC) >> 5; + /* unsigned Bit = GetCodeByte (PC) >> 5; */ /* Output the line */ - OneLineNoIndent (D, "%01X a", Bit); + OneLine (D, "a"); } - +/* <bit> A, rel */ +/* NOTE: currently <bit> is part of the instruction */ void OH_AccumulatorBitBranch (const OpcDesc* D) { - unsigned Bit = GetCodeByte (PC) >> 5; + /* unsigned Bit = GetCodeByte (PC) >> 5; */ signed char BranchOffs = GetCodeByte (PC+1); /* Calculate the target address for the branch */ @@ -793,7 +777,7 @@ void OH_AccumulatorBitBranch (const OpcDesc* D) GenerateLabel (flLabel, BranchAddr); /* Output the line */ - OneLineNoIndent (D, "%01X a, %s", Bit, GetAddrArg (flLabel, BranchAddr)); + OneLine (D, "a, %s", GetAddrArg (flLabel, BranchAddr)); } diff --git a/src/da65/opcm740.c b/src/da65/opcm740.c index e4bd3370f..676bf4dd4 100644 --- a/src/da65/opcm740.c +++ b/src/da65/opcm740.c @@ -51,257 +51,257 @@ const OpcDesc OpcTable_M740[256] = { { "brk", 1, flNone, OH_Implicit }, /* $00 */ { "ora", 2, flUseLabel, OH_DirectXIndirect }, /* $01 */ { "jsr", 2, flLabel, OH_JmpDirectIndirect }, /* $02 */ - { "bbs", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $03 */ + { "bbs0", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $03 */ { "", 1, flIllegal, OH_Illegal }, /* $04 */ { "ora", 2, flUseLabel, OH_Direct }, /* $05 */ { "asl", 2, flUseLabel, OH_Direct }, /* $06 */ - { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $07 */ + { "bbs0", 3, flUseLabel, OH_BitBranch_m740 }, /* $07 */ { "php", 1, flNone, OH_Implicit }, /* $08 */ { "ora", 2, flNone, OH_Immediate }, /* $09 */ { "asl", 1, flNone, OH_Accumulator }, /* $0a */ - { "seb", 1, flNone, OH_AccumulatorBit }, /* $0b */ + { "seb0", 1, flNone, OH_AccumulatorBit }, /* $0b */ { "", 1, flIllegal, OH_Illegal, }, /* $0c */ { "ora", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0d */ { "asl", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0e */ - { "seb", 2, flUseLabel, OH_ZeroPageBit }, /* $0f */ + { "seb0", 2, flUseLabel, OH_ZeroPageBit }, /* $0f */ { "bpl", 2, flLabel, OH_Relative }, /* $10 */ { "ora", 2, flUseLabel, OH_DirectIndirectY }, /* $11 */ { "clt", 1, flNone, OH_Implicit }, /* $12 */ - { "bbc", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $13 */ + { "bbc0", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $13 */ { "", 1, flIllegal, OH_Illegal }, /* $14 */ { "ora", 2, flUseLabel, OH_DirectX }, /* $15 */ { "asl", 2, flUseLabel, OH_DirectX }, /* $16 */ - { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $17 */ + { "bbc0", 3, flUseLabel, OH_BitBranch_m740 }, /* $17 */ { "clc", 1, flNone, OH_Implicit }, /* $18 */ { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */ { "dec", 1, flNone, OH_Accumulator }, /* $1a */ - { "clb", 1, flNone, OH_AccumulatorBit }, /* $1b */ + { "clb0", 1, flNone, OH_AccumulatorBit }, /* $1b */ { "", 1, flIllegal, OH_Illegal }, /* $1c */ { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */ { "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */ - { "clb", 2, flUseLabel, OH_ZeroPageBit }, /* $1f */ + { "clb0", 2, flUseLabel, OH_ZeroPageBit }, /* $1f */ { "jsr", 3, flLabel, OH_Absolute }, /* $20 */ { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */ { "jsr", 2, flLabel, OH_SpecialPage }, /* $22 */ - { "bbs", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $23 */ + { "bbs1", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $23 */ { "bit", 2, flUseLabel, OH_Direct }, /* $24 */ { "and", 2, flUseLabel, OH_Direct }, /* $25 */ { "rol", 2, flUseLabel, OH_Direct }, /* $26 */ - { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $27 */ + { "bbs1", 3, flUseLabel, OH_BitBranch_m740 }, /* $27 */ { "plp", 1, flNone, OH_Implicit }, /* $28 */ { "and", 2, flNone, OH_Immediate }, /* $29 */ { "rol", 1, flNone, OH_Accumulator }, /* $2a */ - { "seb", 1, flNone, OH_AccumulatorBit }, /* $2b */ + { "seb1", 1, flNone, OH_AccumulatorBit }, /* $2b */ { "bit", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2c */ { "and", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2d */ { "rol", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2e */ - { "seb", 2, flUseLabel, OH_ZeroPageBit }, /* $2f */ + { "seb1", 2, flUseLabel, OH_ZeroPageBit }, /* $2f */ { "bmi", 2, flLabel, OH_Relative }, /* $30 */ { "and", 2, flUseLabel, OH_DirectIndirectY }, /* $31 */ { "set", 1, flNone, OH_Implicit }, /* $32 */ - { "bbc", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $33 */ + { "bbc1", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $33 */ { "", 1, flIllegal, OH_Illegal }, /* $34 */ { "and", 2, flUseLabel, OH_DirectX }, /* $35 */ { "rol", 2, flUseLabel, OH_DirectX }, /* $36 */ - { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $37 */ + { "bbc1", 3, flUseLabel, OH_BitBranch_m740 }, /* $37 */ { "sec", 1, flNone, OH_Implicit }, /* $38 */ { "and", 3, flUseLabel, OH_AbsoluteY }, /* $39 */ { "inc", 1, flNone, OH_Accumulator }, /* $3a */ - { "clb", 1, flNone, OH_AccumulatorBit }, /* $3b */ + { "clb1", 1, flNone, OH_AccumulatorBit }, /* $3b */ { "ldm", 3, flLabel, OH_DirectImmediate }, /* $3c */ { "and", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3d */ { "rol", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3e */ - { "clb", 2, flUseLabel, OH_ZeroPageBit }, /* $3f */ + { "clb1", 2, flUseLabel, OH_ZeroPageBit }, /* $3f */ { "rti", 1, flNone, OH_Rts }, /* $40 */ { "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */ { "stp", 1, flNone, OH_Implicit }, /* $42 */ - { "bbs", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $43 */ + { "bbs2", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $43 */ { "com", 2, flUseLabel, OH_Direct }, /* $44 */ { "eor", 2, flUseLabel, OH_Direct }, /* $45 */ { "lsr", 2, flUseLabel, OH_Direct }, /* $46 */ - { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $47 */ + { "bbs2", 3, flUseLabel, OH_BitBranch_m740 }, /* $47 */ { "pha", 1, flNone, OH_Implicit }, /* $48 */ { "eor", 2, flNone, OH_Immediate }, /* $49 */ { "lsr", 1, flNone, OH_Accumulator }, /* $4a */ - { "seb", 1, flNone, OH_AccumulatorBit }, /* $4b */ + { "seb2", 1, flNone, OH_AccumulatorBit }, /* $4b */ { "jmp", 3, flLabel, OH_JmpAbsolute }, /* $4c */ { "eor", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4d */ { "lsr", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4e */ - { "seb", 2, flUseLabel, OH_ZeroPageBit }, /* $4f */ + { "seb2", 2, flUseLabel, OH_ZeroPageBit }, /* $4f */ { "bvc", 2, flLabel, OH_Relative }, /* $50 */ { "eor", 2, flUseLabel, OH_DirectIndirectY }, /* $51 */ { "", 1, flIllegal, OH_Illegal }, /* $52 */ - { "bbc", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $53 */ + { "bbc2", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $53 */ { "", 1, flIllegal, OH_Illegal }, /* $54 */ { "eor", 2, flUseLabel, OH_DirectX }, /* $55 */ { "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */ - { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $57 */ + { "bbc2", 3, flUseLabel, OH_BitBranch_m740 }, /* $57 */ { "cli", 1, flNone, OH_Implicit }, /* $58 */ { "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */ { "", 1, flIllegal, OH_Illegal }, /* $5a */ - { "clb", 1, flNone, OH_AccumulatorBit }, /* $5b */ + { "clb2", 1, flNone, OH_AccumulatorBit }, /* $5b */ { "", 1, flIllegal, OH_Illegal }, /* $5c */ { "eor", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5d */ { "lsr", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5e */ - { "clb", 2, flUseLabel, OH_ZeroPageBit }, /* $5f */ + { "clb2", 2, flUseLabel, OH_ZeroPageBit }, /* $5f */ { "rts", 1, flNone, OH_Rts }, /* $60 */ { "adc", 2, flUseLabel, OH_DirectXIndirect }, /* $61 */ { "", 1, flIllegal, OH_Illegal }, /* $62 */ - { "bbs", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $63 */ + { "bbs3", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $63 */ { "tst", 2, flUseLabel, OH_Direct }, /* $64 */ { "adc", 2, flUseLabel, OH_Direct }, /* $65 */ { "ror", 2, flUseLabel, OH_Direct }, /* $66 */ - { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $67 */ + { "bbs3", 3, flUseLabel, OH_BitBranch_m740 }, /* $67 */ { "pla", 1, flNone, OH_Implicit }, /* $68 */ { "adc", 2, flNone, OH_Immediate }, /* $69 */ { "ror", 1, flNone, OH_Accumulator }, /* $6a */ - { "seb", 1, flNone, OH_AccumulatorBit }, /* $6b */ + { "seb3", 1, flNone, OH_AccumulatorBit }, /* $6b */ { "jmp", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $6c */ { "adc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6d */ { "ror", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6e */ - { "seb", 2, flUseLabel, OH_ZeroPageBit }, /* $6f */ + { "seb3", 2, flUseLabel, OH_ZeroPageBit }, /* $6f */ { "bvs", 2, flLabel, OH_Relative }, /* $70 */ { "adc", 2, flUseLabel, OH_DirectIndirectY }, /* $71 */ { "", 1, flIllegal, OH_Illegal }, /* $72 */ - { "bbc", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $73 */ + { "bbc3", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $73 */ { "", 1, flIllegal, OH_Illegal }, /* $74 */ { "adc", 2, flUseLabel, OH_DirectX }, /* $75 */ { "ror", 2, flUseLabel, OH_DirectX }, /* $76 */ - { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $77 */ + { "bbc3", 3, flUseLabel, OH_BitBranch_m740 }, /* $77 */ { "sei", 1, flNone, OH_Implicit }, /* $78 */ { "adc", 3, flUseLabel, OH_AbsoluteY }, /* $79 */ { "", 1, flIllegal, OH_Illegal }, /* $7a */ - { "clb", 1, flNone, OH_AccumulatorBit }, /* $7b */ + { "clb3", 1, flNone, OH_AccumulatorBit }, /* $7b */ { "", 1, flIllegal, OH_Illegal }, /* $7c */ { "adc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7d */ { "ror", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7e */ - { "clb", 2, flUseLabel, OH_ZeroPageBit }, /* $7f */ + { "clb3", 2, flUseLabel, OH_ZeroPageBit }, /* $7f */ { "bra", 2, flLabel, OH_Relative }, /* $80 */ { "sta", 2, flUseLabel, OH_DirectXIndirect }, /* $81 */ { "rrf", 2, flLabel, OH_Direct }, /* $82 */ - { "bbs", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $83 */ + { "bbs4", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $83 */ { "sty", 2, flUseLabel, OH_Direct }, /* $84 */ { "sta", 2, flUseLabel, OH_Direct }, /* $85 */ { "stx", 2, flUseLabel, OH_Direct }, /* $86 */ - { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $87 */ + { "bbs4", 3, flUseLabel, OH_BitBranch_m740 }, /* $87 */ { "dey", 1, flNone, OH_Implicit }, /* $88 */ { "", 1, flIllegal, OH_Illegal }, /* $89 */ { "txa", 1, flNone, OH_Implicit }, /* $8a */ - { "seb", 1, flNone, OH_AccumulatorBit }, /* $8b */ + { "seb4", 1, flNone, OH_AccumulatorBit }, /* $8b */ { "sty", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8c */ { "sta", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8d */ { "stx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8e */ - { "seb", 2, flUseLabel, OH_ZeroPageBit }, /* $8f */ + { "seb4", 2, flUseLabel, OH_ZeroPageBit }, /* $8f */ { "bcc", 2, flLabel, OH_Relative }, /* $90 */ { "sta", 2, flUseLabel, OH_DirectIndirectY }, /* $91 */ { "", 1, flIllegal, OH_Illegal }, /* $92 */ - { "bbc", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $93 */ + { "bbc4", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $93 */ { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */ { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */ { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */ - { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $97 */ + { "bbc4", 3, flUseLabel, OH_BitBranch_m740 }, /* $97 */ { "tya", 1, flNone, OH_Implicit }, /* $98 */ { "sta", 3, flUseLabel, OH_AbsoluteY }, /* $99 */ { "txs", 1, flNone, OH_Implicit }, /* $9a */ - { "clb", 1, flNone, OH_AccumulatorBit }, /* $9b */ + { "clb4", 1, flNone, OH_AccumulatorBit }, /* $9b */ { "", 1, flIllegal, OH_Illegal }, /* $9c */ { "sta", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9d */ { "", 1, flIllegal, OH_Illegal }, /* $9e */ - { "clb", 2, flUseLabel, OH_ZeroPageBit }, /* $9f */ + { "clb4", 2, flUseLabel, OH_ZeroPageBit }, /* $9f */ { "ldy", 2, flNone, OH_Immediate }, /* $a0 */ { "lda", 2, flUseLabel, OH_DirectXIndirect }, /* $a1 */ { "ldx", 2, flNone, OH_Immediate }, /* $a2 */ - { "bbs", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $a3 */ + { "bbs5", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $a3 */ { "ldy", 2, flUseLabel, OH_Direct }, /* $a4 */ { "lda", 2, flUseLabel, OH_Direct }, /* $a5 */ { "ldx", 2, flUseLabel, OH_Direct }, /* $a6 */ - { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $a7 */ + { "bbs5", 3, flUseLabel, OH_BitBranch_m740 }, /* $a7 */ { "tay", 1, flNone, OH_Implicit }, /* $a8 */ { "lda", 2, flNone, OH_Immediate }, /* $a9 */ { "tax", 1, flNone, OH_Implicit }, /* $aa */ - { "seb", 1, flNone, OH_AccumulatorBit }, /* $ab */ + { "seb5", 1, flNone, OH_AccumulatorBit }, /* $ab */ { "ldy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ac */ { "lda", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ad */ { "ldx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ae */ - { "seb", 2, flUseLabel, OH_ZeroPageBit }, /* $af */ + { "seb5", 2, flUseLabel, OH_ZeroPageBit }, /* $af */ { "bcs", 2, flLabel, OH_Relative }, /* $b0 */ { "lda", 2, flUseLabel, OH_DirectIndirectY }, /* $b1 */ { "jmp", 2, flLabel, OH_JmpDirectIndirect }, /* $b2 */ - { "bbc", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $b3 */ + { "bbc5", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $b3 */ { "ldy", 2, flUseLabel, OH_DirectX }, /* $b4 */ { "lda", 2, flUseLabel, OH_DirectX }, /* $b5 */ { "ldx", 2, flUseLabel, OH_DirectY }, /* $b6 */ - { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $b7 */ + { "bbc5", 3, flUseLabel, OH_BitBranch_m740 }, /* $b7 */ { "clv", 1, flNone, OH_Implicit }, /* $b8 */ { "lda", 3, flUseLabel, OH_AbsoluteY }, /* $b9 */ { "tsx", 1, flNone, OH_Implicit }, /* $ba */ - { "clb", 1, flNone, OH_AccumulatorBit }, /* $bb */ + { "clb5", 1, flNone, OH_AccumulatorBit }, /* $bb */ { "ldy", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bc */ { "lda", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bd */ { "ldx", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $be */ - { "clb", 2, flUseLabel, OH_ZeroPageBit }, /* $bf */ + { "clb5", 2, flUseLabel, OH_ZeroPageBit }, /* $bf */ { "cpy", 2, flNone, OH_Immediate }, /* $c0 */ { "cmp", 2, flUseLabel, OH_DirectXIndirect }, /* $c1 */ { "slw", 1, flNone, OH_Implicit, }, /* $c2 */ - { "bbs", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $c3 */ + { "bbs6", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $c3 */ { "cpy", 2, flUseLabel, OH_Direct }, /* $c4 */ { "cmp", 2, flUseLabel, OH_Direct }, /* $c5 */ { "dec", 2, flUseLabel, OH_Direct }, /* $c6 */ - { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $c7 */ + { "bbs6", 3, flUseLabel, OH_BitBranch_m740 }, /* $c7 */ { "iny", 1, flNone, OH_Implicit }, /* $c8 */ { "cmp", 2, flNone, OH_Immediate }, /* $c9 */ { "dex", 1, flNone, OH_Implicit }, /* $ca */ - { "seb", 1, flNone, OH_AccumulatorBit }, /* $cb */ + { "seb6", 1, flNone, OH_AccumulatorBit }, /* $cb */ { "cpy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cc */ { "cmp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cd */ { "dec", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ce */ - { "seb", 2, flUseLabel, OH_ZeroPageBit }, /* $cf */ + { "seb6", 2, flUseLabel, OH_ZeroPageBit }, /* $cf */ { "bne", 2, flLabel, OH_Relative }, /* $d0 */ { "cmp", 2, flUseLabel, OH_DirectIndirectY }, /* $d1 */ { "", 1, flIllegal, OH_Illegal }, /* $d2 */ - { "bbc", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $d3 */ + { "bbc6", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $d3 */ { "", 1, flIllegal, OH_Illegal }, /* $d4 */ { "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */ { "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */ - { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $d7 */ + { "bbc6", 3, flUseLabel, OH_BitBranch_m740 }, /* $d7 */ { "cld", 1, flNone, OH_Implicit }, /* $d8 */ { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */ { "", 1, flIllegal, OH_Illegal }, /* $da */ - { "clb", 1, flNone, OH_AccumulatorBit }, /* $db */ + { "clb6", 1, flNone, OH_AccumulatorBit }, /* $db */ { "", 1, flIllegal, OH_Illegal }, /* $dc */ { "cmp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dd */ { "dec", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $de */ - { "clb", 2, flUseLabel, OH_ZeroPageBit }, /* $df */ + { "clb6", 2, flUseLabel, OH_ZeroPageBit }, /* $df */ { "cpx", 2, flNone, OH_Immediate }, /* $e0 */ { "sbc", 2, flUseLabel, OH_DirectXIndirect }, /* $e1 */ { "fst", 1, flNone, OH_Implicit }, /* $e2 */ - { "bbs", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $e3 */ + { "bbs7", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $e3 */ { "cpx", 2, flUseLabel, OH_Direct }, /* $e4 */ { "sbc", 2, flUseLabel, OH_Direct }, /* $e5 */ { "inc", 2, flUseLabel, OH_Direct }, /* $e6 */ - { "bbs", 3, flUseLabel, OH_BitBranch_m740 }, /* $e7 */ + { "bbs7", 3, flUseLabel, OH_BitBranch_m740 }, /* $e7 */ { "inx", 1, flNone, OH_Implicit }, /* $e8 */ { "sbc", 2, flNone, OH_Immediate }, /* $e9 */ { "nop", 1, flNone, OH_Implicit }, /* $ea */ - { "seb", 1, flNone, OH_AccumulatorBit }, /* $eb */ + { "seb7", 1, flNone, OH_AccumulatorBit }, /* $eb */ { "cpx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ec */ { "sbc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ed */ { "inc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ee */ - { "seb", 2, flUseLabel, OH_ZeroPageBit }, /* $ef */ + { "seb7", 2, flUseLabel, OH_ZeroPageBit }, /* $ef */ { "beq", 2, flLabel, OH_Relative }, /* $f0 */ { "sbc", 2, flUseLabel, OH_DirectIndirectY }, /* $f1 */ { "", 1, flIllegal, OH_Illegal }, /* $f2 */ - { "bbc", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $f3 */ + { "bbc7", 2, flUseLabel, OH_AccumulatorBitBranch }, /* $f3 */ { "", 1, flIllegal, OH_Illegal }, /* $f4 */ { "sbc", 2, flUseLabel, OH_DirectX }, /* $f5 */ { "inc", 2, flUseLabel, OH_DirectX }, /* $f6 */ - { "bbc", 3, flUseLabel, OH_BitBranch_m740 }, /* $f7 */ + { "bbc7", 3, flUseLabel, OH_BitBranch_m740 }, /* $f7 */ { "sed", 1, flNone, OH_Implicit }, /* $f8 */ { "sbc", 3, flUseLabel, OH_AbsoluteY }, /* $f9 */ { "", 1, flIllegal, OH_Illegal }, /* $fa */ - { "clb", 1, flNone, OH_AccumulatorBit }, /* $fb */ + { "clb7", 1, flNone, OH_AccumulatorBit }, /* $fb */ { "", 1, flIllegal, OH_Illegal }, /* $fc */ { "sbc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fd */ { "inc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fe */ - { "clb", 2, flUseLabel, OH_ZeroPageBit }, /* $ff */ + { "clb7", 2, flUseLabel, OH_ZeroPageBit }, /* $ff */ }; From 20e7c54fa36f2b4a1746b625662b71aa729d4f4c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 16 Jun 2025 20:32:54 +0200 Subject: [PATCH 512/707] more m740 fixes, makes the regression test work --- src/ca65/ea65.c | 9 +- src/ca65/instr.c | 229 ++++++--- src/ca65/instr.h | 55 +- src/da65/handler.c | 12 +- src/da65/opcm740.c | 7 +- test/asm/opcodes/m740-opcodes.ref | Bin 0 -> 768 bytes test/asm/opcodes/m740-opcodes.s | 823 ++++++++++++++++++++---------- 7 files changed, 759 insertions(+), 376 deletions(-) create mode 100644 test/asm/opcodes/m740-opcodes.ref diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c index 965d15b2d..da11b268a 100644 --- a/src/ca65/ea65.c +++ b/src/ca65/ea65.c @@ -186,10 +186,11 @@ void GetEA (EffAddr* A) /* Remaining stuff: ** - ** adr - ** adr,x - ** adr,y - ** adr,s + ** addr + ** addr, x + ** addr, y + ** addr, s + ** addr, relative addr */ A->Expr = Expression (); diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 1b33bcd7d..9fffd312f 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -138,6 +138,11 @@ static void PutJSR816 (const InsDesc* Ins); ** Allowing the long_jsr_jmp_rts feature to permit a long JSR. */ +static void PutJSR_m740 (const InsDesc* Ins); +/* Handle the JSR instruction for the m740 +** Allowing the special page feature. +*/ + static void PutRTS (const InsDesc* Ins attribute ((unused))); /* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if ** the enclosing scope is FAR, but only if the long_jsr_jmp_rts feature applies. @@ -1053,6 +1058,9 @@ static const struct { } }; +/* CAUTION: in the pdf $1a is dec a, and $3a is inc a - if that is really the case, + * the table below (and the handler) should be fixed and this notice removed */ + /* Instruction table for the m740 CPU */ static const struct { unsigned Count; @@ -1091,82 +1099,82 @@ static const struct { { "BRK", 0x00000001, 0x00, 0, PutAll }, { "BVC", 0x00020000, 0x50, 0, PutPCRel8 }, { "BVS", 0x00020000, 0x70, 0, PutPCRel8 }, - { "CLB0", 0x0000006, 0x1b, 10, PutAll }, - { "CLB1", 0x0000006, 0x3b, 10, PutAll }, - { "CLB2", 0x0000006, 0x5b, 10, PutAll }, - { "CLB3", 0x0000006, 0x7b, 10, PutAll }, - { "CLB4", 0x0000006, 0x9b, 10, PutAll }, - { "CLB5", 0x0000006, 0xbb, 10, PutAll }, - { "CLB6", 0x0000006, 0xdb, 10, PutAll }, - { "CLB7", 0x0000006, 0xfb, 10, PutAll }, - { "CLC", 0x0000001, 0x18, 0, PutAll }, - { "CLD", 0x0000001, 0xd8, 0, PutAll }, - { "CLI", 0x0000001, 0x58, 0, PutAll }, - { "CLT", 0x0000001, 0x12, 0, PutAll }, - { "CLV", 0x0000001, 0xb8, 0, PutAll }, - { "CMP", 0x080A26C, 0xc0, 0, PutAll }, - { "COM", 0x0000004, 0x44, 1, PutAll }, - { "CPX", 0x080000C, 0xe0, 1, PutAll }, - { "CPY", 0x080000C, 0xc0, 1, PutAll }, - { "DEC", 0x000006F, 0x00, 3, PutAll }, - { "DEX", 0x0000001, 0xca, 0, PutAll }, - { "DEY", 0x0000001, 0x88, 0, PutAll }, - { "EOR", 0x080A26C, 0x40, 0, PutAll }, - { "FST", 0x0000001, 0xe2, 0, PutAll }, - { "INC", 0x000006f, 0x00, 4, PutAll }, - { "INX", 0x0000001, 0xe8, 0, PutAll }, - { "INY", 0x0000001, 0xc8, 0, PutAll }, - { "JMP", 0x0000C08, 0x00, 12, PutAll }, - { "JSR", 0x0080808, 0x00, 13, PutAll }, - { "LDA", 0x080A26C, 0xa0, 0, PutAll }, + { "CLB0", 0x00000006, 0x1b, 10, PutAll }, + { "CLB1", 0x00000006, 0x3b, 10, PutAll }, + { "CLB2", 0x00000006, 0x5b, 10, PutAll }, + { "CLB3", 0x00000006, 0x7b, 10, PutAll }, + { "CLB4", 0x00000006, 0x9b, 10, PutAll }, + { "CLB5", 0x00000006, 0xbb, 10, PutAll }, + { "CLB6", 0x00000006, 0xdb, 10, PutAll }, + { "CLB7", 0x00000006, 0xfb, 10, PutAll }, + { "CLC", 0x00000001, 0x18, 0, PutAll }, + { "CLD", 0x00000001, 0xd8, 0, PutAll }, + { "CLI", 0x00000001, 0x58, 0, PutAll }, + { "CLT", 0x00000001, 0x12, 0, PutAll }, + { "CLV", 0x00000001, 0xb8, 0, PutAll }, + { "CMP", 0x0080A26C, 0xc0, 0, PutAll }, + { "COM", 0x00000004, 0x44, 1, PutAll }, + { "CPX", 0x0080000C, 0xe0, 1, PutAll }, + { "CPY", 0x0080000C, 0xc0, 1, PutAll }, + { "DEC", 0x0000006F, 0x00, 3, PutAll }, + { "DEX", 0x00000001, 0xca, 0, PutAll }, + { "DEY", 0x00000001, 0x88, 0, PutAll }, + { "EOR", 0x0080A26C, 0x40, 0, PutAll }, + { "FST", 0x00000001, 0xe2, 0, PutAll }, + { "INC", 0x0000006f, 0x00, 4, PutAll }, + { "INX", 0x00000001, 0xe8, 0, PutAll }, + { "INY", 0x00000001, 0xc8, 0, PutAll }, + { "JMP", 0x00000C08, 0x00, 12, PutAll }, + { "JSR", 0x20000408, 0x00, 13, PutJSR_m740 }, + { "LDA", 0x0080A26C, 0xa0, 0, PutAll }, { "LDM", 0x10000000, 0x3c, 0, PutLDM_m740 }, - { "LDX", 0x080030C, 0xa2, 1, PutAll }, - { "LDY", 0x080006C, 0xa0, 1, PutAll }, - { "LSR", 0x000006F, 0x42, 1, PutAll }, - { "NOP", 0x0000001, 0xea, 0, PutAll }, - { "ORA", 0x080A26C, 0x00, 0, PutAll }, - { "PHA", 0x0000001, 0x48, 0, PutAll }, - { "PHP", 0x0000001, 0x08, 0, PutAll }, - { "PLA", 0x0000001, 0x68, 0, PutAll }, - { "PLP", 0x0000001, 0x28, 0, PutAll }, - { "RMB0", 0x0000006, 0x1b, 10, PutAll }, - { "RMB1", 0x0000006, 0x3b, 10, PutAll }, - { "RMB2", 0x0000006, 0x5b, 10, PutAll }, - { "RMB3", 0x0000006, 0x7b, 10, PutAll }, - { "RMB4", 0x0000006, 0x9b, 10, PutAll }, - { "RMB5", 0x0000006, 0xbb, 10, PutAll }, - { "RMB6", 0x0000006, 0xdb, 10, PutAll }, - { "RMB7", 0x0000006, 0xfb, 10, PutAll }, - { "ROL", 0x000006F, 0x22, 1, PutAll }, - { "ROR", 0x000006F, 0x62, 1, PutAll }, - { "RRF", 0x0000004, 0x82, 6, PutAll }, - { "RTI", 0x0000001, 0x40, 0, PutAll }, - { "RTS", 0x0000001, 0x60, 0, PutAll }, - { "SBC", 0x080A26C, 0xe0, 0, PutAll }, - { "SEB0", 0x0000006, 0x0b, 10, PutAll }, - { "SEB1", 0x0000006, 0x2b, 10, PutAll }, - { "SEB2", 0x0000006, 0x4b, 10, PutAll }, - { "SEB3", 0x0000006, 0x6b, 10, PutAll }, - { "SEB4", 0x0000006, 0x8b, 10, PutAll }, - { "SEB5", 0x0000006, 0xab, 10, PutAll }, - { "SEB6", 0x0000006, 0xcb, 10, PutAll }, - { "SEB7", 0x0000006, 0xeb, 10, PutAll }, - { "SEC", 0x0000001, 0x38, 0, PutAll }, - { "SED", 0x0000001, 0xf8, 0, PutAll }, - { "SEI", 0x0000001, 0x78, 0, PutAll }, - { "SET", 0x0000001, 0x32, 0, PutAll }, - { "SLW", 0x0000001, 0xC2, 0, PutAll }, - { "STA", 0x000A26C, 0x80, 0, PutAll }, - { "STP", 0x0000001, 0x42, 0, PutAll }, - { "STX", 0x000010c, 0x82, 1, PutAll }, - { "STY", 0x000002c, 0x80, 1, PutAll }, - { "TAX", 0x0000001, 0xaa, 0, PutAll }, - { "TAY", 0x0000001, 0xa8, 0, PutAll }, - { "TST", 0x0000004, 0x64, 0, PutAll }, - { "TSX", 0x0000001, 0xba, 0, PutAll }, - { "TXA", 0x0000001, 0x8a, 0, PutAll }, - { "TXS", 0x0000001, 0x9a, 0, PutAll }, - { "TYA", 0x0000001, 0x98, 0, PutAll } + { "LDX", 0x0080030C, 0xa2, 1, PutAll }, + { "LDY", 0x0080006C, 0xa0, 1, PutAll }, + { "LSR", 0x0000006F, 0x42, 1, PutAll }, + { "NOP", 0x00000001, 0xea, 0, PutAll }, + { "ORA", 0x0080A26C, 0x00, 0, PutAll }, + { "PHA", 0x00000001, 0x48, 0, PutAll }, + { "PHP", 0x00000001, 0x08, 0, PutAll }, + { "PLA", 0x00000001, 0x68, 0, PutAll }, + { "PLP", 0x00000001, 0x28, 0, PutAll }, + { "RMB0", 0x00000006, 0x1b, 10, PutAll }, + { "RMB1", 0x00000006, 0x3b, 10, PutAll }, + { "RMB2", 0x00000006, 0x5b, 10, PutAll }, + { "RMB3", 0x00000006, 0x7b, 10, PutAll }, + { "RMB4", 0x00000006, 0x9b, 10, PutAll }, + { "RMB5", 0x00000006, 0xbb, 10, PutAll }, + { "RMB6", 0x00000006, 0xdb, 10, PutAll }, + { "RMB7", 0x00000006, 0xfb, 10, PutAll }, + { "ROL", 0x0000006F, 0x22, 1, PutAll }, + { "ROR", 0x0000006F, 0x62, 1, PutAll }, + { "RRF", 0x00000004, 0x82, 6, PutAll }, + { "RTI", 0x00000001, 0x40, 0, PutAll }, + { "RTS", 0x00000001, 0x60, 0, PutAll }, + { "SBC", 0x0080A26C, 0xe0, 0, PutAll }, + { "SEB0", 0x00000006, 0x0b, 10, PutAll }, + { "SEB1", 0x00000006, 0x2b, 10, PutAll }, + { "SEB2", 0x00000006, 0x4b, 10, PutAll }, + { "SEB3", 0x00000006, 0x6b, 10, PutAll }, + { "SEB4", 0x00000006, 0x8b, 10, PutAll }, + { "SEB5", 0x00000006, 0xab, 10, PutAll }, + { "SEB6", 0x00000006, 0xcb, 10, PutAll }, + { "SEB7", 0x00000006, 0xeb, 10, PutAll }, + { "SEC", 0x00000001, 0x38, 0, PutAll }, + { "SED", 0x00000001, 0xf8, 0, PutAll }, + { "SEI", 0x00000001, 0x78, 0, PutAll }, + { "SET", 0x00000001, 0x32, 0, PutAll }, + { "SLW", 0x00000001, 0xC2, 0, PutAll }, + { "STA", 0x0000A26C, 0x80, 0, PutAll }, + { "STP", 0x00000001, 0x42, 0, PutAll }, + { "STX", 0x0000010c, 0x82, 1, PutAll }, + { "STY", 0x0000002c, 0x80, 1, PutAll }, + { "TAX", 0x00000001, 0xaa, 0, PutAll }, + { "TAY", 0x00000001, 0xa8, 0, PutAll }, + { "TST", 0x00000004, 0x64, 1, PutAll }, + { "TSX", 0x00000001, 0xba, 0, PutAll }, + { "TXA", 0x00000001, 0x8a, 0, PutAll }, + { "TXS", 0x00000001, 0x9a, 0, PutAll }, + { "TYA", 0x00000001, 0x98, 0, PutAll } /* END SORTED.SH */ } }; @@ -1197,43 +1205,43 @@ static unsigned char EATab[14][AM65I_COUNT] = { 0x00, 0x00, 0x00, 0x03, 0x13, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00 }, - { /* Table 1 */ + { /* Table 1 (rol, ror, stx, sty) */ 0x08, 0x08, 0x04, 0x0C, 0x00, 0x14, 0x1C, 0x00, 0x14, 0x1C, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, - { /* Table 2 */ + { /* Table 2 (bit) */ 0x00, 0x00, 0x24, 0x2C, 0x0F, 0x34, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { /* Table 3 */ + { /* Table 3 (dec, dea) */ 0x3A, 0x3A, 0xC6, 0xCE, 0x00, 0xD6, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { /* Table 4 */ + { /* Table 4 (inc) */ 0x1A, 0x1A, 0xE6, 0xEE, 0x00, 0xF6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { /* Table 5 */ + { /* Table 5 (stz) */ 0x00, 0x00, 0x60, 0x98, 0x00, 0x70, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { /* Table 6 */ + { /* Table 6 (jmp) */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00 }, - { /* Table 7 (Subroutine opcodes) */ + { /* Table 7 (Subroutine opcodes) (jsr) */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1245,7 +1253,7 @@ static unsigned char EATab[14][AM65I_COUNT] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { /* Table 9 */ + { /* Table 9 (dew, inw) */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1644,7 +1652,7 @@ static void PutBitBranch_m740 (const InsDesc* Ins) /* Accu */ Emit0 (A.Opcode); ConsumeComma (); - EmitSigned (GenBranchExpr (1), 1); + EmitSigned (GenBranchExpr (2), 1); } else if (A.AddrModeSet == 0x10000000) { A.Opcode += 0x04; /* Zeropage */ @@ -1870,6 +1878,59 @@ static void PutJSR816 (const InsDesc* Ins) } +static void PutJSR_m740 (const InsDesc* Ins) +/* Handle a JSR instruction for m740 */ +{ + EffAddr A; + + /* Evaluate the addressing mode used */ + GetEA (&A); + + /* From the possible addressing modes, remove the ones that are invalid + ** for this instruction or CPU. + */ + A.AddrModeSet &= Ins->AddrMode; + + /* Check if we have any adressing modes left */ + if (A.AddrModeSet == 0) { + Error ("Illegal addressing mode"); + return; + } + A.AddrMode = BitFind (A.AddrModeSet); + A.AddrModeBit = (0x01UL << A.AddrMode); + + /* Build the opcode */ + /* A.Opcode = Ins->BaseCode | EATab[Ins->ExtCode][A.AddrMode] | A.Reg; */ + A.Opcode = Ins->BaseCode; + + switch (A.AddrMode) { + case AM65I_DIR_IND: + A.Opcode = 0x02; + Emit1 (A.Opcode, A.Expr); + break; + case AM65I_ABS: + /* If we have an expression and it's const, get it's value */ + if (A.Expr) { + long Val = -1; + if (IsConstExpr (A.Expr, &Val)) { + if ((Val & 0xff00) == 0xff00) { + /* direct page */ + A.Opcode = 0x22; + Emit0 (A.Opcode); + EmitByte(GenByteExpr(A.Expr)); + return; + } + } + } + A.Opcode = 0x20; + Emit2 (A.Opcode, A.Expr); + break; + default: + Internal ("Invalid Opcode 0x%02x", A.Opcode); + } + +} + static void PutRTS (const InsDesc* Ins attribute ((unused))) /* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if diff --git a/src/ca65/instr.h b/src/ca65/instr.h index fff5a0f34..e31ae0734 100644 --- a/src/ca65/instr.h +++ b/src/ca65/instr.h @@ -68,8 +68,8 @@ #define AM65_ABS_LONG_X 0x00000080UL /* -- */ #define AM65_DIR_Y 0x00000100UL /* ZP, Y */ #define AM65_ABS_Y 0x00000200UL /* ABS, Y */ -#define AM65_DIR_IND 0x00000400UL /* ZP, IND */ -#define AM65_ABS_IND 0x00000800UL /* IND */ +#define AM65_DIR_IND 0x00000400UL /* (ZP IND) */ +#define AM65_ABS_IND 0x00000800UL /* (IND) */ #define AM65_DIR_IND_LONG 0x00001000UL /* -- */ #define AM65_DIR_IND_Y 0x00002000UL /* IND, Y */ #define AM65_DIR_IND_LONG_Y 0x00004000UL /* -- */ @@ -87,40 +87,55 @@ #define AM65_ABS_IND_LONG 0x04000000UL /* -- */ #define AM65_IMM_IMPLICIT_WORD 0x08000000UL /* PHW #$1234 (4510 only) */ #define AM65_ZP_REL 0x10000000UL /* ZP, REL (m740) */ +#define AM65_SPECIAL_PAGE 0x20000000UL /* $FFxx (m740) */ /* Bitmask for all ZP operations that have correspondent ABS ops */ -/* $8524 */ #define AM65_SET_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND) - /*$4 $20 $100 $400 $8000 */ /* Bitmask for all ABS operations that have correspondent FAR ops */ -/* $48 */ #define AM65_SET_ABS (AM65_ABS | AM65_ABS_X) -/* $8 $40 */ /* Bitmask for all ZP operations */ -/* $8524 */ #define AM65_ALL_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND) - /*$4 $20 $100 $400 $8000 */ /* Bitmask for all ABS operations */ -/* $10a48 */ #define AM65_ALL_ABS (AM65_ABS | AM65_ABS_X | AM65_ABS_Y | AM65_ABS_IND | AM65_ABS_X_IND) -/* $8 $40 $200 $800 $10000 */ /* Bitmask for all FAR operations */ -/* $90 */ #define AM65_ALL_FAR (AM65_ABS_LONG | AM65_ABS_LONG_X) - /* $10 $80 */ - /* Bitmask for all immediate operations */ -/* $8e00 000 */ #define AM65_ALL_IMM (AM65_IMM_ACCU | AM65_IMM_INDEX | AM65_IMM_IMPLICIT | AM65_IMM_IMPLICIT_WORD) -/* $200000 $400000 $800000 $8000000 */ + /* Bit numbers and count */ -#define AM65I_IMM_ACCU 21 -#define AM65I_IMM_INDEX 22 -#define AM65I_IMM_IMPLICIT 23 -#define AM65I_IMM_IMPLICIT_WORD 27 -#define AM65I_COUNT 28 +#define AM65I_IMPLICIT 0 +#define AM65I_ACCU 1 +#define AM65I_DIR 2 +#define AM65I_ABS 3 +#define AM65I_ABS_LONG 4 +#define AM65I_DIR_X 5 +#define AM65I_ABS_X 6 +#define AM65I_ABS_LONG_X 7 +#define AM65I_DIR_Y 8 +#define AM65I_ABS_Y 9 +#define AM65I_DIR_IND 10 +#define AM65I_ABS_IND 11 +#define AM65I_DIR_IND_LONG 12 +#define AM65I_DIR_IND_Y 13 +#define AM65I_DIR_IND_LONG_Y 14 +#define AM65I_DIR_X_IND 15 +#define AM65I_ABS_X_IND 16 +#define AM65I_REL 17 +#define AM65I_REL_LONG 18 +#define AM65I_STACK_REL 19 +#define AM65I_STACK_REL_IND_Y 20 +#define AM65I_IMM_ACCU 21 +#define AM65I_IMM_INDEX 22 +#define AM65I_IMM_IMPLICIT 23 +#define AM65I_BLOCKMOVE 24 +#define AM65I_BLOCKXFER 25 +#define AM65I_ABS_IND_LONG 26 +#define AM65I_IMM_IMPLICIT_WORD 27 +#define AM65I_ZP_REL 28 +#define AM65I_SPECIAL_PAGE 29 +#define AM65I_COUNT 30 diff --git a/src/da65/handler.c b/src/da65/handler.c index 356e84429..4f35fbaa3 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -795,14 +795,14 @@ void OH_JmpDirectIndirect (const OpcDesc* D) void OH_SpecialPage (const OpcDesc* D) { - /* Get the operand */ - unsigned Addr = 0xFF00 + GetCodeByte (PC+1); + /* Get the operand */ + unsigned Addr = 0xFF00 + GetCodeByte (PC+1); - /* Generate a label in pass 1 */ - GenerateLabel (D->Flags, Addr); + /* Generate a label in pass 1 */ + GenerateLabel (D->Flags, Addr); - /* OneLine (D, "$FF%02X", (CodeByte (PC+1)); */ - OneLine (D, "%s", GetAddrArg (D->Flags, Addr)); + /* OneLine (D, "$FF%02X", (CodeByte (PC+1)); */ + OneLine (D, "%s", GetAddrArg (D->Flags, Addr)); } diff --git a/src/da65/opcm740.c b/src/da65/opcm740.c index 676bf4dd4..6d12a7d37 100644 --- a/src/da65/opcm740.c +++ b/src/da65/opcm740.c @@ -44,7 +44,8 @@ /* Data */ /*****************************************************************************/ - +/* CAUTION: in the pdf $1a is dec, and $3a is inc - if that is really the case, + * the table below should be fixed and this notice removed */ /* Descriptions for all opcodes */ const OpcDesc OpcTable_M740[256] = { @@ -74,7 +75,7 @@ const OpcDesc OpcTable_M740[256] = { { "bbc0", 3, flUseLabel, OH_BitBranch_m740 }, /* $17 */ { "clc", 1, flNone, OH_Implicit }, /* $18 */ { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */ - { "dec", 1, flNone, OH_Accumulator }, /* $1a */ + { "inc", 1, flNone, OH_Accumulator }, /* $1a */ { "clb0", 1, flNone, OH_AccumulatorBit }, /* $1b */ { "", 1, flIllegal, OH_Illegal }, /* $1c */ { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */ @@ -106,7 +107,7 @@ const OpcDesc OpcTable_M740[256] = { { "bbc1", 3, flUseLabel, OH_BitBranch_m740 }, /* $37 */ { "sec", 1, flNone, OH_Implicit }, /* $38 */ { "and", 3, flUseLabel, OH_AbsoluteY }, /* $39 */ - { "inc", 1, flNone, OH_Accumulator }, /* $3a */ + { "dec", 1, flNone, OH_Accumulator }, /* $3a */ { "clb1", 1, flNone, OH_AccumulatorBit }, /* $3b */ { "ldm", 3, flLabel, OH_DirectImmediate }, /* $3c */ { "and", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3d */ diff --git a/test/asm/opcodes/m740-opcodes.ref b/test/asm/opcodes/m740-opcodes.ref new file mode 100644 index 0000000000000000000000000000000000000000..b3cffc9b6c66b8de4f1cdec2e9ae8304a0b02588 GIT binary patch literal 768 zcmV~$0{|cd006OYdD*sY+qP}n{A}B{ZQHhO+qDg(fi;K*RT@l#YX}Xgp)|CH5e=*1 zG`vR8h#E;FYZQ&D(KNco(3l!aV{06ZtMN3xCeVbMNE2%kO{&Q>xu(#Rno3h^8cnO| zG`(ifjG9R^YZlF_*)+T6(43k}b88;WtNAp)7SMuPNDFHbEvm(|xR%h8T1rc687-^j zw7gc(idso4YZa}k)wH_S(3)CHYik{?tM#<LHqeIJNE>StZK}<*xwg=j+Dcn%8*QuY zw7quFj@n5(YZvXR-L$**(4N{$dut!<tNk=U`|AK5sDpH{4$+}HOo!_T9jT*qw2slS zI!?#y1f8gpbh1v-sX9%k>kOT#vvju3(YZQL=j#GpsEc&5F43jBOqc5lU8$>dwXV^% zx=z>Y2HmKebhB>Jt-4LO>ki$iyL7ki(Y?A)_v-;YsE72h9?_$EOpogcJ*lVkw4Twk zdQQ*l1-+=3^s-*jt9nhZ>kYlBxAeB&(Ytz2@9P77sE_oqKGCQ8OrPrueW|bXwZ74} h`cB{L2mPp@^s|1^ulh~D>ks{@zx22M(ZBjn{{s(bkAVOH literal 0 HcmV?d00001 diff --git a/test/asm/opcodes/m740-opcodes.s b/test/asm/opcodes/m740-opcodes.s index df6d71488..e4f8562cc 100644 --- a/test/asm/opcodes/m740-opcodes.s +++ b/test/asm/opcodes/m740-opcodes.s @@ -1,260 +1,565 @@ -.setcpu "65C02" -; copy of 65c02, comments note changes to the m740 according to -; http://documentation.renesas.com/doc/products/mpumcu/rej09b0322_740sm.pdf +; da65 V2.19 - Git 89651fd8b +; Created: 2025-06-16 20:10:42 +; Input file: testfile +; Page: 1 - brk - ora ($12,x) - .byte $02,$00,$00 ; jsr zp,ind - .byte $03,$00,$00 ; bbs 0,a - tsb $12 ; .byte $04 - ora $12 - asl $12 - rmb0 $12 ; bbs 0,zp - php - ora #$12 - asl a - .byte $0B,$00,$00 ; seb 0,a - tsb $3456 ; .byte $0c - ora $3456 - asl $3456 - bbr0 $12,*+122 ; seb 0,zp - bpl *+122 - ora ($12),y - ora ($12) ; clt - .byte $13,$00,$00 ; bbc 0,a - trb $12 ; .byte $14 - ora $12,x - asl $12,x - rmb1 $12 ; bbc 0,zp - clc - ora $3456,y - inc a - .byte $1B,$00,$00 ; clb 0,a - trb $3456 ; .byte $1c - ora $3456,x - asl $3456,x - bbr1 $12,*+122 ; clb 0,zp - jsr $3456 - and ($12,x) - .byte $22,$00,$00 ; jsr sp - .byte $23,$00,$00 ; bbs 1,a - bit $12 - and $12 - rol $12 - rmb2 $12 ; bbs 1,zp - plp - and #$12 - rol a - .byte $2B,$00,$00 ; seb 1,a - bit $3456 - and $3456 - rol $3456 - bbr2 $12,*+122 ; seb 1,zp - bmi *+122 - and ($12),y - and ($12) ; set - .byte $33,$00,$00 ; bbc 1,a - bit $12,x ; .byte $34 - and $12,x - rol $12,x - rmb3 $12 ; bbc 1,zp - sec - and $3456,y - dec a - .byte $3B,$00,$00 ; clb 1,a - bit $3456,x ; ldm zp - and $3456,x - rol $3456,x - bbr3 $12,*+122 ; clb 1,zp - rti - eor ($12,x) - .byte $42,$00,$00 ; stp - .byte $43,$00,$00 ; bbs 2,a - .byte $44,$00,$00 ; com zp - eor $12 - lsr $12 - rmb4 $12 ; bbs 2,zp - pha - eor #$12 - lsr a - .byte $4B,$00,$00 ; seb 2,a - jmp $3456 - eor $3456 - lsr $3456 - bbr4 $12,*+122 ; seb 2,zp - bvc *+122 - eor ($12),y - eor ($12) ; .byte $52 - .byte $53,$00,$00 ; bbc 2,a - .byte $54,$00,$00 - eor $12,x - lsr $12,x - rmb5 $12 ; bbc 2,zp - cli - eor $3456,y - phy - .byte $5B,$00,$00 ; clb 2,a - .byte $5C,$00,$00 - eor $3456,x - lsr $3456,x - bbr5 $12,*+122 ; clb 2,zp - rts - adc ($12,x) - .byte $62,$00,$00 ; mul zp,x - .byte $63,$00,$00 ; bbs 3,a - stz $12 ; tst zp - adc $12 - ror $12 - rmb6 $12 ; bbs 3,zp - pla - adc #$12 - ror a - .byte $6B,$00,$00 ; seb 3,a - jmp ($3456) - adc $3456 - ror $3456 - bbr6 $12,*+122 ; seb 3,zp - bvs *+122 - adc ($12),y - adc ($12) ; .byte $72 - .byte $73,$00,$00 ; bbc 3,a - stz $12,x ; .byte $74 - adc $12,x - ror $12,x - rmb7 $12 ; bbc 3,zp - sei - adc $3456,y - ply - .byte $7B,$00,$00 ; clb 3,a - jmp ($3456,x) ; .byte $7c - adc $3456,x - ror $3456,x - bbr7 $12,*+122 ; clb 3,zp - bra *+122 - sta ($12,x) - .byte $82,$00,$00 ; rrf zp - .byte $83,$00,$00 ; bbs 4,a - sty $12 - sta $12 - stx $12 - smb0 $12 ; bbs 4,zp - dey - bit #$12 - txa - .byte $8B,$00,$00 ; seb 4,a - sty $3456 - sta $3456 - stx $3456 - bbs0 $12,*+122 ; seb 4,zp - bcc *+122 - sta ($12),y - sta ($12) ; .byte $92 - .byte $93,$00,$00 ; bbc 4,a - sty $12,x - sta $12,x - stx $12,y - smb1 $12 ; bbc 4,zp - tya - sta $3456,y - txs - .byte $9B,$00,$00 ; clb 4,a - stz $3456 ; .byte $9c - sta $3456,x - stz $3456,x ; .byte $9e - bbs1 $12,*+122 ; clb 4,zp - ldy #$12 - lda ($12,x) - ldx #$12 - .byte $A3,$00,$00 ; bbs 5,a - ldy $12 - lda $12 - ldx $12 - smb2 $12 ; bbs 5,zp - tay - lda #$12 - tax - .byte $AB,$00,$00 ; seb 5,a - ldy $3456 - lda $3456 - ldx $3456 - bbs2 $12,*+122 ; seb 5,zp - bcs *+122 - lda ($12),y - lda ($12) ; .byte $b2 - .byte $B3,$00,$00 ; bbc 5,a - ldy $12,x - lda $12,x - ldx $12,y - smb3 $12 ; bbc 5,zp - clv - lda $3456,y - tsx - .byte $BB,$00,$00 ; clb 5,a - ldy $3456,x - lda $3456,x - ldx $3456,y - bbs3 $12,*+122 ; clb 5,zp - cpy #$12 - cmp ($12,x) - .byte $C2,$00,$00 ; wit - .byte $C3,$00,$00 ; bbs 6,a - cpy $12 - cmp $12 - dec $12 - smb4 $12 ; bbs 6,zp - iny - cmp #$12 - dex - .byte $CB,$00,$00 ; seb 6,a - cpy $3456 - cmp $3456 - dec $3456 - bbs4 $12,*+122 ; seb 6,zp - bne *+122 - cmp ($12),y - cmp ($12) ; .byte $d2 - .byte $D3,$00,$00 ; bbc 6,a - .byte $D4,$00,$00 - cmp $12,x - dec $12,x - smb5 $12 ; bbc 6,zp - cld - cmp $3456,y - phx - .byte $DB,$00,$00 ; clb 6,a - .byte $DC,$00,$00 - cmp $3456,x - dec $3456,x - bbs5 $12,*+122 ; clb 6,zp - cpx #$12 - sbc ($12,x) - .byte $E2,$00,$00 ; div zp,x - .byte $E3,$00,$00 ; bbs 7,a - cpx $12 - sbc $12 - inc $12 - smb6 $12 ; bbs 7,zp - inx - sbc #$12 - nop - .byte $EB,$00,$00 ; seb 7,a - cpx $3456 - sbc $3456 - inc $3456 - bbs6 $12,*+122 ; seb 7,zp - beq *+122 - sbc ($12),y - sbc ($12) ; .byte $f2 - .byte $F3,$00,$00 ; bbc 7,a - .byte $F4,$00,$00 - sbc $12,x - inc $12,x - smb7 $12 ; bbc 7,zp - sed - sbc $3456,y - plx - .byte $FB,$00,$00 ; clb 7,a - .byte $FC,$00,$00 - sbc $3456,x - inc $3456,x - bbs7 $12,*+122 ; clb 7,zp + + .setcpu "m740" + +L000C := $000C +L040C := $040C +LFF0C := $FF0C + brk + .byte $0C + .byte $04 + ora (L000C,x) + .byte $04 + jsr (L000C) + + .byte $04 + bbs0 a, L8018 + .byte $04 + .byte $04 + .byte $0C + .byte $04 + ora L000C + .byte $04 + asl L000C + .byte $04 + bbs0 L000C, L801C +L8018: php + .byte $0C + .byte $04 + .byte $09 +L801C: .byte $0C + .byte $04 + asl a + .byte $0C + .byte $04 + seb0 a + .byte $0C + .byte $04 + .byte $0C + .byte $0C + .byte $04 + ora L040C + asl L040C + seb0 L000C + .byte $04 + bpl L803E + .byte $04 + ora (L000C),y + .byte $04 + clt + .byte $0C + .byte $04 + bbc0 a, L8048 + .byte $04 + .byte $14 + .byte $0C +L803E: .byte $04 + ora L000C,x + .byte $04 + asl L000C,x + .byte $04 + bbc0 L000C, L804C +L8048: clc + .byte $0C + .byte $04 + .byte $19 +L804C: .byte $0C + .byte $04 + inc a + .byte $0C + .byte $04 + clb0 a + .byte $0C + .byte $04 + .byte $1C + .byte $0C + .byte $04 + ora L040C,x + asl L040C,x + clb0 L000C + .byte $04 + jsr L040C + and (L000C,x) + .byte $04 + jsr LFF0C + .byte $04 + bbs1 a, L8078 + .byte $04 + bit L000C + .byte $04 + and L000C + .byte $04 + rol L000C + .byte $04 + bbs1 L000C, L807C +L8078: plp + .byte $0C + .byte $04 + .byte $29 +L807C: .byte $0C + .byte $04 + rol a + .byte $0C + .byte $04 + seb1 a + .byte $0C + .byte $04 + bit L040C + and L040C + rol L040C + seb1 L000C + .byte $04 + bmi L809E + .byte $04 + and (L000C),y + .byte $04 + set + .byte $0C + .byte $04 + bbc1 a, L80A8 + .byte $04 + .byte $34 + .byte $0C +L809E: .byte $04 + and L000C,x + .byte $04 + rol L000C,x + .byte $04 + bbc1 L000C, L80AC +L80A8: sec + .byte $0C + .byte $04 + .byte $39 +L80AC: .byte $0C + .byte $04 + dec a + .byte $0C + .byte $04 + clb1 a + .byte $0C + .byte $04 + ldm L000C, #$04 + and L040C,x + rol L040C,x + clb1 L000C + .byte $04 + rti + + .byte $0C + .byte $04 + eor (L000C,x) + .byte $04 + stp + .byte $0C + .byte $04 + bbs2 a, L80D8 + .byte $04 + com L000C + .byte $04 + eor L000C + .byte $04 + lsr L000C + .byte $04 + bbs2 L000C, L80DC +L80D8: pha + .byte $0C + .byte $04 + .byte $49 +L80DC: .byte $0C + .byte $04 + lsr a + .byte $0C + .byte $04 + seb2 a + .byte $0C + .byte $04 + jmp L040C + + eor L040C + lsr L040C + seb2 L000C + .byte $04 + bvc L80FE + .byte $04 + eor (L000C),y + .byte $04 + .byte $52 + .byte $0C + .byte $04 + bbc2 a, L8108 + .byte $04 + .byte $54 + .byte $0C +L80FE: .byte $04 + eor L000C,x + .byte $04 + lsr L000C,x + .byte $04 + bbc2 L000C, L810C +L8108: cli + .byte $0C + .byte $04 + .byte $59 +L810C: .byte $0C + .byte $04 + .byte $5A + .byte $0C + .byte $04 + clb2 a + .byte $0C + .byte $04 + .byte $5C + .byte $0C + .byte $04 + eor L040C,x + lsr L040C,x + clb2 L000C + .byte $04 + rts + + .byte $0C + .byte $04 + adc (L000C,x) + .byte $04 + .byte $62 + .byte $0C + .byte $04 + bbs3 a, L8138 + .byte $04 + tst L000C + .byte $04 + adc L000C + .byte $04 + ror L000C + .byte $04 + bbs3 L000C, L813C +L8138: pla + .byte $0C + .byte $04 + .byte $69 +L813C: .byte $0C + .byte $04 + ror a + .byte $0C + .byte $04 + seb3 a + .byte $0C + .byte $04 + jmp (L040C) + + adc L040C + ror L040C + seb3 L000C + .byte $04 + bvs L815E + .byte $04 + adc (L000C),y + .byte $04 + .byte $72 + .byte $0C + .byte $04 + bbc3 a, L8168 + .byte $04 + .byte $74 + .byte $0C +L815E: .byte $04 + adc L000C,x + .byte $04 + ror L000C,x + .byte $04 + bbc3 L000C, L816C +L8168: sei + .byte $0C + .byte $04 + .byte $79 +L816C: .byte $0C + .byte $04 + .byte $7A + .byte $0C + .byte $04 + clb3 a + .byte $0C + .byte $04 + .byte $7C + .byte $0C + .byte $04 + adc L040C,x + ror L040C,x + clb3 L000C + .byte $04 + bra L818E + .byte $04 + sta (L000C,x) + .byte $04 + rrf L000C + .byte $04 + bbs4 a, L8198 + .byte $04 + sty L000C +L818E: .byte $04 + sta L000C + .byte $04 + stx L000C + .byte $04 + bbs4 L000C, L819C +L8198: dey + .byte $0C + .byte $04 + .byte $89 +L819C: .byte $0C + .byte $04 + txa + .byte $0C + .byte $04 + seb4 a + .byte $0C + .byte $04 + sty L040C + sta L040C + stx L040C + seb4 L000C + .byte $04 + bcc L81BE + .byte $04 + sta (L000C),y + .byte $04 + .byte $92 + .byte $0C + .byte $04 + bbc4 a, L81C8 + .byte $04 + sty L000C,x +L81BE: .byte $04 + sta L000C,x + .byte $04 + stx L000C,y + .byte $04 + bbc4 L000C, L81CC +L81C8: tya + .byte $0C + .byte $04 + .byte $99 +L81CC: .byte $0C + .byte $04 + txs + .byte $0C + .byte $04 + clb4 a + .byte $0C + .byte $04 + .byte $9C + .byte $0C + .byte $04 + sta L040C,x + .byte $9E + .byte $0C + .byte $04 + clb4 L000C + .byte $04 + ldy #$0C + .byte $04 + lda (L000C,x) + .byte $04 + ldx #$0C + .byte $04 + bbs5 a, L81F8 + .byte $04 + ldy L000C + .byte $04 + lda L000C + .byte $04 + ldx L000C + .byte $04 + bbs5 L000C, L81FC +L81F8: tay + .byte $0C + .byte $04 + .byte $A9 +L81FC: .byte $0C + .byte $04 + tax + .byte $0C + .byte $04 + seb5 a + .byte $0C + .byte $04 + ldy L040C + lda L040C + ldx L040C + seb5 L000C + .byte $04 + bcs L821E + .byte $04 + lda (L000C),y + .byte $04 + jmp (L000C) + + .byte $04 + bbc5 a, L8228 + .byte $04 + ldy L000C,x +L821E: .byte $04 + lda L000C,x + .byte $04 + ldx L000C,y + .byte $04 + bbc5 L000C, L822C +L8228: clv + .byte $0C + .byte $04 + .byte $B9 +L822C: .byte $0C + .byte $04 + tsx + .byte $0C + .byte $04 + clb5 a + .byte $0C + .byte $04 + ldy L040C,x + lda L040C,x + ldx L040C,y + clb5 L000C + .byte $04 + cpy #$0C + .byte $04 + cmp (L000C,x) + .byte $04 + slw + .byte $0C + .byte $04 + bbs6 a, L8258 + .byte $04 + cpy L000C + .byte $04 + cmp L000C + .byte $04 + dec L000C + .byte $04 + bbs6 L000C, L825C +L8258: iny + .byte $0C + .byte $04 + .byte $C9 +L825C: .byte $0C + .byte $04 + dex + .byte $0C + .byte $04 + seb6 a + .byte $0C + .byte $04 + cpy L040C + cmp L040C + dec L040C + seb6 L000C + .byte $04 + bne L827E + .byte $04 + cmp (L000C),y + .byte $04 + .byte $D2 + .byte $0C + .byte $04 + bbc6 a, L8288 + .byte $04 + .byte $D4 + .byte $0C +L827E: .byte $04 + cmp L000C,x + .byte $04 + dec L000C,x + .byte $04 + bbc6 L000C, L828C +L8288: cld + .byte $0C + .byte $04 + .byte $D9 +L828C: .byte $0C + .byte $04 + .byte $DA + .byte $0C + .byte $04 + clb6 a + .byte $0C + .byte $04 + .byte $DC + .byte $0C + .byte $04 + cmp L040C,x + dec L040C,x + clb6 L000C + .byte $04 + cpx #$0C + .byte $04 + sbc (L000C,x) + .byte $04 + fst + .byte $0C + .byte $04 + bbs7 a, L82B8 + .byte $04 + cpx L000C + .byte $04 + sbc L000C + .byte $04 + inc L000C + .byte $04 + bbs7 L000C, L82BC +L82B8: inx + .byte $0C + .byte $04 + .byte $E9 +L82BC: .byte $0C + .byte $04 + nop + .byte $0C + .byte $04 + seb7 a + .byte $0C + .byte $04 + cpx L040C + sbc L040C + inc L040C + seb7 L000C + .byte $04 + beq L82DE + .byte $04 + sbc (L000C),y + .byte $04 + .byte $F2 + .byte $0C + .byte $04 + bbc7 a, L82E8 + .byte $04 + .byte $F4 + .byte $0C +L82DE: .byte $04 + sbc L000C,x + .byte $04 + inc L000C,x + .byte $04 + bbc7 L000C, L82EC +L82E8: sed + .byte $0C + .byte $04 + .byte $F9 +L82EC: .byte $0C + .byte $04 + .byte $FA + .byte $0C + .byte $04 + clb7 a + .byte $0C + .byte $04 + .byte $FC + .byte $0C + .byte $04 + sbc L040C,x + inc L040C,x + clb7 L000C + .byte $04 From 0b74ae8c2d80fcba49ed5b0557da414363f0f9c0 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 16 Jun 2025 21:59:38 +0200 Subject: [PATCH 513/707] add m740 to macpack cpu, add .ifpm740, add regression test for those --- asminc/cpu.mac | 3 ++- src/ca65/condasm.c | 11 +++++++++++ src/ca65/pseudo.c | 1 + src/ca65/scanner.c | 1 + src/ca65/token.h | 1 + test/asm/cpudetect/cpudetect.s | 8 ++++++++ test/asm/cpudetect/m740-cpudetect.ref | Bin 0 -> 30 bytes 7 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 test/asm/cpudetect/m740-cpudetect.ref diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 084a42119..1f5c0758e 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -8,7 +8,7 @@ CPU_ISET_65C02 = $0020 CPU_ISET_65816 = $0040 CPU_ISET_SWEET16 = $0080 CPU_ISET_HUC6280 = $0100 -;CPU_ISET_M740 = $0200 not actually implemented +CPU_ISET_M740 = $0200 CPU_ISET_4510 = $0400 ; CPU capabilities @@ -22,3 +22,4 @@ CPU_65816 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65816 CPU_SWEET16 = CPU_ISET_SWEET16 CPU_HUC6280 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_HUC6280 CPU_4510 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_4510 +CPU_M740 = CPU_ISET_6502|CPU_ISET_M740 diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index f872ec9ed..049367758 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -434,6 +434,16 @@ void DoConditionals (void) CalcOverallIfCond (); break; + case TOK_IFPM740: + D = AllocIf (".IFPM740", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_M740); + } + ExpectSep (); + CalcOverallIfCond (); + break; + case TOK_IFPSC02: D = AllocIf (".IFPSC02", 1); NextTok (); @@ -489,6 +499,7 @@ int CheckConditionals (void) case TOK_IFP816: case TOK_IFPC02: case TOK_IFPDTV: + case TOK_IFPM740: case TOK_IFPSC02: case TOK_IFREF: DoConditionals (); diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 2ce1ae087..2a14295ab 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -2135,6 +2135,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccKeepToken, DoConditionals }, /* .IFP816 */ { ccKeepToken, DoConditionals }, /* .IFPC02 */ { ccKeepToken, DoConditionals }, /* .IFPDTV */ + { ccKeepToken, DoConditionals }, /* .IFPM740 */ { ccKeepToken, DoConditionals }, /* .IFPSC02 */ { ccKeepToken, DoConditionals }, /* .IFREF */ { ccNone, DoImport }, diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 94c84d897..f93ae977e 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -225,6 +225,7 @@ struct DotKeyword { { ".IFP816", TOK_IFP816 }, { ".IFPC02", TOK_IFPC02 }, { ".IFPDTV", TOK_IFPDTV }, + { ".IFPM740", TOK_IFPM740 }, { ".IFPSC02", TOK_IFPSC02 }, { ".IFREF", TOK_IFREF }, { ".IMPORT", TOK_IMPORT }, diff --git a/src/ca65/token.h b/src/ca65/token.h index 8f935f7a1..a29c6e5ab 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -197,6 +197,7 @@ typedef enum token_t { TOK_IFP816, TOK_IFPC02, TOK_IFPDTV, + TOK_IFPM740, TOK_IFPSC02, TOK_IFREF, TOK_IMPORT, diff --git a/test/asm/cpudetect/cpudetect.s b/test/asm/cpudetect/cpudetect.s index 7b2363b7f..d4d5b9f9f 100644 --- a/test/asm/cpudetect/cpudetect.s +++ b/test/asm/cpudetect/cpudetect.s @@ -28,6 +28,10 @@ sac #$00 .endif +.ifpm740 + jsr $ff12 +.endif + ; step 2: check for bitwise compatibility of instructions sets ; (made verbose for better reading with hexdump/hd(1)) @@ -72,3 +76,7 @@ .byte 0,"CPU_ISET_6502DTV" .endif +.if (.cpu .bitand CPU_ISET_M740) + .byte 0,"CPU_ISET_M740" +.endif + diff --git a/test/asm/cpudetect/m740-cpudetect.ref b/test/asm/cpudetect/m740-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..7788f3ed95ee9e39843989436875ff8889986a60 GIT binary patch literal 30 ccmY!qVsH)!jrR<84T(21H84W(e9cV^0C1ECpa1{> literal 0 HcmV?d00001 From 17a8c92ba1cf40b7fb1244d80abff7ffee7539a8 Mon Sep 17 00:00:00 2001 From: Russell-S-Harper <russell.s.harper@gmail.com> Date: Sun, 15 Jun 2025 13:32:25 -0400 Subject: [PATCH 514/707] Implement conio cgets --- include/conio.h | 18 +++++++ libsrc/conio/cgets.c | 117 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 libsrc/conio/cgets.c diff --git a/include/conio.h b/include/conio.h index cf84d1742..1bf994511 100644 --- a/include/conio.h +++ b/include/conio.h @@ -110,6 +110,24 @@ char cgetc (void); ** 1 (see below), a blinking cursor is displayed while waiting. */ +char *cgets (char *buffer); +/* Get a string of characters directly from the console. The standard interface +** is quirky: +** +** - set buffer[0] to the size of the buffer - 2, must be > 0 +** - call cgets +** - buffer[1] will have the number of characters read +** - the actual string starts at buffer + 2 +** - trailing CRLF are removed +** - terminating \0 is appended +** - therefore the maximum number of characters which can be read is the size +** of the buffer - 3! +** +** param: buffer - where to save the input +** return: buffer + 2 (i.e. start of the string) if successful, NULL otherwise +** author: Russell-S-Harper +*/ + int cscanf (const char* format, ...); /* Like scanf(), but uses direct keyboard input */ diff --git a/libsrc/conio/cgets.c b/libsrc/conio/cgets.c new file mode 100644 index 000000000..c0f7f8e0c --- /dev/null +++ b/libsrc/conio/cgets.c @@ -0,0 +1,117 @@ +/* Created: 2025-06-15 Russell-S-Harper +** Modified: <iso-date> <author> +** Notes: <e.g. revisions made to support target, edge cases, bugs, etc.> +** +** char *cgets(char *buffer); +*/ + +#include <stddef.h> +#include <string.h> +#include <conio.h> + +#ifndef CRLF +#define CRLF "\r\n" +#endif /* CRLF */ + +enum {CGETS_SIZE, CGETS_READ, CGETS_DATA, CGETS_HDR_LEN = CGETS_DATA}; + +static char *cgetsx (char *buffer, int size); + +char *cgets (char *buffer) +/* Get a string of characters directly from the console. The standard interface +** is quirky: +** +** - set buffer[0] to the size of the buffer - 2, must be > 0 +** - call cgets +** - buffer[1] will have the number of characters read +** - the actual string starts at buffer + 2 +** - trailing CRLF are removed +** - terminating \0 is appended +** - therefore the maximum number of characters which can be read is the size +** of the buffer - 3! +** +** param: buffer - where to save the input +** return: buffer + 2 (or start of the string) if successful, NULL otherwise +** see: cgetsx for equivalent functionality but with a saner interface! +*/ +{ + /* Default to NULL */ + char *result = NULL; + + if (buffer && buffer[CGETS_SIZE]) { + /* Initialize just in case the caller didn't! */ + buffer[CGETS_READ] = 0; + buffer[CGETS_DATA] = '\0'; + + /* Call cgetsx to do the real work */ + result = cgetsx (buffer + CGETS_HDR_LEN, (unsigned char)buffer[CGETS_SIZE]); + + /* Trim trailing CRLF and set how many characters were read */ + if (result) { + result[strcspn (result, CRLF)] = '\0'; + buffer[CGETS_READ] = (unsigned char)strlen (result); + } + } + + /* Done */ + return result; +} + +static char *cgetsx (char *buffer, int size) +/* Like fgets but specifically for the console. Stops when CR/LF or size - 1 +** characters are read. Will append a terminating \0, so at most size - 1 +** characters can be read. Note that this function could be made public and +** have features like cursor vs no-cursor, and/or echo vs echo-pwd vs no-echo +** added to extend the functionality. +** +** param: buffer - where to save the input +** param: size - the size of buffer +** return: buffer if successful, NULL otherwise +*/ +{ + int i = 0; + unsigned char w, x, y; + char c; + + if (buffer && size > 1) { + /* Just need the width */ + screensize (&w, &y); + /* Actually just the last column! */ + --w; + cursor (1); + for (i = 0, --size; i < size; ) { + c = cgetc (); + /* Handle backspace */ + if (c == '\b') { + if (i > 0) { + /* Remove the character */ + buffer[--i] = '\0'; + /* Logic to account for line wrapping */ + y = wherey (); + x = wherex (); + y = x? y: y - 1; + x = x? x - 1: w; + /* Clear the character and the cursor */ + gotoxy (x, y); + cputs (" "); + gotoxy (x, y); + } + /* Handle CRLF */ + } else if (strchr (CRLF, c)) { + /* Clear the cursor and advance to the next line */ + cputs (" " CRLF); + buffer[i] = c; + buffer[++i] = '\0'; + break; + /* Handle regular characters */ + } else { + cputc (c); + buffer[i] = c; + buffer[++i] = '\0'; + } + } + cursor (0); + } + + return (i > 0)? buffer: NULL; +} From 2e27ee1702a3691731570ab1a2529ffb5cf2b8cb Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 16 Jun 2025 22:55:58 +0200 Subject: [PATCH 515/707] added .IFM740 and .PM470, and while at it also .IFP02X and .P02X. Updated regression test to use these --- src/ca65/condasm.c | 11 ++ src/ca65/pseudo.c | 199 ++++++++++++++----------- src/ca65/scanner.c | 3 + src/ca65/token.h | 3 + test/asm/cpudetect/6502x-cpudetect.ref | Bin 29 -> 31 bytes test/asm/cpudetect/cpudetect.s | 15 ++ 6 files changed, 142 insertions(+), 89 deletions(-) diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index 049367758..a65fbebba 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -394,6 +394,16 @@ void DoConditionals (void) CalcOverallIfCond (); break; + case TOK_IFP02X: + D = AllocIf (".IFP02X", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_6502X); + } + ExpectSep (); + CalcOverallIfCond (); + break; + case TOK_IFP4510: D = AllocIf (".IFP4510", 1); NextTok (); @@ -495,6 +505,7 @@ int CheckConditionals (void) case TOK_IFNDEF: case TOK_IFNREF: case TOK_IFP02: + case TOK_IFP02X: case TOK_IFP4510: case TOK_IFP816: case TOK_IFPC02: diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 2a14295ab..6cad9ed51 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1562,6 +1562,14 @@ static void DoP02 (void) +static void DoP02X (void) +/* Switch to 6502X CPU */ +{ + SetCPU (CPU_6502X); +} + + + static void DoPC02 (void) /* Switch to 65C02 CPU */ { @@ -1594,6 +1602,14 @@ static void DoPDTV (void) +static void DoPM740 (void) +/* Switch to M740 CPU */ +{ + SetCPU (CPU_M740); +} + + + static void DoPageLength (void) /* Set the page length for the listing */ { @@ -2057,70 +2073,72 @@ struct CtrlDesc { void (*Handler) (void); /* Command handler */ }; +/* NOTE: .AND, .BITAND, .BITNOT, .BITOR, .BITXOR, .MOD, .NOT, .OR, .SHL, .SHR + and .XOR do NOT go into this table */ #define PSEUDO_COUNT (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0])) static CtrlDesc CtrlCmdTab [] = { - { ccNone, DoA16 }, - { ccNone, DoA8 }, + { ccNone, DoA16 }, /* .A16 */ + { ccNone, DoA8 }, /* .A8 */ { ccNone, DoAddr }, /* .ADDR */ { ccNone, DoUnexpected }, /* .ADDRSIZE */ - { ccNone, DoAlign }, - { ccNone, DoASCIIZ }, + { ccNone, DoAlign }, /* .ALIGN */ + { ccNone, DoASCIIZ }, /* .ASCIIZ */ { ccNone, DoUnexpected }, /* .ASIZE */ - { ccNone, DoAssert }, - { ccNone, DoAutoImport }, + { ccNone, DoAssert }, /* .ASSERT */ + { ccNone, DoAutoImport }, /* .AUTOIMPORT */ { ccNone, DoUnexpected }, /* .BANK */ { ccNone, DoUnexpected }, /* .BANKBYTE */ - { ccNone, DoBankBytes }, + { ccNone, DoBankBytes }, /* .BANKBYTES */ { ccNone, DoUnexpected }, /* .BLANK */ - { ccNone, DoBss }, - { ccNone, DoByte }, - { ccNone, DoCase }, - { ccNone, DoCharMap }, - { ccNone, DoCode }, + { ccNone, DoBss }, /* .BSS */ + { ccNone, DoByte }, /* .BYT, .BYTE */ + { ccNone, DoCase }, /* .CASE */ + { ccNone, DoCharMap }, /* .CHARMAP */ + { ccNone, DoCode }, /* .CODE */ { ccNone, DoUnexpected, }, /* .CONCAT */ - { ccNone, DoConDes }, + { ccNone, DoConDes }, /* .CONDES */ { ccNone, DoUnexpected }, /* .CONST */ - { ccNone, DoConstructor }, + { ccNone, DoConstructor }, /* .CONSTRUCTOR */ { ccNone, DoUnexpected }, /* .CPU */ - { ccNone, DoData }, - { ccNone, DoDbg, }, - { ccNone, DoDByt }, - { ccNone, DoDebugInfo }, - { ccKeepToken, DoDefine }, + { ccNone, DoData }, /* .DATA */ + { ccNone, DoDbg, }, /* .DBG */ + { ccNone, DoDByt }, /* .DBYT */ + { ccNone, DoDebugInfo }, /* .DEBUGINFO */ + { ccKeepToken, DoDefine }, /* .DEF, .DEFINE */ { ccNone, DoUnexpected }, /* .DEFINED */ { ccNone, DoUnexpected }, /* .DEFINEDMACRO */ - { ccNone, DoDelMac }, - { ccNone, DoDestructor }, - { ccNone, DoDWord }, + { ccNone, DoDelMac }, /* .DELMAC, .DELMACRO */ + { ccNone, DoDestructor }, /* .DESTRUCTOR */ + { ccNone, DoDWord }, /* .DWORD */ { ccKeepToken, DoConditionals }, /* .ELSE */ { ccKeepToken, DoConditionals }, /* .ELSEIF */ - { ccKeepToken, DoEnd }, + { ccKeepToken, DoEnd }, /* .END */ { ccNone, DoUnexpected }, /* .ENDENUM */ { ccKeepToken, DoConditionals }, /* .ENDIF */ - { ccNone, DoUnexpected }, /* .ENDMACRO */ - { ccNone, DoEndProc }, - { ccNone, DoUnexpected }, /* .ENDREPEAT */ - { ccNone, DoEndScope }, + { ccNone, DoUnexpected }, /* .ENDMAC, .ENDMACRO */ + { ccNone, DoEndProc }, /* .ENDPROC */ + { ccNone, DoUnexpected }, /* .ENDREP, .ENDREPEAT */ + { ccNone, DoEndScope }, /* .ENDSCOPE */ { ccNone, DoUnexpected }, /* .ENDSTRUCT */ { ccNone, DoUnexpected }, /* .ENDUNION */ - { ccNone, DoEnum }, - { ccNone, DoError }, - { ccNone, DoExitMacro }, - { ccNone, DoExport }, - { ccNone, DoExportZP }, - { ccNone, DoFarAddr }, - { ccNone, DoFatal }, - { ccNone, DoFeature }, - { ccNone, DoFileOpt }, - { ccNone, DoForceImport }, + { ccNone, DoEnum }, /* .ENUM */ + { ccNone, DoError }, /* .ERROR */ + { ccNone, DoExitMacro }, /* .EXITMAC, .EXITMACRO */ + { ccNone, DoExport }, /* .EXPORT */ + { ccNone, DoExportZP }, /* .EXPORTZP */ + { ccNone, DoFarAddr }, /* .FARADDR */ + { ccNone, DoFatal }, /* .FATAL */ + { ccNone, DoFeature }, /* .FEATURE */ + { ccNone, DoFileOpt }, /* .FOPT, .FILEOPT */ + { ccNone, DoForceImport }, /* .FORCEIMPORT */ { ccNone, DoUnexpected }, /* .FORCEWORD */ - { ccNone, DoGlobal }, - { ccNone, DoGlobalZP }, + { ccNone, DoGlobal }, /* .GLOBAL */ + { ccNone, DoGlobalZP }, /* .GLOBALZP */ { ccNone, DoUnexpected }, /* .HIBYTE */ - { ccNone, DoHiBytes }, + { ccNone, DoHiBytes }, /* .HIBYTES */ { ccNone, DoUnexpected }, /* .HIWORD */ - { ccNone, DoI16 }, - { ccNone, DoI8 }, + { ccNone, DoI16 }, /* .I16 */ + { ccNone, DoI8 }, /* .I8 */ { ccNone, DoUnexpected }, /* .IDENT */ { ccKeepToken, DoConditionals }, /* .IF */ { ccKeepToken, DoConditionals }, /* .IFBLANK */ @@ -2131,6 +2149,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccKeepToken, DoConditionals }, /* .IFNDEF */ { ccKeepToken, DoConditionals }, /* .IFNREF */ { ccKeepToken, DoConditionals }, /* .IFP02 */ + { ccKeepToken, DoConditionals }, /* .IFP02X */ { ccKeepToken, DoConditionals }, /* .IFP4510 */ { ccKeepToken, DoConditionals }, /* .IFP816 */ { ccKeepToken, DoConditionals }, /* .IFPC02 */ @@ -2138,75 +2157,77 @@ static CtrlDesc CtrlCmdTab [] = { { ccKeepToken, DoConditionals }, /* .IFPM740 */ { ccKeepToken, DoConditionals }, /* .IFPSC02 */ { ccKeepToken, DoConditionals }, /* .IFREF */ - { ccNone, DoImport }, - { ccNone, DoImportZP }, - { ccNone, DoIncBin }, - { ccNone, DoInclude }, - { ccNone, DoInterruptor }, + { ccNone, DoImport }, /* .IMPORT */ + { ccNone, DoImportZP }, /* .IMPORTZP */ + { ccNone, DoIncBin }, /* .INCBIN */ + { ccNone, DoInclude }, /* .INCLUDE */ + { ccNone, DoInterruptor }, /* .INTERRUPTPOR */ { ccNone, DoUnexpected }, /* .ISIZE */ { ccNone, DoUnexpected }, /* .ISMNEMONIC */ { ccNone, DoInvalid }, /* .LEFT */ - { ccNone, DoLineCont }, - { ccNone, DoList }, - { ccNone, DoListBytes }, - { ccNone, DoLiteral }, + { ccNone, DoLineCont }, /* .LINECONT */ + { ccNone, DoList }, /* .LIST */ + { ccNone, DoListBytes }, /* .LISTBYTES */ + { ccNone, DoLiteral }, /* .LITERAL */ { ccNone, DoUnexpected }, /* .LOBYTE */ - { ccNone, DoLoBytes }, + { ccNone, DoLoBytes }, /* .LOBYTES */ { ccNone, DoUnexpected }, /* .LOCAL */ - { ccNone, DoLocalChar }, + { ccNone, DoLocalChar }, /* .LOCALCHAR */ { ccNone, DoUnexpected }, /* .LOWORD */ - { ccNone, DoMacPack }, - { ccNone, DoMacro }, + { ccNone, DoMacPack }, /* .MACPACK */ + { ccNone, DoMacro }, /* .MAC, .MACRO */ { ccNone, DoUnexpected }, /* .MATCH */ { ccNone, DoUnexpected }, /* .MAX */ { ccNone, DoInvalid }, /* .MID */ { ccNone, DoUnexpected }, /* .MIN */ - { ccNone, DoNull }, - { ccNone, DoOrg }, - { ccNone, DoOut }, - { ccNone, DoP02 }, - { ccNone, DoP4510 }, - { ccNone, DoP816 }, - { ccNone, DoPageLength }, + { ccNone, DoNull }, /* .NULL */ + { ccNone, DoOrg }, /* .ORG */ + { ccNone, DoOut }, /* .OUT */ + { ccNone, DoP02 }, /* .P02 */ + { ccNone, DoP02X }, /* .P02X */ + { ccNone, DoP4510 }, /* .P4510 */ + { ccNone, DoP816 }, /* .P816 */ + { ccNone, DoPageLength }, /* .PAGELEN, .PAGELENGTH */ { ccNone, DoUnexpected }, /* .PARAMCOUNT */ - { ccNone, DoPC02 }, - { ccNone, DoPDTV }, - { ccNone, DoPopCharmap }, - { ccNone, DoPopCPU }, - { ccNone, DoPopSeg }, - { ccNone, DoProc }, - { ccNone, DoPSC02 }, - { ccNone, DoPushCharmap }, - { ccNone, DoPushCPU }, - { ccNone, DoPushSeg }, - { ccNone, DoUnexpected }, /* .REFERENCED */ - { ccNone, DoReferTo }, /* .REFERTO */ - { ccNone, DoReloc }, - { ccNone, DoRepeat }, - { ccNone, DoRes }, + { ccNone, DoPC02 }, /* .PSC02 */ + { ccNone, DoPDTV }, /* .PDTV */ + { ccNone, DoPM740 }, /* .PM740 */ + { ccNone, DoPopCharmap }, /* .POPCHARMAP */ + { ccNone, DoPopCPU }, /* .POPCPU */ + { ccNone, DoPopSeg }, /* .POPSEG */ + { ccNone, DoProc }, /* .PROC */ + { ccNone, DoPSC02 }, /* .PSC02 */ + { ccNone, DoPushCharmap }, /* .PUSHCHARMAP */ + { ccNone, DoPushCPU }, /* .PUSHCPU */ + { ccNone, DoPushSeg }, /* .PUSHSEG */ + { ccNone, DoUnexpected }, /* .REF, .REFERENCED */ + { ccNone, DoReferTo }, /* .REFTO, .REFERTO */ + { ccNone, DoReloc }, /* .RELOC */ + { ccNone, DoRepeat }, /* .REPEAT */ + { ccNone, DoRes }, /* .RES */ { ccNone, DoInvalid }, /* .RIGHT */ - { ccNone, DoROData }, - { ccNone, DoScope }, - { ccNone, DoSegment }, + { ccNone, DoROData }, /* .RODATA */ + { ccNone, DoScope }, /* .SCOPE */ + { ccNone, DoSegment }, /* .SEGMENT */ { ccNone, DoUnexpected }, /* .SET */ - { ccNone, DoSetCPU }, + { ccNone, DoSetCPU }, /* .SETCPU */ { ccNone, DoUnexpected }, /* .SIZEOF */ - { ccNone, DoSmart }, + { ccNone, DoSmart }, /* .SMART */ { ccNone, DoUnexpected }, /* .SPRINTF */ { ccNone, DoUnexpected }, /* .STRAT */ { ccNone, DoUnexpected }, /* .STRING */ { ccNone, DoUnexpected }, /* .STRLEN */ - { ccNone, DoStruct }, - { ccNone, DoTag }, + { ccNone, DoStruct }, /* .STRUCT */ + { ccNone, DoTag }, /* .TAG */ { ccNone, DoUnexpected }, /* .TCOUNT */ { ccNone, DoUnexpected }, /* .TIME */ - { ccKeepToken, DoUnDef }, - { ccNone, DoUnion }, + { ccKeepToken, DoUnDef }, /* .UNDEF, .UNDEFINE */ + { ccNone, DoUnion }, /* .UNION */ { ccNone, DoUnexpected }, /* .VERSION */ - { ccNone, DoWarning }, - { ccNone, DoWord }, + { ccNone, DoWarning }, /* .WARNING */ + { ccNone, DoWord }, /* .WORD */ { ccNone, DoUnexpected }, /* .XMATCH */ - { ccNone, DoZeropage }, + { ccNone, DoZeropage }, /* .ZEROPAGE */ }; diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index f93ae977e..0d90ddc7f 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -221,6 +221,7 @@ struct DotKeyword { { ".IFNDEF", TOK_IFNDEF }, { ".IFNREF", TOK_IFNREF }, { ".IFP02", TOK_IFP02 }, + { ".IFP02X", TOK_IFP02X }, { ".IFP4510", TOK_IFP4510 }, { ".IFP816", TOK_IFP816 }, { ".IFPC02", TOK_IFPC02 }, @@ -260,6 +261,7 @@ struct DotKeyword { { ".ORG", TOK_ORG }, { ".OUT", TOK_OUT }, { ".P02", TOK_P02 }, + { ".P02X", TOK_P02X }, { ".P4510", TOK_P4510 }, { ".P816", TOK_P816 }, { ".PAGELEN", TOK_PAGELENGTH }, @@ -267,6 +269,7 @@ struct DotKeyword { { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, { ".PDTV", TOK_PDTV }, + { ".PM740", TOK_PM740 }, { ".POPCHARMAP", TOK_POPCHARMAP }, { ".POPCPU", TOK_POPCPU }, { ".POPSEG", TOK_POPSEG }, diff --git a/src/ca65/token.h b/src/ca65/token.h index a29c6e5ab..d4fa3a697 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -193,6 +193,7 @@ typedef enum token_t { TOK_IFNDEF, TOK_IFNREF, TOK_IFP02, + TOK_IFP02X, TOK_IFP4510, TOK_IFP816, TOK_IFPC02, @@ -227,12 +228,14 @@ typedef enum token_t { TOK_ORG, TOK_OUT, TOK_P02, + TOK_P02X, TOK_P4510, TOK_P816, TOK_PAGELENGTH, TOK_PARAMCOUNT, TOK_PC02, TOK_PDTV, + TOK_PM740, TOK_POPCHARMAP, TOK_POPCPU, TOK_POPSEG, diff --git a/test/asm/cpudetect/6502x-cpudetect.ref b/test/asm/cpudetect/6502x-cpudetect.ref index 3434ecbea7fb1e119879fae346989933fd09bacd..9e7abe573ffc65dce67d2b8b95d1c3ef9827bd71 100644 GIT binary patch delta 7 Ocmb1@XIlMgf-C?CJpzFM literal 29 ZcmZQ@4hW6+40a8PH#0RbVnE?V0042#2dMx6 diff --git a/test/asm/cpudetect/cpudetect.s b/test/asm/cpudetect/cpudetect.s index d4d5b9f9f..cf2f5cb26 100644 --- a/test/asm/cpudetect/cpudetect.s +++ b/test/asm/cpudetect/cpudetect.s @@ -8,6 +8,10 @@ lda #$ea .endif +.ifp02X + lax #$ea +.endif + .ifpsc02 jmp ($1234,x) .endif @@ -80,3 +84,14 @@ .byte 0,"CPU_ISET_M740" .endif + +; step 3: switch through all supported cpus to verify the pseudo-op is there + +.p02 +.p02X +.psc02 +.pc02 +.p816 +.p4510 +.pdtv +.pm740 From ed86cb84f9cf4a8a73f94b5e8b37987f2751c434 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:10:49 +0200 Subject: [PATCH 516/707] slightly updated docs --- doc/ca65.sgml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 80224a84e..4e449d8e5 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -152,7 +152,7 @@ Here is a description of all the command line options: Set the default for the CPU type. The option takes a parameter, which may be one of - 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510 + 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510, m740 <label id="option-create-dep"> @@ -440,6 +440,8 @@ The assembler accepts <tt><ref id=".P816" name=".P816"></tt> command was given). <item>all valid 4510 mnemonics when in 4510 mode (after the <tt><ref id=".P4510" name=".P4510"></tt> command was given). +<item>all valid M740 mnemonics when in M740 mode (after the + <tt><ref id=".PM740" name=".PM740"></tt> command was given). </itemize> On 6502-derived platforms the <tt/BRK/ instruction has an optional signature @@ -529,6 +531,15 @@ For more information about the Commodore C65/C64DX and the 4510 CPU, see <url url="https://en.wikipedia.org/wiki/Commodore_65" name="Wikipedia">. +<sect1>M740 mode<p> + +The M740 is a microcontroller by Mitsubishi, which was marketed for embedded +devices in the mid 80s. + +For more information about the M740 Controllers, see +<url url="https://en.wikipedia.org/wiki/Mitsubishi_740" name="Wikipedia">. + + <sect1>sweet16 mode<label id="sweet16-mode"><p> SWEET 16 is an interpreter for a pseudo 16 bit CPU written by Steve Wozniak @@ -4012,18 +4023,22 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" Switch the CPU instruction set. The command is followed by a string that specifies the CPU. Possible values are those that can also be supplied to the <tt><ref id="option--cpu" name="--cpu"></tt> command line option, - namely: 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, 4510 and HuC6280. + namely: 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, 4510, HuC6280 and m740. See: <tt><ref id=".CPU" name=".CPU"></tt>, <tt><ref id=".IFP02" name=".IFP02"></tt>, + <tt><ref id=".IFP02X" name=".IFP02"></tt>, <tt><ref id=".IFPDTV" name=".IFPDTV"></tt>, <tt><ref id=".IFP816" name=".IFP816"></tt>, <tt><ref id=".IFPC02" name=".IFPC02"></tt>, + <tt><ref id=".IFPM740" name=".IFPM740"></tt>, <tt><ref id=".IFPSC02" name=".IFPSC02"></tt>, <tt><ref id=".P02" name=".P02"></tt>, + <tt><ref id=".P02X" name=".P02"></tt>, <tt><ref id=".P816" name=".P816"></tt>, <tt><ref id=".P4510" name=".P4510"></tt>, <tt><ref id=".PC02" name=".PC02"></tt>, + <tt><ref id=".PM740" name=".PM740"></tt>, <tt><ref id=".PSC02" name=".PSC02"></tt> From 476abbddd1f02a84f0fa9abfa51bd76d9fd08e0e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:26:47 +0200 Subject: [PATCH 517/707] update/fix doc nodes --- doc/ca65.sgml | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 4e449d8e5..3324131b4 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3245,6 +3245,12 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH (see <tt><ref id=".P02" name=".P02"></tt> command). +<sect1><tt>.IFP02X</tt><label id=".IFP02X"><p> + + Conditional assembly: Check if the assembler is currently in 6502X mode + (see <tt><ref id=".P02X" name=".P02X"></tt> command). + + <sect1><tt>.IFP4510</tt><label id=".IFP4510"><p> Conditional assembly: Check if the assembler is currently in 4510 mode @@ -3269,6 +3275,12 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH (see <tt><ref id=".PDTV" name=".PDTV"></tt> command). +<sect1><tt>.IFPM740</tt><label id=".IFPM740"><p> + + Conditional assembly: Check if the assembler is currently in M740 mode + (see <tt><ref id=".PM740" name=".PM740"></tt> command). + + <sect1><tt>.IFPSC02</tt><label id=".IFPSC02"><p> Conditional assembly: Check if the assembler is currently in 65SC02 mode @@ -3632,6 +3644,16 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" <tt><ref id=".P4510" name=".P4510"></tt> +<sect1><tt>.P02X</tt><label id=".P02X"><p> + + Enable the 6502X instruction set, disable 65SC02, 65C02 and 65816 + instructions. + + See: <tt><ref id=".PC02" name=".PC02"></tt>, <tt><ref id=".PSC02" + name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt> and + <tt><ref id=".P4510" name=".P4510"></tt> + + <sect1><tt>.P4510</tt><label id=".P4510"><p> Enable the 4510 instruction set. This is a superset of the 65C02 and @@ -3689,6 +3711,14 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" See: <tt><ref id=".P02" name=".P02"></tt> +<sect1><tt>.PM740</tt><label id=".PM740"><p> + + Enable the M740 instruction set. This is a superset of the 6502 + instruction set. + + See: <tt><ref id=".P02" name=".P02"></tt> + + <sect1><tt>.POPCHARMAP</tt><label id=".POPCHARMAP"><p> Pop the last character mapping from the stack, and activate it. @@ -4027,14 +4057,14 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" See: <tt><ref id=".CPU" name=".CPU"></tt>, <tt><ref id=".IFP02" name=".IFP02"></tt>, - <tt><ref id=".IFP02X" name=".IFP02"></tt>, + <tt><ref id=".IFP02X" name=".IFP02X"></tt>, <tt><ref id=".IFPDTV" name=".IFPDTV"></tt>, <tt><ref id=".IFP816" name=".IFP816"></tt>, <tt><ref id=".IFPC02" name=".IFPC02"></tt>, <tt><ref id=".IFPM740" name=".IFPM740"></tt>, <tt><ref id=".IFPSC02" name=".IFPSC02"></tt>, <tt><ref id=".P02" name=".P02"></tt>, - <tt><ref id=".P02X" name=".P02"></tt>, + <tt><ref id=".P02X" name=".P02X"></tt>, <tt><ref id=".P816" name=".P816"></tt>, <tt><ref id=".P4510" name=".P4510"></tt>, <tt><ref id=".PC02" name=".PC02"></tt>, From 7ea6575ca892fd82fc94af480c6fe6eab47177f5 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:35:51 +0200 Subject: [PATCH 518/707] update cpu list on da65 page too --- doc/da65.sgml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index 94fbfbd29..b72cd9b66 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -118,11 +118,13 @@ Here is a description of all the command line options: <item>65816 <item>huc6280 <item>4510 + <item>m740 </itemize> 6502x is for the NMOS 6502 with unofficial opcodes. 6502dtv is for the emulated CPU of the C64DTV device. huc6280 is the CPU of the PC engine. - 4510 is the CPU of the Commodore C65. 65816 is the CPU of the SNES. + 4510 is the CPU of the Commodore C65. 65816 is the CPU of the SNES. M740 is a + Microcontroller by Mitsubishi. <label id="option--formfeeds"> From c90c61f08f74abc1d164d926e48a13b130fd2d91 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Mon, 16 Jun 2025 23:30:46 +0000 Subject: [PATCH 519/707] rename functions --- src/cc65/error.c | 22 +++++++++++----------- src/cc65/error.h | 44 ++++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/cc65/error.c b/src/cc65/error.c index 90577c0ad..ae2d6f27d 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -184,7 +184,7 @@ static unsigned GetDiagnosticLineNum (void) -void _Fatal (const char *file, int line, const char* Format, ...) +void Fatal_ (const char *file, int line, const char* Format, ...) /* Print a message about a fatal error and die */ { va_list ap; @@ -208,7 +208,7 @@ void _Fatal (const char *file, int line, const char* Format, ...) -void _Internal (const char *file, int line, const char* Format, ...) +void Internal_ (const char *file, int line, const char* Format, ...) /* Print a message about an internal compiler error and die */ { va_list ap; @@ -279,7 +279,7 @@ static void IntError (errcat_t EC, LineInfo* LI, const char* Msg, va_list ap) -void _LIError (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) +void LIError_ (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) /* Print an error message with the line info given explicitly */ { va_list ap; @@ -295,7 +295,7 @@ void _LIError (const char *file, int line, errcat_t EC, LineInfo* LI, const char -void _Error (const char *file, int line, const char* Format, ...) +void Error_ (const char *file, int line, const char* Format, ...) /* Print an error message */ { va_list ap; @@ -311,7 +311,7 @@ void _Error (const char *file, int line, const char* Format, ...) -void _PPError (const char *file, int line, const char* Format, ...) +void PPError_ (const char *file, int line, const char* Format, ...) /* Print an error message. For use within the preprocessor */ { va_list ap; @@ -370,7 +370,7 @@ static void IntWarning (errcat_t EC, LineInfo* LI, const char* Msg, va_list ap) -void _LIWarning (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) +void LIWarning_ (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) /* Print a warning message with the line info given explicitly */ { va_list ap; @@ -386,7 +386,7 @@ void _LIWarning (const char *file, int line, errcat_t EC, LineInfo* LI, const ch -void _Warning (const char *file, int line, const char* Format, ...) +void Warning_ (const char *file, int line, const char* Format, ...) /* Print a warning message */ { va_list ap; @@ -402,7 +402,7 @@ void _Warning (const char *file, int line, const char* Format, ...) -void _PPWarning (const char *file, int line, const char* Format, ...) +void PPWarning_ (const char *file, int line, const char* Format, ...) /* Print a warning message. For use within the preprocessor */ { va_list ap; @@ -475,7 +475,7 @@ static void IntNote (const LineInfo* LI, const char* Msg, va_list ap) -void _LINote (const char *file, int line, const LineInfo* LI, const char* Format, ...) +void LINote_ (const char *file, int line, const LineInfo* LI, const char* Format, ...) /* Print a note message with the line info given explicitly */ { va_list ap; @@ -491,7 +491,7 @@ void _LINote (const char *file, int line, const LineInfo* LI, const char* Format -void _Note (const char *file, int line, const char* Format, ...) +void Note_ (const char *file, int line, const char* Format, ...) /* Print a note message */ { va_list ap; @@ -507,7 +507,7 @@ void _Note (const char *file, int line, const char* Format, ...) -void _PPNote (const char *file, int line, const char* Format, ...) +void PPNote_ (const char *file, int line, const char* Format, ...) /* Print a note message. For use within the preprocessor */ { va_list ap; diff --git a/src/cc65/error.h b/src/cc65/error.h index 63158b3bd..0a18d51a4 100644 --- a/src/cc65/error.h +++ b/src/cc65/error.h @@ -103,36 +103,36 @@ struct StrBuf; void PrintFileInclusionInfo (const LineInfo* LI); /* Print hierarchy of file inclusion */ -void _Fatal (const char *file, int line, const char* Format, ...) attribute ((noreturn, format (printf, 3, 4))); -#define Fatal(...) _Fatal(__FILE__, __LINE__, __VA_ARGS__) +void Fatal_ (const char *file, int line, const char* Format, ...) attribute ((noreturn, format (printf, 3, 4))); +#define Fatal(...) Fatal_(__FILE__, __LINE__, __VA_ARGS__) /* Print a message about a fatal error and die */ -void _Internal (const char *file, int line, const char* Format, ...) attribute ((noreturn, format (printf, 3, 4))); -#define Internal(...) _Internal(__FILE__, __LINE__, __VA_ARGS__) +void Internal_ (const char *file, int line, const char* Format, ...) attribute ((noreturn, format (printf, 3, 4))); +#define Internal(...) Internal_(__FILE__, __LINE__, __VA_ARGS__) /* Print a message about an internal compiler error and die */ -void _Error (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); -#define Error(...) _Error(__FILE__, __LINE__, __VA_ARGS__) +void Error_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define Error(...) Error_(__FILE__, __LINE__, __VA_ARGS__) /* Print an error message */ -void _LIError (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__) +void LIError_ (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 5, 6))); +#define LIError(...) LIError_(__FILE__, __LINE__, __VA_ARGS__) /* Print an error message with the line info given explicitly */ -void _PPError (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); -#define PPError(...) _PPError(__FILE__, __LINE__, __VA_ARGS__) +void PPError_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define PPError(...) PPError_(__FILE__, __LINE__, __VA_ARGS__) /* Print an error message. For use within the preprocessor */ -void _Warning (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); -#define Warning(...) _Warning(__FILE__, __LINE__, __VA_ARGS__) +void Warning_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define Warning(...) Warning_(__FILE__, __LINE__, __VA_ARGS__) /* Print a warning message */ -void _LIWarning (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__) +void LIWarning_ (const char *file, int line, errcat_t EC, LineInfo* LI, const char* Format, ...) attribute ((format (printf, 5, 6))); +#define LIWarning(...) LIWarning_(__FILE__, __LINE__, __VA_ARGS__) /* Print a warning message with the line info given explicitly */ -void _PPWarning (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); -#define PPWarning(...) _PPWarning(__FILE__, __LINE__, __VA_ARGS__) +void PPWarning_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define PPWarning(...) PPWarning_(__FILE__, __LINE__, __VA_ARGS__) /* Print a warning message. For use within the preprocessor */ void UnreachableCodeWarning (void); @@ -148,16 +148,16 @@ IntStack* FindWarning (const char* Name); void ListWarnings (FILE* F); /* Print a list of warning types/names to the given file */ -void _Note (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); -#define Note(...) _Note(__FILE__, __LINE__, __VA_ARGS__) +void Note_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define Note(...) Note_(__FILE__, __LINE__, __VA_ARGS__) /* Print a note message */ -void _LINote (const char *file, int line, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 4, 5))); -#define LINote(...) _LINote(__FILE__, __LINE__, __VA_ARGS__) +void LINote_ (const char *file, int line, const LineInfo* LI, const char* Format, ...) attribute ((format (printf, 4, 5))); +#define LINote(...) LINote_(__FILE__, __LINE__, __VA_ARGS__) /* Print a note message with the line info given explicitly */ -void _PPNote (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); -#define PPNote(...) _PPNote(__FILE__, __LINE__, __VA_ARGS__) +void PPNote_ (const char *file, int line, const char* Format, ...) attribute ((format (printf, 3, 4))); +#define PPNote(...) PPNote_(__FILE__, __LINE__, __VA_ARGS__) /* Print a note message. For use within the preprocessor */ unsigned GetTotalErrors (void); From bae58ae419d369a140e275009fe991b11a978f4d Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Tue, 17 Jun 2025 20:29:01 +0200 Subject: [PATCH 520/707] Update cbm264.h - fix misunderstanding about TGI colors --- include/cbm264.h | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/include/cbm264.h b/include/cbm264.h index 82ecdc4d8..c220bf407 100644 --- a/include/cbm264.h +++ b/include/cbm264.h @@ -110,25 +110,23 @@ #define COLOR_LIGHTBLUE (BCOLOR_LIGHTBLUE | CATTR_LUMA7) #define COLOR_GRAY3 (BCOLOR_WHITE | CATTR_LUMA5) -/* TGI color defines (these are indices into the default palette) */ -#define TGI_COLOR_BLACK 0 -#define TGI_COLOR_WHITE 1 -/* -#define TGI_COLOR_RED 2 -#define TGI_COLOR_CYAN 3 -#define TGI_COLOR_PURPLE 4 -#define TGI_COLOR_GREEN 5 -#define TGI_COLOR_BLUE 6 -#define TGI_COLOR_YELLOW 7 -#define TGI_COLOR_ORANGE 8 -#define TGI_COLOR_BROWN 9 -#define TGI_COLOR_LIGHTRED 10 -#define TGI_COLOR_GRAY1 11 -#define TGI_COLOR_GRAY2 12 -#define TGI_COLOR_LIGHTGREEN 13 -#define TGI_COLOR_LIGHTBLUE 14 -#define TGI_COLOR_GRAY3 15 -*/ +/* TGI color defines */ +#define TGI_COLOR_BLACK (BCOLOR_BLACK) +#define TGI_COLOR_WHITE (BCOLOR_WHITE | CATTR_LUMA7) +#define TGI_COLOR_RED (BCOLOR_RED | CATTR_LUMA4) +#define TGI_COLOR_CYAN (BCOLOR_CYAN | CATTR_LUMA7) +#define TGI_COLOR_PURPLE (BCOLOR_LIGHTVIOLET | CATTR_LUMA7) +#define TGI_COLOR_GREEN (BCOLOR_GREEN | CATTR_LUMA7) +#define TGI_COLOR_BLUE (BCOLOR_BLUE | CATTR_LUMA7) +#define TGI_COLOR_YELLOW (BCOLOR_YELLOW | CATTR_LUMA7) +#define TGI_COLOR_ORANGE (BCOLOR_ORANGE | CATTR_LUMA7) +#define TGI_COLOR_BROWN (BCOLOR_BROWN | CATTR_LUMA7) +#define TGI_COLOR_LIGHTRED (BCOLOR_RED | CATTR_LUMA7) +#define TGI_COLOR_GRAY1 (BCOLOR_WHITE | CATTR_LUMA1) +#define TGI_COLOR_GRAY2 (BCOLOR_WHITE | CATTR_LUMA3) +#define TGI_COLOR_LIGHTGREEN (BCOLOR_LIGHTGREEN | CATTR_LUMA7) +#define TGI_COLOR_LIGHTBLUE (BCOLOR_LIGHTBLUE | CATTR_LUMA7) +#define TGI_COLOR_GRAY3 (BCOLOR_WHITE | CATTR_LUMA5) /* Masks for joy_read */ #define JOY_UP_MASK 0x01 From 0b0bead6348b8e03cbe47fe3a57861676895dd5d Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Tue, 17 Jun 2025 20:29:41 +0200 Subject: [PATCH 521/707] Update tgidemo.c - fix misunderstanding about TGI colors --- samples/tgidemo.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/samples/tgidemo.c b/samples/tgidemo.c index 132697182..cdb4c3ad9 100644 --- a/samples/tgidemo.c +++ b/samples/tgidemo.c @@ -13,10 +13,9 @@ #endif -/* TGI colors are indices into the default palette. So keep in mind that, if - you redefine the palette, those names may no more match the actual colors. */ -#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 /*****************************************************************************/ @@ -69,35 +68,30 @@ static void DoWarning (void) /* - * Note that everywhere else in the TGI API, colors are referred to via TGI_COLOR_ - * color indices, which in turn refer to the default TGI palette. + * Note that everywhere else in the TGI API, colors are referred to via an index + * to the current palette. * - * Redefining the colors (changing the palette) is a target dependend operation, - * and the colors/values in the palette itself are not portable. - * - * That said, for some (perhaps most?) targets, the COLOR_ values may work here. + * 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__) - { COLOR_BLACK, COLOR_BLUE }, - { COLOR_WHITE, COLOR_BLACK }, - { COLOR_RED, COLOR_BLACK }, - { COLOR_BLACK, COLOR_WHITE } + { TGI_COLOR_BLACK, TGI_COLOR_BLUE }, + { TGI_COLOR_WHITE, TGI_COLOR_BLACK }, + { TGI_COLOR_RED, TGI_COLOR_BLACK }, #else - { COLOR_WHITE, COLOR_BLACK }, - { COLOR_BLACK, COLOR_WHITE }, - { COLOR_WHITE, COLOR_BLACK }, - { COLOR_BLACK, COLOR_WHITE } + { 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) { unsigned char I; @@ -117,7 +111,9 @@ static void DoCircles (void) tgi_ellipse (X, Y, I, tgi_imulround (I, AspectRatio)); } } - + while (kbhit ()) { + cgetc (); + } cgetc (); } @@ -186,6 +182,9 @@ static void DoDiagram (void) tgi_lineto (XOrigin + X, YOrigin + Y); } + while (kbhit ()) { + cgetc (); + } cgetc (); } @@ -206,6 +205,9 @@ static void DoLines (void) tgi_line (Min, Min, Min-X, 0); } + while (kbhit ()) { + cgetc (); + } cgetc (); } @@ -241,8 +243,7 @@ int main (void) /* Do graphics stuff */ - /* first uses the default palette */ - DoCircles (); + /* use default palette */ DoCircles (); DoPalette (0); DoCheckerboard (); DoPalette (1); DoDiagram (); DoPalette (2); DoLines (); From 55742003d63664c47b0dab179a0e7c3f0e8a1414 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 17 Jun 2025 21:40:04 +0200 Subject: [PATCH 522/707] add some more comments --- include/tgi.h | 9 +++++---- libsrc/apple2/tgi_colors.s | 1 + libsrc/common/tgi_colors.s | 1 + libsrc/lynx/tgi_colors.s | 1 + libsrc/tgi/tgi-kernel.s | 2 +- libsrc/tgi/tgi_getcolor.s | 2 +- libsrc/tgi/tgi_setcolor.s | 4 ++-- 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/tgi.h b/include/tgi.h index 2ef65b856..ecd98e6e8 100644 --- a/include/tgi.h +++ b/include/tgi.h @@ -141,15 +141,16 @@ unsigned char tgi_getmaxcolor (void); ** then be getmaxcolor()+1). */ -void __fastcall__ tgi_setcolor (unsigned char color); -/* Set the current drawing color. */ +void __fastcall__ tgi_setcolor (unsigned char color_index); +/* Set the current drawing color (palette index). */ unsigned char tgi_getcolor (void); -/* Return the current drawing color. */ +/* Return the current drawing color (palette index). */ void __fastcall__ tgi_setpalette (const unsigned char* palette); /* Set the palette (not available with all drivers/hardware). palette is -** a pointer to as many entries as there are colors. +** a pointer to as many entries as there are colors required for the drivers +** palette. This palette is the (only) place where to use the TGI_COLOR values. */ const unsigned char* tgi_getpalette (void); diff --git a/libsrc/apple2/tgi_colors.s b/libsrc/apple2/tgi_colors.s index 53505b33d..936d89b76 100644 --- a/libsrc/apple2/tgi_colors.s +++ b/libsrc/apple2/tgi_colors.s @@ -1,6 +1,7 @@ ; ; Target-specific black & white values for use by the target-shared TGI kernel ; +; NOTE: These are indices into the default palette .include "tgi-kernel.inc" diff --git a/libsrc/common/tgi_colors.s b/libsrc/common/tgi_colors.s index 6ef3729b4..ba14ffa09 100644 --- a/libsrc/common/tgi_colors.s +++ b/libsrc/common/tgi_colors.s @@ -1,6 +1,7 @@ ; ; Target-specific black & white values for use by the target-shared TGI kernel ; +; NOTE: These are indices into the default palette .include "tgi-kernel.inc" diff --git a/libsrc/lynx/tgi_colors.s b/libsrc/lynx/tgi_colors.s index ebc8c2889..6d0ea442a 100644 --- a/libsrc/lynx/tgi_colors.s +++ b/libsrc/lynx/tgi_colors.s @@ -1,6 +1,7 @@ ; ; Target-specific black & white values for use by the target-shared TGI kernel ; +; NOTE: These are indices into the default palette .include "tgi-kernel.inc" diff --git a/libsrc/tgi/tgi-kernel.s b/libsrc/tgi/tgi-kernel.s index cbd655279..c2d87b002 100644 --- a/libsrc/tgi/tgi-kernel.s +++ b/libsrc/tgi/tgi-kernel.s @@ -23,7 +23,7 @@ _tgi_error: .res 1 ; Last error code _tgi_gmode: .res 1 ; Flag: Graphics mode active _tgi_curx: .res 2 ; Current drawing cursor X _tgi_cury: .res 2 ; Current drawing cursor Y -_tgi_color: .res 1 ; Current drawing color +_tgi_color: .res 1 ; Current drawing color (palette index) _tgi_font: .res 1 ; Which font to use _tgi_textdir: .res 1 ; Current text direction _tgi_vectorfont: .res 2 ; Pointer to vector font diff --git a/libsrc/tgi/tgi_getcolor.s b/libsrc/tgi/tgi_getcolor.s index c1c0022d0..95cf7d553 100644 --- a/libsrc/tgi/tgi_getcolor.s +++ b/libsrc/tgi/tgi_getcolor.s @@ -2,7 +2,7 @@ ; Ullrich von Bassewitz, 22.06.2002 ; ; unsigned char tgi_getcolor (void); -; /* Return the current drawing color */ +; /* Return the current drawing color (palette index) */ .include "tgi-kernel.inc" diff --git a/libsrc/tgi/tgi_setcolor.s b/libsrc/tgi/tgi_setcolor.s index 16f075767..6f3bb1871 100644 --- a/libsrc/tgi/tgi_setcolor.s +++ b/libsrc/tgi/tgi_setcolor.s @@ -2,8 +2,8 @@ ; 2002-06-21, Ullrich von Bassewitz ; 2020-06-04, Greg King ; -; void __fastcall__ tgi_setcolor (unsigned char color); -; /* Set the current drawing color */ +; void __fastcall__ tgi_setcolor (unsigned char color_index); +; /* Set the current drawing color (palette index) */ .include "tgi-kernel.inc" From 9edc396ce712e010392dc2ef60e39c846338e0fd Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 17 Jun 2025 22:27:47 +0200 Subject: [PATCH 523/707] fix TGI docs a bit --- doc/tgi.sgml | 56 ++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index 3b013664f..182ce2807 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -43,7 +43,7 @@ of range. <ref id="tgi_setcolor" name="tgi_setcolor"> <tag/Example/<tscreen><verb> /* Draw the upper half of an ellipse */ -tgi_setcolor(TGI_COLOR_BLUE); +tgi_setcolor(1); tgi_arc (50, 50, 40, 20, 0, 180); </verb></tscreen> </descrip> @@ -67,7 +67,7 @@ be used in presence of a prototype. <tag/Availability/cc65 <tag/See also/Other tgi function <tag/Example/<tscreen><verb> -tgi_setcolor(TGI_COLOR_GREEN); +tgi_setcolor(1); tgi_bar(10, 10, 100, 60); </verb></tscreen> </descrip> @@ -94,7 +94,7 @@ be used in presence of a prototype. <ref id="tgi_pieslice" name="tgi_pieslice">, <ref id="tgi_setcolor" name="tgi_setcolor"> <tag/Example/<tscreen><verb> -tgi_setcolor(TGI_COLOR_BLACK); +tgi_setcolor(1); tgi_circle(50, 40, 40); </verb></tscreen> </descrip> @@ -154,7 +154,7 @@ be used in presence of a prototype. <ref id="tgi_pieslice" name="tgi_pieslice">, <ref id="tgi_setcolor" name="tgi_setcolor"> <tag/Example/<tscreen><verb> -tgi_setcolor(TGI_COLOR_RED); +tgi_setcolor(1); tgi_ellipse (50, 40, 40, 20); </verb></tscreen> </descrip> @@ -216,17 +216,15 @@ original aspect ratio. <quote> <descrip> -<tag/Function/Return the current drawing color. +<tag/Function/Return the current drawing color (palette index). <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/unsigned char tgi_getcolor (void);/ <tag/Description/The actual color is an index to a palette. During tgi_init -you will get a default palette. The number of colors depend on the platform. -All platforms recognize at least TGI_COLOR_BLACK and TGI_COLOR_WHITE. But some -platforms have many more predefined colors. If you paint using TGI_COLOR_GREEN -and then you change the green of the palette to blue using tgi_setpalette then -after this painting in TGI_COLOR_GREEN will actually be blue. +you will get a default palette. Note that both the number of colors, and also +the available colors, depend on the platform. <tag/Availability/cc65 -<tag/See also/Other tgi functions +<tag/See also/<ref id="tgi_setcolor" name="tgi_setcolor">, +<ref id="tgi_setpalette" name="tgi_setpalette"> <tag/Example/<tscreen><verb> color = tgi_getcolor(); </verb></tscreen> @@ -238,7 +236,8 @@ color = tgi_getcolor(); <quote> <descrip> -<tag/Function/Get the number of available colors. +<tag/Function/Get the number of available colors in the palette for the current +driver. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/unsigned char tgi_getcolorcount (void);/ <tag/Description/TGI platforms use indexed color palettes. This function @@ -287,8 +286,6 @@ if (num_colors == 0) { <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/const unsigned char* tgi_getdefpalette (void);/ <tag/Description/The tgi driver has a default palette that is active at startup. -The named colors TGI_COLOR_BLACK, TGI_COLOR_WHITE, TGI_COLOR_RED... need this -palette to work correctly. <tag/Availability/cc65 <tag/See also/Other tgi functions <tag/Example/None. @@ -418,10 +415,10 @@ be used in presence of a prototype. <quote> <descrip> -<tag/Function/Get the color of a pixel from the viewpage. +<tag/Function/Get the color (palette index) of a pixel from the viewpage. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/unsigned char __fastcall__ tgi_getpixel (int x, int y);/ -<tag/Description/Get the color of a pixel from the viewpage. +<tag/Description/Get the color (palette index) of a pixel from the viewpage. <tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. @@ -626,7 +623,7 @@ be used in presence of a prototype. #define tgi_updatedisplay() tgi_ioctl(4, (void*)1) if (!tgi_busy()) { tgi_sprite(&background); - tgi_setcolor(TGI_COLOR_BLUE); + tgi_setcolor(1); tgi_outttextxy(20,40,"Hello World"); tgi_updatedisplay(); } @@ -791,7 +788,7 @@ of range. <ref id="tgi_setcolor" name="tgi_setcolor"> <tag/Example/<tscreen><verb> /* Draw the closed upper half of an ellipse */ -tgi_setcolor(TGI_COLOR_BLUE); +tgi_setcolor(1); tgi_pieslice (50, 50, 40, 20, 0, 180); </verb></tscreen> </descrip> @@ -834,20 +831,21 @@ only in the presence of a prototype. <quote> <descrip> -<tag/Function/Set color to be used in future draw operations. +<tag/Function/Set color (palette index) to be used in future draw operations. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ -<tag/Declaration/<tt/void __fastcall__ tgi_setcolor (unsigned char color);/ -<tag/Description/Set color to be used in future draw operations. +<tag/Declaration/<tt/void __fastcall__ tgi_setcolor (unsigned char color_index);/ +<tag/Description/Set color (palette index) to be used in future draw operations. <tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. </itemize> <tag/Availability/cc65 -<tag/See also/Other tgi functions. +<tag/See also/<ref id="tgi_getcolor" name="tgi_getcolor">, +<ref id="tgi_setpalette" name="tgi_setpalette"> <tag/Example/<tscreen><verb> -tgi_setcolor(TGI_COLOR_BLACK); +tgi_setcolor(1); tgi_bar(0,0,30,30); -tgi_setcolor(TGI_COLOR_WHITE); +tgi_setcolor(2); tgi_bar(10,10,20,20); </verb></tscreen> </descrip> @@ -893,13 +891,19 @@ Palette is a pointer to as many entries as there are colors. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/void __fastcall__ tgi_setpalette (const unsigned char* palette);/ <tag/Description/Set the palette (not available with all drivers/hardware). -Palette is a pointer to as many entries as there are colors. +Palette is a pointer to as many entries as there are colors. The values in the +palette are target specific, some (hopefully, more or less) portable values are +defined in the TGI_COLOR_XY defines. <tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. +<item>The palette is the (only) place where to use the TGI_COLOR_XY values. This +has been an ongoing and reoccurring misunderstanding in the past: At every other +place, the "color" values are indices into the current palette. </itemize> <tag/Availability/cc65 -<tag/See also/Other tgi functions. +<tag/See also/<ref id="tgi_setcolor" name="tgi_setcolor">, +<ref id="tgi_getpalette" name="tgi_getpalette"> <tag/Example/None. </descrip> </quote> From 5e4f811ddf16069e64503cb0445de5e2b1eeeb7e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 17 Jun 2025 22:52:42 +0200 Subject: [PATCH 524/707] remove commented out code --- src/da65/handler.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index 4f35fbaa3..ee9b6e3c5 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -740,7 +740,6 @@ void OH_DirectImmediate (const OpcDesc* D) /* NOTE: currently <bit> is part of the instruction */ void OH_ZeroPageBit (const OpcDesc* D) { - /* unsigned Bit = GetCodeByte (PC) >> 5; */ unsigned Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ @@ -756,8 +755,6 @@ void OH_ZeroPageBit (const OpcDesc* D) /* NOTE: currently <bit> is part of the instruction */ void OH_AccumulatorBit (const OpcDesc* D) { - /* unsigned Bit = GetCodeByte (PC) >> 5; */ - /* Output the line */ OneLine (D, "a"); } @@ -767,7 +764,6 @@ void OH_AccumulatorBit (const OpcDesc* D) /* NOTE: currently <bit> is part of the instruction */ void OH_AccumulatorBitBranch (const OpcDesc* D) { - /* unsigned Bit = GetCodeByte (PC) >> 5; */ signed char BranchOffs = GetCodeByte (PC+1); /* Calculate the target address for the branch */ From 5a3aa1fd51d6509515c63382f3215021914dbd68 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 17 Jun 2025 23:34:23 +0200 Subject: [PATCH 525/707] fix/add missing .ifp02x and .p02x pseudo ops, update test --- doc/ca65.sgml | 18 +++ src/ca65/condasm.c | 11 ++ src/ca65/pseudo.c | 190 +++++++++++++------------ src/ca65/scanner.c | 2 + src/ca65/token.h | 2 + test/asm/cpudetect/6502x-cpudetect.ref | Bin 29 -> 31 bytes test/asm/cpudetect/cpudetect.s | 14 ++ 7 files changed, 148 insertions(+), 89 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 80224a84e..a12a4accb 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3234,6 +3234,12 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH (see <tt><ref id=".P02" name=".P02"></tt> command). +<sect1><tt>.IFP02X</tt><label id=".IFP02X"><p> + + Conditional assembly: Check if the assembler is currently in 6502X mode + (see <tt><ref id=".P02X" name=".P02X"></tt> command). + + <sect1><tt>.IFP4510</tt><label id=".IFP4510"><p> Conditional assembly: Check if the assembler is currently in 4510 mode @@ -3621,6 +3627,16 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" <tt><ref id=".P4510" name=".P4510"></tt> +<sect1><tt>.P02X</tt><label id=".P02X"><p> + + Enable the 6502X instruction set, disable 65SC02, 65C02 and 65816 + instructions. + + See: <tt><ref id=".PC02" name=".PC02"></tt>, <tt><ref id=".PSC02" + name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt> and + <tt><ref id=".P4510" name=".P4510"></tt> + + <sect1><tt>.P4510</tt><label id=".P4510"><p> Enable the 4510 instruction set. This is a superset of the 65C02 and @@ -4016,11 +4032,13 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" See: <tt><ref id=".CPU" name=".CPU"></tt>, <tt><ref id=".IFP02" name=".IFP02"></tt>, + <tt><ref id=".IFP02X" name=".IFP02X"></tt>, <tt><ref id=".IFPDTV" name=".IFPDTV"></tt>, <tt><ref id=".IFP816" name=".IFP816"></tt>, <tt><ref id=".IFPC02" name=".IFPC02"></tt>, <tt><ref id=".IFPSC02" name=".IFPSC02"></tt>, <tt><ref id=".P02" name=".P02"></tt>, + <tt><ref id=".P02X" name=".P02X"></tt>, <tt><ref id=".P816" name=".P816"></tt>, <tt><ref id=".P4510" name=".P4510"></tt>, <tt><ref id=".PC02" name=".PC02"></tt>, diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index f872ec9ed..60e8ab0c1 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -394,6 +394,16 @@ void DoConditionals (void) CalcOverallIfCond (); break; + case TOK_IFP02X: + D = AllocIf (".IFP02X", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_6502X); + } + ExpectSep (); + CalcOverallIfCond (); + break; + case TOK_IFP4510: D = AllocIf (".IFP4510", 1); NextTok (); @@ -485,6 +495,7 @@ int CheckConditionals (void) case TOK_IFNDEF: case TOK_IFNREF: case TOK_IFP02: + case TOK_IFP02X: case TOK_IFP4510: case TOK_IFP816: case TOK_IFPC02: diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 2ce1ae087..37dcd78da 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1562,6 +1562,14 @@ static void DoP02 (void) +static void DoP02X (void) +/* Switch to 6502 CPU */ +{ + SetCPU (CPU_6502X); +} + + + static void DoPC02 (void) /* Switch to 65C02 CPU */ { @@ -2057,70 +2065,72 @@ struct CtrlDesc { void (*Handler) (void); /* Command handler */ }; +/* NOTE: .AND, .BITAND, .BITNOT, .BITOR, .BITXOR, .MOD, .NOT, .OR, .SHL, .SHR + and .XOR do NOT go into this table */ #define PSEUDO_COUNT (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0])) static CtrlDesc CtrlCmdTab [] = { - { ccNone, DoA16 }, - { ccNone, DoA8 }, + { ccNone, DoA16 }, /* .A16 */ + { ccNone, DoA8 }, /* .A8 */ { ccNone, DoAddr }, /* .ADDR */ { ccNone, DoUnexpected }, /* .ADDRSIZE */ - { ccNone, DoAlign }, - { ccNone, DoASCIIZ }, + { ccNone, DoAlign }, /* .ALIGN */ + { ccNone, DoASCIIZ }, /* .ASCIIZ */ { ccNone, DoUnexpected }, /* .ASIZE */ - { ccNone, DoAssert }, - { ccNone, DoAutoImport }, + { ccNone, DoAssert }, /* .ASSERT */ + { ccNone, DoAutoImport }, /* .AUTOIMPORT */ { ccNone, DoUnexpected }, /* .BANK */ { ccNone, DoUnexpected }, /* .BANKBYTE */ - { ccNone, DoBankBytes }, + { ccNone, DoBankBytes }, /* .BANKBYTES */ { ccNone, DoUnexpected }, /* .BLANK */ - { ccNone, DoBss }, - { ccNone, DoByte }, - { ccNone, DoCase }, - { ccNone, DoCharMap }, - { ccNone, DoCode }, + { ccNone, DoBss }, /* .BSS */ + { ccNone, DoByte }, /* .BYT, .BYTE */ + { ccNone, DoCase }, /* .CASE */ + { ccNone, DoCharMap }, /* .CHARMAP */ + { ccNone, DoCode }, /* .CODE */ { ccNone, DoUnexpected, }, /* .CONCAT */ - { ccNone, DoConDes }, + { ccNone, DoConDes }, /* .CONDES */ { ccNone, DoUnexpected }, /* .CONST */ - { ccNone, DoConstructor }, + { ccNone, DoConstructor }, /* .CONSTRUCTOR */ { ccNone, DoUnexpected }, /* .CPU */ - { ccNone, DoData }, - { ccNone, DoDbg, }, - { ccNone, DoDByt }, - { ccNone, DoDebugInfo }, - { ccKeepToken, DoDefine }, + { ccNone, DoData }, /* .DATA */ + { ccNone, DoDbg, }, /* .DBG */ + { ccNone, DoDByt }, /* .DBYT */ + { ccNone, DoDebugInfo }, /* .DEBUGINFO */ + { ccKeepToken, DoDefine }, /* .DEF, .DEFINE */ { ccNone, DoUnexpected }, /* .DEFINED */ { ccNone, DoUnexpected }, /* .DEFINEDMACRO */ - { ccNone, DoDelMac }, - { ccNone, DoDestructor }, - { ccNone, DoDWord }, + { ccNone, DoDelMac }, /* .DELMAC, .DELMACRO */ + { ccNone, DoDestructor }, /* .DESTRUCTOR */ + { ccNone, DoDWord }, /* .DWORD */ { ccKeepToken, DoConditionals }, /* .ELSE */ { ccKeepToken, DoConditionals }, /* .ELSEIF */ - { ccKeepToken, DoEnd }, + { ccKeepToken, DoEnd }, /* .END */ { ccNone, DoUnexpected }, /* .ENDENUM */ { ccKeepToken, DoConditionals }, /* .ENDIF */ - { ccNone, DoUnexpected }, /* .ENDMACRO */ - { ccNone, DoEndProc }, - { ccNone, DoUnexpected }, /* .ENDREPEAT */ - { ccNone, DoEndScope }, + { ccNone, DoUnexpected }, /* .ENDMAC, .ENDMACRO */ + { ccNone, DoEndProc }, /* .ENDPROC */ + { ccNone, DoUnexpected }, /* .ENDREP, .ENDREPEAT */ + { ccNone, DoEndScope }, /* .ENDSCOPE */ { ccNone, DoUnexpected }, /* .ENDSTRUCT */ { ccNone, DoUnexpected }, /* .ENDUNION */ - { ccNone, DoEnum }, - { ccNone, DoError }, - { ccNone, DoExitMacro }, - { ccNone, DoExport }, - { ccNone, DoExportZP }, - { ccNone, DoFarAddr }, - { ccNone, DoFatal }, - { ccNone, DoFeature }, - { ccNone, DoFileOpt }, - { ccNone, DoForceImport }, + { ccNone, DoEnum }, /* .ENUM */ + { ccNone, DoError }, /* .ERROR */ + { ccNone, DoExitMacro }, /* .EXITMAC, .EXITMACRO */ + { ccNone, DoExport }, /* .EXPORT */ + { ccNone, DoExportZP }, /* .EXPORTZP */ + { ccNone, DoFarAddr }, /* .FARADDR */ + { ccNone, DoFatal }, /* .FATAL */ + { ccNone, DoFeature }, /* .FEATURE */ + { ccNone, DoFileOpt }, /* .FOPT, .FILEOPT */ + { ccNone, DoForceImport }, /* .FORCEIMPORT */ { ccNone, DoUnexpected }, /* .FORCEWORD */ - { ccNone, DoGlobal }, - { ccNone, DoGlobalZP }, + { ccNone, DoGlobal }, /* .GLOBAL */ + { ccNone, DoGlobalZP }, /* .GLOBALZP */ { ccNone, DoUnexpected }, /* .HIBYTE */ - { ccNone, DoHiBytes }, + { ccNone, DoHiBytes }, /* .HIBYTES */ { ccNone, DoUnexpected }, /* .HIWORD */ - { ccNone, DoI16 }, - { ccNone, DoI8 }, + { ccNone, DoI16 }, /* .I16 */ + { ccNone, DoI8 }, /* .I8 */ { ccNone, DoUnexpected }, /* .IDENT */ { ccKeepToken, DoConditionals }, /* .IF */ { ccKeepToken, DoConditionals }, /* .IFBLANK */ @@ -2131,81 +2141,83 @@ static CtrlDesc CtrlCmdTab [] = { { ccKeepToken, DoConditionals }, /* .IFNDEF */ { ccKeepToken, DoConditionals }, /* .IFNREF */ { ccKeepToken, DoConditionals }, /* .IFP02 */ + { ccKeepToken, DoConditionals }, /* .IFP02X */ { ccKeepToken, DoConditionals }, /* .IFP4510 */ { ccKeepToken, DoConditionals }, /* .IFP816 */ { ccKeepToken, DoConditionals }, /* .IFPC02 */ { ccKeepToken, DoConditionals }, /* .IFPDTV */ { ccKeepToken, DoConditionals }, /* .IFPSC02 */ { ccKeepToken, DoConditionals }, /* .IFREF */ - { ccNone, DoImport }, - { ccNone, DoImportZP }, - { ccNone, DoIncBin }, - { ccNone, DoInclude }, - { ccNone, DoInterruptor }, + { ccNone, DoImport }, /* .IMPORT */ + { ccNone, DoImportZP }, /* .IMPORTZP */ + { ccNone, DoIncBin }, /* .INCBIN */ + { ccNone, DoInclude }, /* .INCLUDE */ + { ccNone, DoInterruptor }, /* .INTERRUPTPOR */ { ccNone, DoUnexpected }, /* .ISIZE */ { ccNone, DoUnexpected }, /* .ISMNEMONIC */ { ccNone, DoInvalid }, /* .LEFT */ - { ccNone, DoLineCont }, - { ccNone, DoList }, - { ccNone, DoListBytes }, - { ccNone, DoLiteral }, + { ccNone, DoLineCont }, /* .LINECONT */ + { ccNone, DoList }, /* .LIST */ + { ccNone, DoListBytes }, /* .LISTBYTES */ + { ccNone, DoLiteral }, /* .LITERAL */ { ccNone, DoUnexpected }, /* .LOBYTE */ - { ccNone, DoLoBytes }, + { ccNone, DoLoBytes }, /* .LOBYTES */ { ccNone, DoUnexpected }, /* .LOCAL */ - { ccNone, DoLocalChar }, + { ccNone, DoLocalChar }, /* .LOCALCHAR */ { ccNone, DoUnexpected }, /* .LOWORD */ - { ccNone, DoMacPack }, - { ccNone, DoMacro }, + { ccNone, DoMacPack }, /* .MACPACK */ + { ccNone, DoMacro }, /* .MAC, .MACRO */ { ccNone, DoUnexpected }, /* .MATCH */ { ccNone, DoUnexpected }, /* .MAX */ { ccNone, DoInvalid }, /* .MID */ { ccNone, DoUnexpected }, /* .MIN */ - { ccNone, DoNull }, - { ccNone, DoOrg }, - { ccNone, DoOut }, - { ccNone, DoP02 }, - { ccNone, DoP4510 }, - { ccNone, DoP816 }, - { ccNone, DoPageLength }, + { ccNone, DoNull }, /* .NULL */ + { ccNone, DoOrg }, /* .ORG */ + { ccNone, DoOut }, /* .OUT */ + { ccNone, DoP02 }, /* .P02 */ + { ccNone, DoP02X }, /* .P02X */ + { ccNone, DoP4510 }, /* .P4510 */ + { ccNone, DoP816 }, /* .P816 */ + { ccNone, DoPageLength }, /* .PAGELEN, .PAGELENGTH */ { ccNone, DoUnexpected }, /* .PARAMCOUNT */ - { ccNone, DoPC02 }, - { ccNone, DoPDTV }, - { ccNone, DoPopCharmap }, - { ccNone, DoPopCPU }, - { ccNone, DoPopSeg }, - { ccNone, DoProc }, - { ccNone, DoPSC02 }, - { ccNone, DoPushCharmap }, - { ccNone, DoPushCPU }, - { ccNone, DoPushSeg }, - { ccNone, DoUnexpected }, /* .REFERENCED */ - { ccNone, DoReferTo }, /* .REFERTO */ - { ccNone, DoReloc }, - { ccNone, DoRepeat }, - { ccNone, DoRes }, + { ccNone, DoPC02 }, /* .PSC02 */ + { ccNone, DoPDTV }, /* .PDTV */ + { ccNone, DoPopCharmap }, /* .POPCHARMAP */ + { ccNone, DoPopCPU }, /* .POPCPU */ + { ccNone, DoPopSeg }, /* .POPSEG */ + { ccNone, DoProc }, /* .PROC */ + { ccNone, DoPSC02 }, /* .PSC02 */ + { ccNone, DoPushCharmap }, /* .PUSHCHARMAP */ + { ccNone, DoPushCPU }, /* .PUSHCPU */ + { ccNone, DoPushSeg }, /* .PUSHSEG */ + { ccNone, DoUnexpected }, /* .REF, .REFERENCED */ + { ccNone, DoReferTo }, /* .REFTO, .REFERTO */ + { ccNone, DoReloc }, /* .RELOC */ + { ccNone, DoRepeat }, /* .REPEAT */ + { ccNone, DoRes }, /* .RES */ { ccNone, DoInvalid }, /* .RIGHT */ - { ccNone, DoROData }, - { ccNone, DoScope }, - { ccNone, DoSegment }, + { ccNone, DoROData }, /* .RODATA */ + { ccNone, DoScope }, /* .SCOPE */ + { ccNone, DoSegment }, /* .SEGMENT */ { ccNone, DoUnexpected }, /* .SET */ - { ccNone, DoSetCPU }, + { ccNone, DoSetCPU }, /* .SETCPU */ { ccNone, DoUnexpected }, /* .SIZEOF */ - { ccNone, DoSmart }, + { ccNone, DoSmart }, /* .SMART */ { ccNone, DoUnexpected }, /* .SPRINTF */ { ccNone, DoUnexpected }, /* .STRAT */ { ccNone, DoUnexpected }, /* .STRING */ { ccNone, DoUnexpected }, /* .STRLEN */ - { ccNone, DoStruct }, - { ccNone, DoTag }, + { ccNone, DoStruct }, /* .STRUCT */ + { ccNone, DoTag }, /* .TAG */ { ccNone, DoUnexpected }, /* .TCOUNT */ { ccNone, DoUnexpected }, /* .TIME */ - { ccKeepToken, DoUnDef }, - { ccNone, DoUnion }, + { ccKeepToken, DoUnDef }, /* .UNDEF, .UNDEFINE */ + { ccNone, DoUnion }, /* .UNION */ { ccNone, DoUnexpected }, /* .VERSION */ - { ccNone, DoWarning }, - { ccNone, DoWord }, + { ccNone, DoWarning }, /* .WARNING */ + { ccNone, DoWord }, /* .WORD */ { ccNone, DoUnexpected }, /* .XMATCH */ - { ccNone, DoZeropage }, + { ccNone, DoZeropage }, /* .ZEROPAGE */ }; diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 94c84d897..157702897 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -221,6 +221,7 @@ struct DotKeyword { { ".IFNDEF", TOK_IFNDEF }, { ".IFNREF", TOK_IFNREF }, { ".IFP02", TOK_IFP02 }, + { ".IFP02X", TOK_IFP02X }, { ".IFP4510", TOK_IFP4510 }, { ".IFP816", TOK_IFP816 }, { ".IFPC02", TOK_IFPC02 }, @@ -259,6 +260,7 @@ struct DotKeyword { { ".ORG", TOK_ORG }, { ".OUT", TOK_OUT }, { ".P02", TOK_P02 }, + { ".P02X", TOK_P02X }, { ".P4510", TOK_P4510 }, { ".P816", TOK_P816 }, { ".PAGELEN", TOK_PAGELENGTH }, diff --git a/src/ca65/token.h b/src/ca65/token.h index 8f935f7a1..aeae7166a 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -193,6 +193,7 @@ typedef enum token_t { TOK_IFNDEF, TOK_IFNREF, TOK_IFP02, + TOK_IFP02X, TOK_IFP4510, TOK_IFP816, TOK_IFPC02, @@ -226,6 +227,7 @@ typedef enum token_t { TOK_ORG, TOK_OUT, TOK_P02, + TOK_P02X, TOK_P4510, TOK_P816, TOK_PAGELENGTH, diff --git a/test/asm/cpudetect/6502x-cpudetect.ref b/test/asm/cpudetect/6502x-cpudetect.ref index 3434ecbea7fb1e119879fae346989933fd09bacd..9e7abe573ffc65dce67d2b8b95d1c3ef9827bd71 100644 GIT binary patch delta 7 Ocmb1@XIlMgf-C?CJpzFM literal 29 ZcmZQ@4hW6+40a8PH#0RbVnE?V0042#2dMx6 diff --git a/test/asm/cpudetect/cpudetect.s b/test/asm/cpudetect/cpudetect.s index 7b2363b7f..6ee07ae3c 100644 --- a/test/asm/cpudetect/cpudetect.s +++ b/test/asm/cpudetect/cpudetect.s @@ -8,6 +8,10 @@ lda #$ea .endif +.ifp02x + lax #$ea +.endif + .ifpsc02 jmp ($1234,x) .endif @@ -72,3 +76,13 @@ .byte 0,"CPU_ISET_6502DTV" .endif + +; step 3: switch through all supported cpus to verify the pseudo-op is there + +.p02 +.p02X +.psc02 +.pc02 +.p816 +.p4510 +.pdtv From 3d2734172f1d60ede400d804aeea0aa5c03d938d Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Tue, 17 Jun 2025 23:53:40 +0200 Subject: [PATCH 526/707] Delete cfg/m740.cfg --- cfg/m740.cfg | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 cfg/m740.cfg diff --git a/cfg/m740.cfg b/cfg/m740.cfg deleted file mode 100644 index e68bff0f5..000000000 --- a/cfg/m740.cfg +++ /dev/null @@ -1,37 +0,0 @@ -FEATURES { - STARTADDRESS: default = $8000; -} -SYMBOLS { - __STACKSIZE__: type = weak, value = $0000; # 2k stack - __STACKSTART__: type = weak, value = $100; - __ZPSTART__: type = weak, value = $0000; -} -MEMORY { - ZP: file = "", define = yes, start = __ZPSTART__, size = $001F; - MAIN: file = %O, start = %S, size = __STACKSTART__ - __STACKSIZE__ - %S; -} -SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - STARTUP: load = MAIN, type = ro, optional = yes; - LOWCODE: load = MAIN, type = ro, optional = yes; - ONCE: load = MAIN, type = ro, optional = yes; - CODE: load = MAIN, type = rw; - RODATA: load = MAIN, type = rw; - DATA: load = MAIN, type = rw; - BSS: load = MAIN, 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__; -} From 4daba00d4780524d998e95faf93c74cb4e3a7d38 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 18 Jun 2025 00:28:53 +0200 Subject: [PATCH 527/707] don't make script choke with more than 9 tables --- .github/checks/sorted.sh | 4 ++-- .github/checks/sorted_codeopt.sh | 4 ++-- .github/checks/sorted_opcodes.sh | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/checks/sorted.sh b/.github/checks/sorted.sh index 0a4a90db7..4f53b0484 100755 --- a/.github/checks/sorted.sh +++ b/.github/checks/sorted.sh @@ -13,8 +13,8 @@ function checkarray_quoted_name START="\\/\\* BEGIN SORTED.SH \\*\\/" END="\\/\\* END SORTED.SH \\*\\/" - awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \ - sed -e 's:\(.*\) ##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \ + sed -e 's:\(.*\)##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then echo "error: "$1" table is empty" diff --git a/.github/checks/sorted_codeopt.sh b/.github/checks/sorted_codeopt.sh index e90e32b4a..c78662b9d 100755 --- a/.github/checks/sorted_codeopt.sh +++ b/.github/checks/sorted_codeopt.sh @@ -13,7 +13,7 @@ function checkarray START="\\/\\* BEGIN DECL SORTED_CODEOPT.SH \\*\\/" END="\\/\\* END DECL SORTED_CODEOPT.SH \\*\\/" - awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \ + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \ sed -e 's:\(.*##\).*"\(.*\)",.*:\1\2:g' > .a.tmp if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then @@ -33,7 +33,7 @@ function checkarray START="\\/\\* BEGIN SORTED_CODEOPT.SH \\*\\/" END="\\/\\* END SORTED_CODEOPT.SH \\*\\/" - awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \ + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \ sed -e 's:\(.*##\).*&D\(.*\),.*:\1\2:g' > .b.tmp if [[ -z $(grep '[^[:space:]]' .b.tmp) ]] ; then diff --git a/.github/checks/sorted_opcodes.sh b/.github/checks/sorted_opcodes.sh index b18b841c8..3e45ea752 100755 --- a/.github/checks/sorted_opcodes.sh +++ b/.github/checks/sorted_opcodes.sh @@ -13,10 +13,10 @@ function checkarray_quoted_name START="\\/\\* BEGIN SORTED_OPCODES.SH \\*\\/" END="\\/\\* END SORTED_OPCODES.SH \\*\\/" - awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \ + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \ sed 's:/\*.*::g' | \ grep '".*",' | \ - sed -e 's:\(.*\) ##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp + sed -e 's:\(.*\)##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then echo "error: "$1" table is empty" From dd78eb91c37964e7004b8d305a7859f8f842f3cb Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 18 Jun 2025 00:28:53 +0200 Subject: [PATCH 528/707] don't make script choke with more than 9 tables --- .github/checks/sorted_codeopt.sh | 4 ++-- .github/checks/sorted_opcodes.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/checks/sorted_codeopt.sh b/.github/checks/sorted_codeopt.sh index e90e32b4a..c78662b9d 100755 --- a/.github/checks/sorted_codeopt.sh +++ b/.github/checks/sorted_codeopt.sh @@ -13,7 +13,7 @@ function checkarray START="\\/\\* BEGIN DECL SORTED_CODEOPT.SH \\*\\/" END="\\/\\* END DECL SORTED_CODEOPT.SH \\*\\/" - awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \ + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \ sed -e 's:\(.*##\).*"\(.*\)",.*:\1\2:g' > .a.tmp if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then @@ -33,7 +33,7 @@ function checkarray START="\\/\\* BEGIN SORTED_CODEOPT.SH \\*\\/" END="\\/\\* END SORTED_CODEOPT.SH \\*\\/" - awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \ + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \ sed -e 's:\(.*##\).*&D\(.*\),.*:\1\2:g' > .b.tmp if [[ -z $(grep '[^[:space:]]' .b.tmp) ]] ; then diff --git a/.github/checks/sorted_opcodes.sh b/.github/checks/sorted_opcodes.sh index b18b841c8..3e45ea752 100755 --- a/.github/checks/sorted_opcodes.sh +++ b/.github/checks/sorted_opcodes.sh @@ -13,10 +13,10 @@ function checkarray_quoted_name START="\\/\\* BEGIN SORTED_OPCODES.SH \\*\\/" END="\\/\\* END SORTED_OPCODES.SH \\*\\/" - awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {print count,"##",$0}' "$CHECK_FILE" | \ + awk '/'"$START"'/{flag=1; count++; next} /'"$END"'/{flag=0;} flag {printf("%04d##%s\n", count, $0)}' "$CHECK_FILE" | \ sed 's:/\*.*::g' | \ grep '".*",' | \ - sed -e 's:\(.*\) ##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp + sed -e 's:\(.*\)##.*\"\(.*\)\".*:\1##\2:g' > .a.tmp if [[ -z $(grep '[^[:space:]]' .a.tmp) ]] ; then echo "error: "$1" table is empty" From ff1e5b33519d439004fb0781c364b7e3cfa2b1dc Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 17 Jun 2025 23:11:55 +0200 Subject: [PATCH 529/707] minimize diff --- src/ca65/instr.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ca65/instr.h b/src/ca65/instr.h index e31ae0734..8e0900c77 100644 --- a/src/ca65/instr.h +++ b/src/ca65/instr.h @@ -89,18 +89,21 @@ #define AM65_ZP_REL 0x10000000UL /* ZP, REL (m740) */ #define AM65_SPECIAL_PAGE 0x20000000UL /* $FFxx (m740) */ - - /* Bitmask for all ZP operations that have correspondent ABS ops */ #define AM65_SET_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND) + /* Bitmask for all ABS operations that have correspondent FAR ops */ #define AM65_SET_ABS (AM65_ABS | AM65_ABS_X) + /* Bitmask for all ZP operations */ #define AM65_ALL_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND) + /* Bitmask for all ABS operations */ #define AM65_ALL_ABS (AM65_ABS | AM65_ABS_X | AM65_ABS_Y | AM65_ABS_IND | AM65_ABS_X_IND) + /* Bitmask for all FAR operations */ #define AM65_ALL_FAR (AM65_ABS_LONG | AM65_ABS_LONG_X) + /* Bitmask for all immediate operations */ #define AM65_ALL_IMM (AM65_IMM_ACCU | AM65_IMM_INDEX | AM65_IMM_IMPLICIT | AM65_IMM_IMPLICIT_WORD) From 9eecd794b112e0060615200ed3dbe5d0172a3f8b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 18 Jun 2025 02:03:52 +0200 Subject: [PATCH 530/707] less hacky way to get the addr mode --- src/ca65/instr.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 9fffd312f..647dccc46 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1645,15 +1645,27 @@ static void PutBitBranch_m740 (const InsDesc* Ins) /* Evaluate the addressing mode used */ GetEA(&A); - A.AddrMode = 2; /* HACK */ + /* From the possible addressing modes, remove the ones that are invalid + ** for this instruction or CPU. + */ + A.AddrModeSet &= Ins->AddrMode; + + /* Check if we have any adressing modes left */ + if (A.AddrModeSet == 0) { + Error ("Illegal addressing mode"); + return; + } + A.AddrMode = BitFind (A.AddrModeSet); + A.Opcode = Ins->BaseCode; - if (A.AddrModeSet == 0x00000002) { + if (A.AddrMode == AM65I_ACCU) { /* Accu */ Emit0 (A.Opcode); ConsumeComma (); EmitSigned (GenBranchExpr (2), 1); - } else if (A.AddrModeSet == 0x10000000) { + } else if (A.AddrMode == AM65I_ZP_REL) { + /* FIXME: hacky, the comma was already consumed here */ A.Opcode += 0x04; /* Zeropage */ Emit0 (A.Opcode); From 80b4ea304b80e36342a819ca817009f91b74a85c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 18 Jun 2025 02:24:59 +0200 Subject: [PATCH 531/707] fix table for added address modes --- src/ca65/instr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 647dccc46..a9f7a62a9 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1298,6 +1298,7 @@ static unsigned char Sweet16EATab[2][AMSW16I_COUNT] = { }; /* Table that encodes the additional bytes for each 65xx instruction */ +/* NOTE: one entry per addressing mode! */ unsigned char ExtBytes[AM65I_COUNT] = { 0, /* Implicit */ 0, /* Accu */ @@ -1327,6 +1328,8 @@ unsigned char ExtBytes[AM65I_COUNT] = { 7, /* Block transfer (HuC6280) */ 2, /* Absolute Indirect long */ 2, /* Immidiate word */ + 2, /* Direct, Relative short */ + 1, /* Special Page */ }; /* Table that encodes the additional bytes for each SWEET16 instruction */ From 499fcbdb5f14f6ddbcad7164c0f344df168ed660 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 18 Jun 2025 02:38:34 +0200 Subject: [PATCH 532/707] we dont use the table in the custom jsr --- src/ca65/instr.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index a9f7a62a9..c9e0768b6 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1125,7 +1125,7 @@ static const struct { { "INX", 0x00000001, 0xe8, 0, PutAll }, { "INY", 0x00000001, 0xc8, 0, PutAll }, { "JMP", 0x00000C08, 0x00, 12, PutAll }, - { "JSR", 0x20000408, 0x00, 13, PutJSR_m740 }, + { "JSR", 0x20000408, 0x00, 0, PutJSR_m740 }, { "LDA", 0x0080A26C, 0xa0, 0, PutAll }, { "LDM", 0x10000000, 0x3c, 0, PutLDM_m740 }, { "LDX", 0x0080030C, 0xa2, 1, PutAll }, @@ -1275,13 +1275,6 @@ static unsigned char EATab[14][AM65I_COUNT] = { 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }, - { /* Table 13 m740 JSR */ - 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, }; @@ -1912,10 +1905,8 @@ static void PutJSR_m740 (const InsDesc* Ins) return; } A.AddrMode = BitFind (A.AddrModeSet); - A.AddrModeBit = (0x01UL << A.AddrMode); /* Build the opcode */ - /* A.Opcode = Ins->BaseCode | EATab[Ins->ExtCode][A.AddrMode] | A.Reg; */ A.Opcode = Ins->BaseCode; switch (A.AddrMode) { From 157ddf2c5bfb86051b7d0eb1acf80ef25540b059 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 18 Jun 2025 02:41:15 +0200 Subject: [PATCH 533/707] codestyle --- src/da65/handler.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index ee9b6e3c5..8145a6bfc 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -736,9 +736,10 @@ void OH_DirectImmediate (const OpcDesc* D) -/* <bit> zp */ -/* NOTE: currently <bit> is part of the instruction */ void OH_ZeroPageBit (const OpcDesc* D) +/* <bit> zp +** NOTE: currently <bit> is part of the instruction +*/ { unsigned Addr = GetCodeByte (PC+1); @@ -751,18 +752,20 @@ void OH_ZeroPageBit (const OpcDesc* D) -/* <bit> A */ -/* NOTE: currently <bit> is part of the instruction */ void OH_AccumulatorBit (const OpcDesc* D) +/* <bit> A +** NOTE: currently <bit> is part of the instruction +*/ { /* Output the line */ OneLine (D, "a"); } -/* <bit> A, rel */ -/* NOTE: currently <bit> is part of the instruction */ void OH_AccumulatorBitBranch (const OpcDesc* D) +/* <bit> A, rel +** NOTE: currently <bit> is part of the instruction +*/ { signed char BranchOffs = GetCodeByte (PC+1); @@ -788,8 +791,8 @@ void OH_JmpDirectIndirect (const OpcDesc* D) } - void OH_SpecialPage (const OpcDesc* D) +/* m740 "special page" address mode */ { /* Get the operand */ unsigned Addr = 0xFF00 + GetCodeByte (PC+1); @@ -797,7 +800,6 @@ void OH_SpecialPage (const OpcDesc* D) /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); - /* OneLine (D, "$FF%02X", (CodeByte (PC+1)); */ OneLine (D, "%s", GetAddrArg (D->Flags, Addr)); } From 05506ede2a4eec03ee79493657ad4e0ac29368f6 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 18 Jun 2025 02:41:22 +0200 Subject: [PATCH 534/707] comments --- src/ca65/instr.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index c9e0768b6..f94740dcb 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1197,84 +1197,86 @@ const InsTable* InsTab = (const InsTable*) &InsTab6502; /* Table to build the effective 65xx opcode from a base opcode and an ** addressing mode. (The value in the table is ORed with the base opcode) +** NOTE: each table has one entry per addressing mode! */ static unsigned char EATab[14][AM65I_COUNT] = { - { /* Table 0 */ + { /* Table 0 (sec, sed, seo, set, slw, sta, stp, tax, tay, tsx, txa, txs, tya) */ 0x00, 0x00, 0x05, 0x0D, 0x0F, 0x15, 0x1D, 0x1F, 0x00, 0x19, 0x12, 0x00, 0x07, 0x11, 0x17, 0x01, 0x00, 0x00, 0x00, 0x03, 0x13, 0x09, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { /* Table 1 (rol, ror, stx, sty) */ + { /* Table 1 (rol, ror, stx, sty, tst) */ 0x08, 0x08, 0x04, 0x0C, 0x00, 0x14, 0x1C, 0x00, 0x14, 0x1C, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x00 + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }, { /* Table 2 (bit) */ 0x00, 0x00, 0x24, 0x2C, 0x0F, 0x34, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 3 (dec, dea) */ 0x3A, 0x3A, 0xC6, 0xCE, 0x00, 0xD6, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 4 (inc) */ 0x1A, 0x1A, 0xE6, 0xEE, 0x00, 0xF6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 5 (stz) */ 0x00, 0x00, 0x60, 0x98, 0x00, 0x70, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { /* Table 6 (jmp) */ + { /* Table 6 (jmp, rrf) */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x90, 0x00 + 0x00, 0x00, 0x90, 0x00, 0x00, 0x00 }, - { /* Table 7 (Subroutine opcodes) (jsr) */ + { /* Table 7 (jsr) */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 8 */ 0x00, 0x40, 0x01, 0x41, 0x00, 0x09, 0x49, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 9 (dew, inw) */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { /* Table 10 (NOPs) */ + { /* Table 10 (NOPs, clbX, sebX) */ 0xea, 0x00, 0x04, 0x0c, 0x00, 0x14, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 11 (LAX) */ 0x08, 0x08, 0x04, 0x0C, 0x00, 0x14, 0x1C, 0x00, 0x14, 0x1C, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x80, 0x00 + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }, - { /* Table 12 m740 JMP */ + { /* Table 12 (m740: JMP) */ 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, }; From 00de49a46d07127d14d1370f32e306b0525bf97d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 18 Jun 2025 02:43:40 +0200 Subject: [PATCH 535/707] codestyle --- src/da65/handler.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index 8145a6bfc..45c152697 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -531,9 +531,10 @@ void OH_BitBranch (const OpcDesc* D) xfree (BranchLabel); } -/* <bit> zp, rel */ -/* NOTE: currently <bit> is part of the instruction */ void OH_BitBranch_m740 (const OpcDesc* D) +/* <bit> zp, rel +** NOTE: currently <bit> is part of the instruction +*/ { /* unsigned Bit = GetCodeByte (PC) >> 5; */ unsigned Addr = GetCodeByte (PC+1); From 8cb05784472c63e4b126426e21c0ce96de131b8b Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Wed, 18 Jun 2025 06:38:38 +0000 Subject: [PATCH 536/707] changes suggested by mrdudz --- Makefile | 10 +++------- doc/Makefile | 10 +++------- libsrc/Makefile | 10 +++------- samples/Makefile | 10 +++------- samples/apple2/Makefile | 10 +++------- samples/atari2600/Makefile | 10 +++------- samples/atari5200/Makefile | 10 +++------- samples/cbm/Makefile | 10 +++------- samples/disasm/Makefile | 10 +++------- samples/gamate/Makefile | 10 +++------- samples/geos/Makefile | 10 +++------- samples/geos/grc/Makefile | 10 +++------- samples/kim1/Makefile | 10 +++------- samples/lynx/Makefile | 10 +++------- samples/sim65/Makefile | 10 +++------- samples/supervision/Makefile | 10 +++------- samples/sym1/Makefile | 10 +++------- samples/tutorial/Makefile | 10 +++------- src/Makefile | 10 +++------- targettest/Makefile | 10 +++------- targettest/accelerator/Makefile | 10 +++------- targettest/atari/Makefile | 10 +++------- targettest/cbm/Makefile | 10 +++------- targettest/gamate/Makefile | 10 +++------- targettest/pce/Makefile | 10 +++------- test/Makefile | 10 +++------- test/asm/Makefile | 10 +++------- test/asm/cpudetect/Makefile | 10 +++------- test/asm/err/Makefile | 10 +++------- test/asm/listing/Makefile | 10 +++------- test/asm/misc/Makefile | 10 +++------- test/asm/opcodes/Makefile | 10 +++------- test/asm/val/Makefile | 10 +++------- test/dasm/Makefile | 10 +++------- test/err/Makefile | 10 +++------- test/misc/Makefile | 10 +++------- test/ref/Makefile | 10 +++------- test/standard/Makefile | 10 +++------- test/standard_err/Makefile | 10 +++------- test/todo/Makefile | 10 +++------- test/val/Makefile | 10 +++------- util/Makefile | 10 +++------- util/atari/Makefile | 10 +++------- util/gamate/Makefile | 10 +++------- util/zlib/Makefile | 10 +++------- 45 files changed, 135 insertions(+), 315 deletions(-) diff --git a/Makefile b/Makefile index 912dbf7cb..13e965c9e 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) .PHONY: all mostlyclean clean install zip avail unavail bin lib doc html info samples test util checkstyle check diff --git a/doc/Makefile b/doc/Makefile index cbb41132d..330f7b31c 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) ifneq ($(shell echo),) CMD_EXE = 1 diff --git a/libsrc/Makefile b/libsrc/Makefile index 487c9d8a1..1ec0bcfea 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) ifneq ($(shell echo),) CMD_EXE = 1 diff --git a/samples/Makefile b/samples/Makefile index 9c9d4bcf6..0a56af3c1 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # # Makefile for cc65 samples diff --git a/samples/apple2/Makefile b/samples/apple2/Makefile index 2bf9ca257..d9fa40f66 100644 --- a/samples/apple2/Makefile +++ b/samples/apple2/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/atari2600/Makefile b/samples/atari2600/Makefile index 8224b8784..71264792d 100644 --- a/samples/atari2600/Makefile +++ b/samples/atari2600/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/atari5200/Makefile b/samples/atari5200/Makefile index 838966782..1bdf1b75d 100644 --- a/samples/atari5200/Makefile +++ b/samples/atari5200/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/cbm/Makefile b/samples/cbm/Makefile index fbd0248be..a593569b0 100644 --- a/samples/cbm/Makefile +++ b/samples/cbm/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/disasm/Makefile b/samples/disasm/Makefile index 818742e5c..6599915f6 100644 --- a/samples/disasm/Makefile +++ b/samples/disasm/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Sample makefile using a preprocessor against info files # and the --sync-lines option diff --git a/samples/gamate/Makefile b/samples/gamate/Makefile index 629b5a584..35aef293d 100644 --- a/samples/gamate/Makefile +++ b/samples/gamate/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/geos/Makefile b/samples/geos/Makefile index 9d7a98d3f..ad4033f80 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index f3343a4bb..360c7bc7d 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/kim1/Makefile b/samples/kim1/Makefile index 96a64cbcf..dbdbcec8d 100644 --- a/samples/kim1/Makefile +++ b/samples/kim1/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/lynx/Makefile b/samples/lynx/Makefile index 44e6cec71..078ea129a 100644 --- a/samples/lynx/Makefile +++ b/samples/lynx/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/sim65/Makefile b/samples/sim65/Makefile index 0cf9778c6..3a06321ee 100644 --- a/samples/sim65/Makefile +++ b/samples/sim65/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/supervision/Makefile b/samples/supervision/Makefile index 9dd201f6a..9396be63d 100644 --- a/samples/supervision/Makefile +++ b/samples/supervision/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/sym1/Makefile b/samples/sym1/Makefile index e81cc7c33..8abcfb5aa 100644 --- a/samples/sym1/Makefile +++ b/samples/sym1/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile index eeb37f72d..7b3286e27 100644 --- a/samples/tutorial/Makefile +++ b/samples/tutorial/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/src/Makefile b/src/Makefile index 99caf7450..085a50f9d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) ifneq ($(shell echo),) CMD_EXE = 1 diff --git a/targettest/Makefile b/targettest/Makefile index 19d141a12..56b5df446 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # # Makefile for cc65 testcode diff --git a/targettest/accelerator/Makefile b/targettest/accelerator/Makefile index 2cc67d4fe..6e710d010 100644 --- a/targettest/accelerator/Makefile +++ b/targettest/accelerator/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/targettest/atari/Makefile b/targettest/atari/Makefile index 2f1856ffd..0e376e9bc 100644 --- a/targettest/atari/Makefile +++ b/targettest/atari/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/targettest/cbm/Makefile b/targettest/cbm/Makefile index 8944d72c6..ebe00198f 100644 --- a/targettest/cbm/Makefile +++ b/targettest/cbm/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. # var. to build for another target system. diff --git a/targettest/gamate/Makefile b/targettest/gamate/Makefile index 674ccf85f..f03c2b064 100644 --- a/targettest/gamate/Makefile +++ b/targettest/gamate/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/targettest/pce/Makefile b/targettest/pce/Makefile index 9a97027f3..549720a40 100644 --- a/targettest/pce/Makefile +++ b/targettest/pce/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Run 'make SYS=<target>'; or, set a SYS env. diff --git a/test/Makefile b/test/Makefile index 21d0623e2..94bc7e5ea 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # top-level Makefile for the regression tests diff --git a/test/asm/Makefile b/test/asm/Makefile index c69bbb725..2d5ba764e 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # top-level Makefile for the regression tests diff --git a/test/asm/cpudetect/Makefile b/test/asm/cpudetect/Makefile index cd755bd13..fde19b17b 100644 --- a/test/asm/cpudetect/Makefile +++ b/test/asm/cpudetect/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the assembler regression tests diff --git a/test/asm/err/Makefile b/test/asm/err/Makefile index 0f37a2b9a..c1a8285e4 100644 --- a/test/asm/err/Makefile +++ b/test/asm/err/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the tests that MUST NOT compile diff --git a/test/asm/listing/Makefile b/test/asm/listing/Makefile index 88940c769..4321d3b95 100644 --- a/test/asm/listing/Makefile +++ b/test/asm/listing/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the assembler regression tests diff --git a/test/asm/misc/Makefile b/test/asm/misc/Makefile index 3605504b1..1b2305cda 100644 --- a/test/asm/misc/Makefile +++ b/test/asm/misc/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the remaining asm tests that need special care in one way or another diff --git a/test/asm/opcodes/Makefile b/test/asm/opcodes/Makefile index d0115ae05..70dd41c06 100644 --- a/test/asm/opcodes/Makefile +++ b/test/asm/opcodes/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the assembler regression tests diff --git a/test/asm/val/Makefile b/test/asm/val/Makefile index 34111cfed..08c000f95 100644 --- a/test/asm/val/Makefile +++ b/test/asm/val/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the regression tests that return an error code on failure diff --git a/test/dasm/Makefile b/test/dasm/Makefile index 240503191..29e97b9c1 100644 --- a/test/dasm/Makefile +++ b/test/dasm/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the disassembler regression tests diff --git a/test/err/Makefile b/test/err/Makefile index 238e57e35..a0cdc22ae 100644 --- a/test/err/Makefile +++ b/test/err/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the tests that MUST NOT compile diff --git a/test/misc/Makefile b/test/misc/Makefile index dcda6e7b4..989e8f83a 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the remaining tests that need special care in one way or another diff --git a/test/ref/Makefile b/test/ref/Makefile index 213512640..2dadf5bcc 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the regression tests that generate output which has to be # compared with reference output diff --git a/test/standard/Makefile b/test/standard/Makefile index d710ab443..e359fa975 100644 --- a/test/standard/Makefile +++ b/test/standard/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the regression tests that return an error code on failure diff --git a/test/standard_err/Makefile b/test/standard_err/Makefile index c99108cca..f554d33eb 100644 --- a/test/standard_err/Makefile +++ b/test/standard_err/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the tests that MUST NOT compile diff --git a/test/todo/Makefile b/test/todo/Makefile index cb341ff80..ec14cf8d4 100644 --- a/test/todo/Makefile +++ b/test/todo/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the currently failing regression tests that return an error code on failure diff --git a/test/val/Makefile b/test/val/Makefile index 75a0755e8..68882971d 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) # Makefile for the regression tests that return an error code on failure diff --git a/util/Makefile b/util/Makefile index b4c1d900c..337320d36 100644 --- a/util/Makefile +++ b/util/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) .PHONY: atari gamate zlib diff --git a/util/atari/Makefile b/util/atari/Makefile index 3fbde98c2..aa3163ec4 100644 --- a/util/atari/Makefile +++ b/util/atari/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) CC = $(CROSS_COMPILE)gcc diff --git a/util/gamate/Makefile b/util/gamate/Makefile index cbd6c68d9..d9b4bbd42 100644 --- a/util/gamate/Makefile +++ b/util/gamate/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) CC = $(CROSS_COMPILE)gcc diff --git a/util/zlib/Makefile b/util/zlib/Makefile index b0f274539..8068ea120 100644 --- a/util/zlib/Makefile +++ b/util/zlib/Makefile @@ -1,12 +1,8 @@ # ---- Display info during parsing phase ---- -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) -$(info ~~~ Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST)))) -ifeq ($(MAKECMDGOALS),) - $(info ~~~ Invoked target: (default)) -else - $(info ~~~ Invoked target: $(MAKECMDGOALS)) +SILENT:=$(findstring s,$(word 1, $(MAKEFLAGS))) +ifneq ($(SILENT),s) + $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -$(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~) CC = $(CROSS_COMPILE)gcc From 2ceaa3fabb3ef16a36a6a712502b0cbedcdaf221 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Wed, 18 Jun 2025 10:34:13 +0200 Subject: [PATCH 537/707] Added a few simple optimizations that resolve most of #2527. --- src/cc65/codeopt.c | 17 +++++-- src/cc65/coptind.c | 45 ++++++++++++++++++- src/cc65/coptind.h | 3 ++ src/cc65/coptmisc.c | 106 +++++++++++++++++++++++++++++++++++++++++++- src/cc65/coptmisc.h | 10 ++++- 5 files changed, 173 insertions(+), 8 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index c8d7d2ce9..19acfde74 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -119,7 +119,8 @@ static OptFunc DOptBNegAX1 = { OptBNegAX1, "OptBNegAX1", 100, 0, static OptFunc DOptBNegAX2 = { OptBNegAX2, "OptBNegAX2", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptBNegAX3 = { OptBNegAX3, "OptBNegAX3", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptBNegAX4 = { OptBNegAX4, "OptBNegAX4", 100, 0, 0, 0, 0, 0 }; -static OptFunc DOptBinOps = { OptBinOps, "OptBinOps", 0, 0, 0, 0, 0, 0 }; +static OptFunc DOptBinOps1 = { OptBinOps1, "OptBinOps1", 0, 0, 0, 0, 0, 0 }; +static OptFunc DOptBinOps2 = { OptBinOps2, "OptBinOps2", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptBoolCmp = { OptBoolCmp, "OptBoolCmp", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptBoolTrans = { OptBoolTrans, "OptBoolTrans", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptBoolUnary1 = { OptBoolUnary1, "OptBoolUnary1", 40, 0, 0, 0, 0, 0 }; @@ -154,6 +155,8 @@ static OptFunc DOptJumpTarget3 = { OptJumpTarget3, "OptJumpTarget3", 100, 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 DOptLoad3 = { OptLoad3, "OptLoad3", 0, 0, 0, 0, 0, 0 }; +static OptFunc DOptLoadStore1 = { OptLoadStore1, "OptLoadStore1", 0, 0, 0, 0, 0, 0 }; +static OptFunc DOptLoadStore2 = { OptLoadStore2, "OptLoadStore2", 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 DOptLongCopy = { OptLongCopy, "OptLongCopy", 100, 0, 0, 0, 0, 0 }; @@ -238,7 +241,8 @@ static OptFunc* OptFuncs[] = { &DOptBNegAX2, &DOptBNegAX3, &DOptBNegAX4, - &DOptBinOps, + &DOptBinOps1, + &DOptBinOps2, &DOptBoolCmp, &DOptBoolTrans, &DOptBoolUnary1, @@ -273,6 +277,8 @@ static OptFunc* OptFuncs[] = { &DOptLoad1, &DOptLoad2, &DOptLoad3, + &DOptLoadStore1, + &DOptLoadStore2, &DOptLoadStoreLoad, &DOptLongAssign, &DOptLongCopy, @@ -649,6 +655,7 @@ static unsigned RunOptGroup1 (CodeSeg* S) Changes += RunOptFunc (S, &DOptSub1, 1); Changes += RunOptFunc (S, &DOptSub3, 1); Changes += RunOptFunc (S, &DOptLongAssign, 1); + Changes += RunOptFunc (S, &DOptLoadStore2, 1); Changes += RunOptFunc (S, &DOptStore4, 1); Changes += RunOptFunc (S, &DOptStore5, 1); Changes += RunOptFunc (S, &DOptShift1, 1); @@ -741,9 +748,10 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptJumpTarget3, 1); /* After OptCondBranches2 */ C += RunOptFunc (S, &DOptUnusedLoads, 1); C += RunOptFunc (S, &DOptUnusedStores, 1); - C += RunOptFunc (S, &DOptDupLoads, 1); C += RunOptFunc (S, &DOptStoreLoad, 1); C += RunOptFunc (S, &DOptLoadStoreLoad, 1); + C += RunOptFunc (S, &DOptDupLoads, 1); + C += RunOptFunc (S, &DOptLoadStore1, 1); C += RunOptFunc (S, &DOptTransfers1, 1); C += RunOptFunc (S, &DOptTransfers3, 1); C += RunOptFunc (S, &DOptTransfers4, 1); @@ -755,7 +763,8 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptPrecalc, 1); C += RunOptFunc (S, &DOptShiftBack, 1); C += RunOptFunc (S, &DOptSignExtended, 1); - C += RunOptFunc (S, &DOptBinOps, 1); + C += RunOptFunc (S, &DOptBinOps1, 1); + C += RunOptFunc (S, &DOptBinOps2, 1); Changes += C; diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 52c47481e..99fc101a9 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -590,6 +590,49 @@ unsigned OptStoreLoad (CodeSeg* S) +unsigned OptLoadStore1 (CodeSeg* S) +/* Remove an 8 bit load followed by a store into the same location. */ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* N; + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if it is a load instruction followed by a store into the + ** same address. + */ + if ((E->Info & OF_LOAD) != 0 && + (N = CS_GetNextEntry (S, I)) != 0 && + !CE_HasLabel (N) && + E->AM == N->AM && + ((E->OPC == OP65_LDA && N->OPC == OP65_STA) || + (E->OPC == OP65_LDX && N->OPC == OP65_STX) || + (E->OPC == OP65_LDY && N->OPC == OP65_STY)) && + strcmp (E->Arg, N->Arg) == 0) { + + /* Memory cell has already the correct value, remove the store */ + CS_DelEntry (S, I+1); + + /* Remember, we had changes */ + ++Changes; + } + + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} + + + unsigned OptLoadStoreLoad (CodeSeg* S) /* Search for the sequence ** @@ -626,7 +669,7 @@ unsigned OptLoadStoreLoad (CodeSeg* S) strcmp (L[0]->Arg, L[2]->Arg) == 0) { /* Remove the second load */ - CS_DelEntries (S, I+2, 1); + CS_DelEntry (S, I+2); /* Remember, we had changes */ ++Changes; diff --git a/src/cc65/coptind.h b/src/cc65/coptind.h index 3493543a4..e54ba37d2 100644 --- a/src/cc65/coptind.h +++ b/src/cc65/coptind.h @@ -66,6 +66,9 @@ unsigned OptDupLoads (CodeSeg* S); unsigned OptStoreLoad (CodeSeg* S); /* Remove a store followed by a load from the same location. */ +unsigned OptLoadStore1 (CodeSeg* S); +/* Remove an 8 bit load followed by a store into the same location. */ + unsigned OptLoadStoreLoad (CodeSeg* S); /* Remove a load, store followed by a reload of the same location. */ diff --git a/src/cc65/coptmisc.c b/src/cc65/coptmisc.c index e48d469a1..b23ee6e0a 100644 --- a/src/cc65/coptmisc.c +++ b/src/cc65/coptmisc.c @@ -582,11 +582,57 @@ unsigned OptGotoSPAdj (CodeSeg* S) /*****************************************************************************/ -/* Optimize stack load ops */ +/* Optimize stack load/store ops */ /*****************************************************************************/ +unsigned OptLoadStore2 (CodeSeg* S) +/* Remove 16 bit stack loads followed by a store into the same location. */ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* N; + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if this is a 16 bit load followed by a store into the same + ** address. + */ + if (CE_IsCallTo (E, "ldaxysp") && /* Stack load ... */ + RegValIsKnown (E->RI->In.RegY) && /* ... with known offs */ + (N = CS_GetNextEntry (S, I)) != 0 && /* Next insn ... */ + !CE_HasLabel (N) && /* ... without label ... */ + N->OPC == OP65_LDY && /* ... is LDY */ + CE_IsKnownImm (N, E->RI->In.RegY-1) && /* Same offset as load */ + (N = CS_GetNextEntry (S, I+1)) != 0 && /* Next insn ... */ + !CE_HasLabel (N) && /* ... without label ... */ + CE_IsCallTo (N, "staxysp")) { /* ... is store */ + + /* Found - remove it. Leave the load in place. If it's unused, it + ** will get removed by later steps. + */ + CS_DelEntries (S, I+1, 2); + + /* Remember, we had changes */ + ++Changes; + } + + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} + + + unsigned OptLoad1 (CodeSeg* S) /* Search for a call to ldaxysp where X is not used later and replace it by ** a load of just the A register. @@ -736,7 +782,7 @@ unsigned OptLoad2 (CodeSeg* S) -unsigned OptBinOps (CodeSeg* S) +unsigned OptBinOps1 (CodeSeg* S) /* Search for an AND/EOR/ORA where the value of A or the operand is known and ** replace it by something simpler. */ @@ -902,3 +948,59 @@ unsigned OptBinOps (CodeSeg* S) /* Return the number of changes made */ return Changes; } + + + +unsigned OptBinOps2 (CodeSeg* S) +/* Search for an AND/EOR/ORA for identical memory locations and replace it +** by something simpler. +*/ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* N; + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check if this is an 8 bit load followed by a bit operation with the + ** same memory cell. + */ + if (E->OPC == OP65_LDA && + (N = CS_GetNextEntry (S, I)) != 0 && /* Next insn ... */ + !CE_HasLabel (N) && /* ... without label ... */ + (N->OPC == OP65_AND || /* ... is AND/EOR/ORA ... */ + N->OPC == OP65_EOR || + N->OPC == OP65_ORA) && + E->AM == N->AM && /* ... with same addr mode ... */ + strcmp (E->Arg, N->Arg) == 0) { /* ... and same argument */ + + /* For an EOR, the result is zero. For the other instructions, the + ** result doesn't change so they can be removed. + */ + if (N->OPC == OP65_EOR) { + /* Simply insert a load of the now known value. The flags will + ** be correct because of the load and the preceeding + ** instructions will be removed by later steps. + */ + CodeEntry* X = NewCodeEntry (OP65_LDA, AM65_IMM, "$00", 0, N->LI); + CS_InsertEntry (S, X, I+2); + } else { + CS_DelEntry (S, I+1); + } + + /* Remember, we had changes */ + ++Changes; + } + + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} diff --git a/src/cc65/coptmisc.h b/src/cc65/coptmisc.h index 418b61e94..aceaa55d3 100644 --- a/src/cc65/coptmisc.h +++ b/src/cc65/coptmisc.h @@ -99,6 +99,9 @@ unsigned OptStackPtrOps (CodeSeg* S); unsigned OptGotoSPAdj (CodeSeg* S); /* Optimize SP adjustment for forward 'goto' */ +unsigned OptLoadStore2 (CodeSeg* S); +/* Remove 16 bit stack loads followed by a store into the same location. */ + unsigned OptLoad1 (CodeSeg* S); /* Search for a call to ldaxysp where X is not used later and replace it by ** a load of just the A register. @@ -107,11 +110,16 @@ unsigned OptLoad1 (CodeSeg* S); unsigned OptLoad2 (CodeSeg* S); /* Replace calls to ldaxysp by inline code */ -unsigned OptBinOps (CodeSeg* S); +unsigned OptBinOps1 (CodeSeg* S); /* Search for an AND/EOR/ORA where the value of A or the operand is known and ** replace it by something simpler. */ +unsigned OptBinOps2 (CodeSeg* S); +/* Search for an AND/EOR/ORA for identical memory locations and replace it +** by something simpler. +*/ + /* End of coptmisc.h */ From 130c5e67b3be0144655ba19f81424a5629eb6341 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:30:29 +0200 Subject: [PATCH 538/707] typo --- doc/ca65.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 3324131b4..095dcb7f3 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -152,7 +152,7 @@ Here is a description of all the command line options: Set the default for the CPU type. The option takes a parameter, which may be one of - 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510, m740 + 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510, M740 <label id="option-create-dep"> From 8d407c7b17dde74e59d38d92803546964d69f8ac Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Mon, 16 Jun 2025 07:49:22 +0200 Subject: [PATCH 539/707] Fix #2649. When generating labels for "skip" sections, GetGranularity() is called which wouldn't handle this type. --- src/da65/attrtab.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/da65/attrtab.c b/src/da65/attrtab.c index e35530afd..002965dff 100644 --- a/src/da65/attrtab.c +++ b/src/da65/attrtab.c @@ -146,8 +146,7 @@ unsigned GetGranularity (attr_t Style) case atAddrTab: return 2; case atRtsTab: return 2; case atTextTab: return 1; - - case atSkip: + case atSkip: return 1; default: Internal ("GetGranularity called for style = %d", Style); return 0; From 2be28d2d6401f60fbe86b4ca3551e75727267ee8 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 19 Jun 2025 01:32:43 +0200 Subject: [PATCH 540/707] add some comments --- asminc/cpu.mac | 2 ++ doc/ca65.sgml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 1f5c0758e..818d70df1 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -20,6 +20,8 @@ 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 CPU_SWEET16 = CPU_ISET_SWEET16 +; NOTE: HUC6280 removes "wai" ($cb) and "stp" ($db) from the 65C02 instruction set CPU_HUC6280 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_HUC6280 +; NOTE: 45100 replaces "wai" ($cb) and "stp" ($db) of the 65C02 instruction set CPU_4510 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_4510 CPU_M740 = CPU_ISET_6502|CPU_ISET_M740 diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 095dcb7f3..22f9a03cf 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -4807,6 +4807,7 @@ each supported CPU a constant similar to CPU_HUC6280 CPU_4510 CPU_6502DTV + CPU_M740 </verb></tscreen> is defined. These constants may be used to determine the exact type of the @@ -4822,6 +4823,7 @@ another constant is defined: CPU_ISET_HUC6280 CPU_ISET_4510 CPU_ISET_6502DTV + CPU_ISET_M740 </verb></tscreen> The value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable may From d34b36c6e582bf2f0720f524cce15ea894cd0e54 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 19 Jun 2025 01:33:31 +0200 Subject: [PATCH 541/707] add test that checks all opcodes per current cpu flags --- test/asm/cpudetect/allinst.inc | 813 +++++++++++++++++++++++++++++++++ test/asm/cpudetect/cpudetect.s | 6 + 2 files changed, 819 insertions(+) create mode 100644 test/asm/cpudetect/allinst.inc diff --git a/test/asm/cpudetect/allinst.inc b/test/asm/cpudetect/allinst.inc new file mode 100644 index 000000000..d698a053e --- /dev/null +++ b/test/asm/cpudetect/allinst.inc @@ -0,0 +1,813 @@ + + ; just emit to bss for now, this way the output wont get checked, which is + ; fine - we only want to see if the assembler accepts all the opcodes it + ; should accept for the current CPU mode + .bss + +.if (.cpu .bitand CPU_ISET_6502) + .scope + ; regular basic 6502 (legal) instruction set +LABEL0: + brk ; $00 + ora ($12,x) ; $01 + ora $12 ; $05 + asl $12 ; $06 + php ; $08 + ora #$12 ; $09 + asl a ; $0a + ora $1234 ; $0d + asl $1234 ; $0e + bpl LABEL0 ; $10 + ora ($12),y ; $11 + ora $12,x ; $15 + asl $12,x ; $16 + clc ; $18 + ora $1234,y ; $19 + ora $1234,x ; $1d + asl $1234,x ; $1e + jsr $1234 ; $20 + and ($12,x) ; $21 + bit $12 ; $24 + and $12 ; $25 + rol $12 ; $26 + plp ; $28 + and #$12 ; $29 + rol a ; $2a + bit $1234 ; $2c + and $1234 ; $2d + rol $1234 ; $2e + bmi LABEL ; $30 + and ($12),y ; $31 + and $12,x ; $35 + rol $12,x ; $36 + sec ; $38 + and $1234,y ; $39 + and $1234,x ; $3d + rol $1234,x ; $3e + rti ; $40 + eor ($12,x) ; $41 + eor $12 ; $45 + lsr $12 ; $46 + pha ; $48 + eor #$12 ; $49 + lsr a ; $4a + jmp $1234 ; $4c + eor $1234 ; $4d + lsr $1234 ; $4e + bvc LABEL ; $50 + eor ($12),y ; $51 + eor $12,x ; $55 + lsr $12,x ; $56 + cli ; $58 + eor $1234,y ; $59 + eor $1234,x ; $5d + lsr $1234,x ; $5e + rts ; $60 + adc ($12,x) ; $61 + adc $12 ; $65 + ror $12 ; $66 + pla ; $68 + adc #$12 ; $69 + ror a ; $6a + jmp ($1234) ; $6c + adc $1234 ; $6d + ror $1234 ; $6e + bvs LABEL ; $70 + adc ($12),y ; $71 + adc $12,x ; $75 + ror $12,x ; $76 + sei ; $78 + adc $1234,y ; $79 + adc $1234,x ; $7d + ror $1234,x ; $7e +LABEL: + sta ($12,x) ; $81 + sty $12 ; $84 + sta $12 ; $85 + stx $12 ; $86 + dey ; $88 + txa ; $8a + sty $1234 ; $8c + sta $1234 ; $8d + stx $1234 ; $8e + bcc LABEL ; $90 + sta ($12),y ; $91 + sty $12,x ; $94 + sta $12,x ; $95 + stx $12,y ; $96 + tya ; $98 + sta $1234,y ; $99 + txs ; $9a + sta $1234,x ; $9d + ldy #$12 ; $a0 + lda ($12,x) ; $a1 + ldx #$12 ; $a2 + ldy $12 ; $a4 + lda $12 ; $a5 + ldx $12 ; $a6 + tay ; $a8 + lda #$12 ; $a9 + tax ; $aa + ldy $1234 ; $ac + lda $1234 ; $ad + ldx $1234 ; $ae + bcs LABEL ; $b0 + lda ($12),y ; $b1 + ldy $12,x ; $b4 + lda $12,x ; $b5 + ldx $12,y ; $b6 + clv ; $b8 + lda $1234,y ; $b9 + tsx ; $ba + ldy $1234,x ; $bc + lda $1234,x ; $bd + ldx $1234,y ; $be + cpy #$12 ; $c0 + cmp ($12,x) ; $c1 + cpy $12 ; $c4 + cmp $12 ; $c5 + dec $12 ; $c6 + iny ; $c8 + cmp #$12 ; $c9 + dex ; $ca + cpy $1234 ; $cc + cmp $1234 ; $cd + dec $1234 ; $ce + bne LABEL ; $d0 + cmp ($12),y ; $d1 + cmp $12,x ; $d5 + dec $12,x ; $d6 + cld ; $d8 + cmp $1234,y ; $d9 + cmp $1234,x ; $dd + dec $1234,x ; $de + cpx #$12 ; $e0 + sbc ($12,x) ; $e1 + cpx $12 ; $e4 + sbc $12 ; $e5 + inc $12 ; $e6 + inx ; $e8 + sbc #$12 ; $e9 + nop ; $ea + cpx $1234 ; $ec + sbc $1234 ; $ed + inc $1234 ; $ee + beq LABEL1 ; $f0 + sbc ($12),y ; $f1 + sbc $12,x ; $f5 + inc $12,x ; $f6 + sed ; $f8 + sbc $1234,y ; $f9 + sbc $1234,x ; $fd + inc $1234,x ; $fe +LABEL1: + .endscope +.endif + + +.if (.cpu .bitand CPU_ISET_6502X) + .scope + ; all "undocumented" 6502 instructions (aka "unintended opcodes") + jam ; $02 + slo ($12,x) ; $03 + nop $12 ; $04 + slo $12 ; $07 + anc #$12 ; $0b + nop $1234 ; $0c + slo $1234 ; $0f + jam ; $12 + slo ($12),y ; $13 + nop $12,x ; $14 + slo $12,y ; $17 + nop ; $1a + slo $1234,y ; $1b + nop $1234,x ; $1c + slo $1234,x ; $1f + jam ; $22 + rla ($12,x) ; $23 + rla $12 ; $27 + anc #$12 ; $2b + rla $1234 ; $2f + jam ; $32 + rla ($12),y ; $33 + nop $12,x ; $34 + rla $12,y ; $37 + nop ; $3a + rla $1234,y ; $3b + nop $1234,x ; $3c + rla $1234,x ; $3f + jam ; $42 + sre ($12,x) ; $43 + nop $12 ; $44 + sre $12 ; $47 + alr #$12 ; $4b + sre $1234 ; $4f + jam ; $52 + sre ($12),y ; $53 + nop $12,x ; $54 + sre $12,y ; $57 + nop ; $5a + sre $1234,y ; $5b + nop $1234,x ; $5c + sre $1234,x ; $5f + jam ; $62 + rra ($12,x) ; $63 + nop $12 ; $64 + rra $12 ; $67 + arr #$12 ; $6b + rra $1234 ; $6f + jam ; $72 + rra ($12),y ; $73 + nop $12,x ; $74 + rra $12,y ; $77 + nop ; $7a + rra $1234,y ; $7b + nop $1234,x ; $7c + rra $1234,x ; $7f + nop #$12 ; $80 + nop #$12 ; $82 + sax ($12,x) ; $83 + sax $12 ; $87 + nop #$12 ; $89 + ;xaa #$12 ; $8b FIXME (implement in assembler) + sax $1234 ; $8f + jam ; $92 + ;ahx ($12),y ; $93 FIXME (implement in assembler) + sax $12,y ; $97 + tas $1234,y ; $9b + shy $1234,x ; $9c + shx $1234,y ; $9e + ;ahx $1234,y ; $9f FIXME (implement in assembler) + lax ($12,x) ; $a3 + lax $12 ; $a7 + lax #$12 ; $ab + lax $1234 ; $af + jam ; $b2 + lax ($12),y ; $b3 + lax $12,y ; $b7 + las $1234,y ; $bb + lax $1234,y ; $bf + nop #$12 ; $c2 + dcp ($12,x) ; $c3 + dcp $12 ; $c7 + axs #$12 ; $cb + dcp $1234 ; $cf + jam ; $d2 + dcp ($12),y ; $d3 + nop $12,x ; $d4 + dcp $12,y ; $d7 + nop ; $da + dcp $1234,y ; $db + nop $1234,x ; $dc + dcp $1234,x ; $df + nop #$12 ; $e2 + isc ($12,x) ; $e3 + isc $12 ; $e7 + sbc #$12 ; $eb + isc $1234 ; $ef + jam ; $f2 + isc ($12),y ; $f3 + nop $12,x ; $f4 + isc $12,y ; $f7 + nop ; $fa + isc $1234,y ; $fb + nop $1234,x ; $fc + isc $1234,x ; $ff + .endscope +.endif + + +.if (.cpu .bitand CPU_ISET_6502DTV) + .scope +LABEL: + ; opcodes added over 6502 (these are JAM on 6502) + bra LABEL ; $12 + sac #$12 ; $32 + sir #$12 ; $42 + + ; opcodes added over 6502, which work the same as the "illegal" opcodes on 6502 + nop $12 ; $04 + nop $1234 ; $0c + nop $12,x ; $14 + nop ; $1a + nop $1234,x ; $1c + nop $12,x ; $34 + nop ; $3a + nop $1234,x ; $3c + nop $12 ; $44 + nop $12,x ; $54 + nop ; $5a + nop $1234,x ; $5c + nop $12 ; $64 + nop $12,x ; $74 + nop ; $7a + nop $1234,x ; $7c + nop #$12 ; $80 + nop #$12 ; $82 + nop #$12 ; $89 + nop #$12 ; $c2 + nop $12,x ; $d4 + nop ; $da + nop $1234,x ; $dc + nop #$12 ; $e2 + nop $12,x ; $f4 + nop ; $fa + nop $1234,x ; $fc + + anc #$12 ; $0b + anc #$12 ; $2b + + rla ($12,x) ; $23 + rla $12 ; $27 + rla $1234 ; $2f + rla ($12),y ; $33 + rla $12,y ; $37 + rla $1234,y ; $3b + rla $1234,x ; $3f + + lax ($12,x) ; $a3 + lax $12 ; $a7 + lax #$12 ; $ab + lax $1234 ; $af + lax ($12),y ; $b3 + lax $12,y ; $b7 + las $1234,y ; $bb + lax $1234,y ; $bf + + alr #$12 ; $4b + + arr #$12 ; $6b + + rra ($12,x) ; $63 + rra $12 ; $67 + rra $1234 ; $6f + rra ($12),y ; $73 + rra $12,y ; $77 + rra $1234,y ; $7b + rra $1234,x ; $7f + + shy $1234,x ; $9c + shx $1234,y ; $9e + + axs #$12 ; $cb + + sbc #$12 ; $eb + + .endscope +.endif + + +;------------------------------------------------------------------------------ +; The 65c02 is the CMOS re-design of the 6502. It has a few improvements: +; +; 65C02 65ce02 +; +; $04 tsb zp +; $0c tsb abs16 +; $12 ora (zp) (-> ora (zp), z) +; $14 trb zp +; $1a inc +; $1c trb abs16 +; $32 and (zp) (-> and (zp), z) +; $34 bit zp, x +; $3a dec +; $3c bit abs16, x +; $52 eor (zp) (-> eor (zp), z) +; $5a phy +; $64 stz zp (store z, not 0) +; $72 adc (zp) (-> adc (zp), z) +; $74 stz zp, x (store z, not 0) +; $7a ply +; $7c jmp (abs16, x) +; $80 bra rel8 +; $89 bit #imm8 +; $92 sta (zp) (-> sta (zp), z) +; $9c stz abs16 (store z, not 0) +; $9e stz abs16, x (store z, not 0) +; $b2 lda (zp) (-> lda (zp), z) +; $d2 cmp (zp) (-> cmp (zp), z) +; $da phx +; $f2 sbc (zp) (-> sbc (zp), z) +; $fa plx + +; FIXME: currently CPU_ISET_65SC02 and CPU_65SC02 really means "65C02" + +; FIXME: should really check for 65C02 + +.if (.cpu .bitand CPU_ISET_65SC02) + .scope + ; 65c02 instruction set adds some extra legal instructions to 6502 + tsb $12 ; $04 + tsb $1234 ; $0c + ;ora ($12) ; $12 FIXME: not working with 4510:ora (zp), z + trb $12 ; $14 + inc a ; $1a + trb $1234 ; $1c + ;and ($12) ; $32 FIXME: not working with 4510:and (zp), z + bit $12,x ; $34 + dec a ; $3a + bit $1234,x ; $3c + ;eor ($12) ; $52 FIXME: not working with 4510:eor (zp), z + phy ; $5a + stz $12 ; $64 + ;adc ($12) ; $72 FIXME: not working with 4510:adc (zp), z + stz $12,x ; $74 + ply ; $7a + jmp ($1234) ; $7c +LABEL: + bra LABEL ; $80 + bit #$12 ; $89 + ;sta ($12) ; $92 FIXME: not working with 4510:sta (zp), z + stz $1234 ; $9c + stz $1234,x ; $9e + ;lda ($12) ; $b2 FIXME: not working with 4510:lda (zp), z + ;cmp ($12) ; $d2 FIXME: not working with 4510:cmp (zp), z + phx ; $da + ;sbc ($12) ; $f2 FIXME: not working with 4510:sbc (zp), z + plx ; $fa + .endscope +.endif + +; FIXME: hack so these opcodes get fixed anyway, while 4510 is still quirky +.if (.cpu .bitand CPU_ISET_65SC02) +.if (.not .cpu = CPU_4510) + ora ($12) ; $12 + and ($12) ; $32 + eor ($12) ; $52 + adc ($12) ; $72 + sta ($12) ; $92 + lda ($12) ; $b2 + cmp ($12) ; $d2 + sbc ($12) ; $f2 +.endif +.endif + +; TODO: R65C02 +; The R65C02 is a superset of the 65C02. It adds bit manipulation instructions: +; smbB zp set bit in zp location +; rmbB zp reset bit in zp location +; bbsB zp, rel8 branch if bit is set in zp location +; bbrB zp, rel8 branch if bit is reset in zp location + +; FIXME: currently CPU_ISET_65C02 and CPU_65C02 really means "W65C02" + +; FIXME: should really check for R65C02 + +.if (.cpu .bitand CPU_ISET_65C02) + + ; R65C02 instruction set adds some extra legal instructions to 65C02 + rmb0 $12 ; $07 + bbr0 $12, LABEL3 ; $0f + rmb1 $12 ; $17 + bbr1 $12, LABEL3 ; $1f + rmb2 $12 ; $27 + bbr2 $12, LABEL3 ; $2f + rmb3 $12 ; $37 + bbr3 $12, LABEL3 ; $3f + rmb4 $12 ; $47 + bbr4 $12, LABEL3 ; $4f + rmb5 $12 ; $57 + bbr5 $12, LABEL3 ; $5f + rmb6 $12 ; $67 + bbr6 $12, LABEL3 ; $6f + rmb7 $12 ; $77 + bbr7 $12, LABEL3 ; $7f +LABEL3: + smb0 $12 ; $87 + bbs0 $12, LABEL3 ; $8f + smb1 $12 ; $97 + bbs1 $12, LABEL3 ; $9f + smb2 $12 ; $a7 + bbs2 $12, LABEL3 ; $af + smb3 $12 ; $b7 + bbs3 $12, LABEL3 ; $bf + smb4 $12 ; $c7 + bbs4 $12, LABEL3 ; $cf + smb5 $12 ; $d7 + bbs5 $12, LABEL3 ; $df + smb6 $12 ; $e7 + bbs6 $12, LABEL3 ; $ef + smb7 $12 ; $f7 + bbs7 $12, LABEL3 ; $ff + +.endif + + +; TODO: W65C02 +; The W65C02 is a superset of the R65C02. It only adds two instructions: +; +; $cb wai wait for interrupt +; $db stp wait for reset + +; FIXME: currently CPU_ISET_65C02 and CPU_65C02 really means "W65C02" + +; FIXME: should really check for W65C02 + +.if (.cpu = CPU_65C02) + wai ; $cb + stp ; $db +.endif + + +; TODO: 65CE02 +; The 65CE02 is another superset of the R65C02. It has several improvements: +; +; $02 cle clear stack extend disable +; $03 see set stack extend disable +; $0b tsy transfer stack_ptr_high to Y +; $12 ora (zp), z +; $13 lbpl rel16 +; $1b inz increment Z +; $22 jsr (abs16) +; $23 jsr (abs16, x) +; $2b tys transfer Y to stack_ptr_high +; $32 and (zp), z +; $33 lbmi rel16 +; $3b dez decrement Z +; $42 neg negate A +; $43 asr +; $44 asr zp +; $4b taz transfer A to Z +; $52 eor (zp), z +; $53 lbvc rel16 +; $54 asr zp, x +; $5b tab +; $5c aug "4-byte NOP reserved for future expansion" +; $62 rtn #imm8 +; $63 lbsr rel16 relative jsr, "branch to subroutine" +; $64 stz zp store Z +; $6b tza transfer Z to A +; $72 adc (zp), z +; $73 lbvs rel16 +; $74 stz zp, x store Z +; $7b tba +; $82 sta (off8, s), y +; $83 lbra rel16 relative jmp +; $8b sty abs16, x +; $92 sta (zp), z +; $93 lbcc rel16 +; $9b stx abs16, y +; $9c stz abs16 store Z +; $9e stz abs16, x store Z +; $a3 ldz #imm8 +; $ab ldz abs16 +; $b2 lda (zp), z +; $b3 lbcs rel16 +; $bb ldz abs16, x +; $c2 cpz #imm8 +; $c3 dew zp +; $cb asw abs16 +; $d2 cmp (zp), z +; $d3 lbne rel16 +; $d4 cpz zp +; $db phz push Z +; $dc cpz abs16 +; $e2 lda (off8, s), y +; $e3 inw zp +; $eb row abs16 +; $f2 sbc (zp), z +; $f3 lbeq rel16 +; $f4 phw #imm16 +; $fb plz pull Z +; $fc phw abs16 + +; FIXME: should really check for 65CE02 + +.if (.cpu .bitand CPU_ISET_4510) + .scope + ; 65CE02 adds the following: + cle ; $02 + see ; $03 + tsy ; $0b + ora ($12), z ; $12 (ora (zp) on 65C02) + lbpl $1234 ; $13 + inz ; $1b + jsr ($1234) ; $22 + jsr ($1234,x) ; $23 + tys ; $2b + and ($12), z ; $32 (and (zp) on 65C02) + lbmi $1234 ; $33 + dez ; $3b + neg ; $42 + asr a ; $43 + asr $12 ; $44 + taz ; $4b + lbvc $1234 ; $53 + asr $12,x ; $54 + tab ; $5b + ;aug ; $5c FIXME: implement in assembler + rtn #$12 ; $62 + bsr $1234 ; $63 + stz $12 ; $64 (stores 0 on 65C02) + tza ; $6b + adc ($12), z ; $72 (adc (zp) on 65C02) + lbvs $1234 ; $73 + stz $12, x ; $74 (stores 0 on 65C02) + tba ; $7b + sta ($12,s),y ; $82 + lbra $1234 ; $83 + sty $1234,x ; $8b + lbcc $1234 ; $93 + sta ($12), z ; $92 (sta (zp) on 65C02) + stx $1234,y ; $9b + stz $1234 ; $9c (stores 0 on 65C02) + ldz #$12 ; $a3 + ldz $1234 ; $ab + lda ($12), z ; $b2 (lda (zp) on 65C02) + lbcs $1234 ; $b3 + ldz $1234,x ; $bb + cpz #$12 ; $c2 + dew $12 ; $c3 + cmp ($12), z ; $d2 (cmp ($12) on 65C02) + lbne $1234 ; $d3 + cpz $12 ; $d4 + cpz $1234 ; $dc + lda ($12,s),y ; $e2 + inw $12 ; $e3 + row $1234 ; $eb + sbc ($12), z ; $f2 (sbc (zp) on 65C02) + lbeq $1234 ; $f3 + phw #$1234 ; $f4 + plz ; $fb + phw $1234 ; $fc + + .endscope +.endif + + +; The 4502 is a superset of the 65CE02. Opcode 5c (originally a "4-byte NOP +; reserved for future expansion") has been changed to the "map" instruction, +; now using implied addressing. +; +; $5c map +; $cb asw abs +; $db phz + +.if (.cpu .bitand CPU_ISET_4510) + .scope + + ; added to 65CE02 + map ; $5c ("4-byte NOP reserved for future expansion" on 65CE02) + asw $1234 ; $cb (wai on W65C02) + phz ; $db (stp on W65C02) + + .endscope +.endif + + +; TODO: MEGA65 +; The m65 instruction set extends the 4502 instruction set using prefix bytes. +; Therefore, the "normal" opcode table is the same as for the 4502 cpu + + +; The HUC6280 is a superset of the R65C02. It adds some other instructions: + +.if (.cpu .bitand CPU_ISET_HUC6280) + .scope + + ; added to R65C02 + sxy ; $02 + st0 #$12 ; $03 + st1 #$12 ; $13 + sax ; $22 + st2 #$12 ; $23 + say ; $42 + tma #$10 ; $43 + bsr LABEL ; $44 + tam #$12 ; $53 + csl ; $54 + cla ; $62 + tii $1234, $5678, $9abc ; $73 +LABEL: + clx ; $82 + tst #$12, $34 ; $83 + clx ; $82 + tst #$12, $34 ; $83 + tst #$12, $3456 ; $93 + tst #$12, $34, x ; $a3 + tst #$12, $3456, x ; $b3 + cly ; $c2 + tdd $1234, $5678, $9abc ; $c3 + tin $1234, $5678, $9abc ; $d3 + csh ; $d4 + tia $1234, $5678, $9abc ; $e3 + tai $1234, $5678, $9abc ; $f3 + set ; $f4 + + .endscope +.endif + + +.if (.cpu .bitand CPU_ISET_M740) + .scope + ; Mitsubishi M740 - adds new instructions to 65SC02 (but also removes some) + + jsr ($12) ; $02 + bbs0 a, LABEL ; $03 + bbs0 $12, LABEL ; $07 + seb0 a ; $0b + seb0 $12 ; $0f + bbc0 a, LABEL ; $13 + bbc0 $12, LABEL ; $17 + clb0 a ; $1b + clb0 $12 ; $1f + jsr $ff12 ; $22 + bbs1 a, LABEL ; $23 + bbs1 $12, LABEL ; $27 + seb1 a ; $2b + seb1 $12 ; $2f + bbc1 a, LABEL ; $33 + bbc1 $12, LABEL ; $37 + clb1 a ; $3b + clb1 $12 ; $3f + stp ; $42 + bbs2 a, LABEL ; $43 + com $12 ; $44 + bbs2 $12, LABEL ; $47 + seb2 a ; $4b + seb2 $12 ; $4f + bbc2 a, LABEL ; $53 + bbc2 $12, LABEL ; $57 + clb2 a ; $5b + clb2 $12 ; $5f + bbs3 a, LABEL ; $63 + bbs3 $12, LABEL ; $67 + seb3 a ; $6b + seb3 $12 ; $6f + bbc3 a, LABEL ; $73 + bbc3 $12, LABEL ; $77 + clb3 a ; $7b + clb3 $12 ; $7f +LABEL: + rrf $12 ; $82 + bbs4 a, LABEL ; $83 + bbs4 $12, LABEL ; $87 + seb4 a ; $8b + seb4 $12 ; $8f + bbc4 a, LABEL ; $93 + bbc4 $12, LABEL ; $97 + clb4 a ; $9b + clb4 $12 ; $9f + bbs5 a, LABEL ; $a3 + bbs5 $12, LABEL ; $a7 + seb5 a ; $ab + seb5 $12 ; $af + bbc5 a, LABEL ; $b3 + bbc5 $12, LABEL ; $b7 + clb5 a ; $bb + clb5 $12 ; $bf + slw ; $c2 + bbs6 a, LABEL ; $c3 + bbs6 $12, LABEL ; $c7 + seb6 a ; $cb + seb6 $12 ; $cf + bbc6 a, LABEL ; $d3 + bbc6 $12, LABEL ; $d7 + clb6 a ; $db + clb6 $12 ; $df + fst ; $e2 + bbs7 a, LABEL ; $e3 + bbs7 $12, LABEL ; $e7 + seb7 a ; $eb + seb7 $12 ; $ef + bbc7 a, LABEL ; $f3 + bbc7 $12, LABEL ; $f7 + clb7 a ; $fb + clb7 $12 ; $ff + + ; replaced from 65SC02 + clt ; $12 + set ; $32 + ldm $12, #$34 ; $3c + tst $12 ; $64 + + ; removed from 65SC02 (replaced by new) + ; ora ($12) ; $12 + ; and ($12) ; $32 + ; bit $1234,x ; $3c + ; stz $12 ; $64 + + ; removed from 65SC02 + ; tsb $12 ; $04 + ; tsb $1234 ; $0c + ; trb $12 ; $14 + ; trb $1234 ; $1c + ; bit $12,y ; $34 + ; eor ($12) ; $52 + ; phy ; $5a + ; adc ($12) ; $72 + ; stz $12,y ; $74 + ; ply ; $7a + ; jmp ($1234) ; $7c + ; bit #$12 ; $89 + ; sta ($12) ; $92 + ; stz $1234 ; $9c + ; stz $1234,x ; $9e + ; cmp ($12) ; $d2 + ; phx ; $da + ; sbc ($12) ; $f2 + ; plx ; $fa + + .endscope +.endif + diff --git a/test/asm/cpudetect/cpudetect.s b/test/asm/cpudetect/cpudetect.s index 35f925cdf..a017e652d 100644 --- a/test/asm/cpudetect/cpudetect.s +++ b/test/asm/cpudetect/cpudetect.s @@ -84,6 +84,12 @@ .byte 0,"CPU_ISET_M740" .endif +; FIXME: something with 65816 is quirky +.if (.not .cpu .bitand CPU_ISET_65816) + .include "allinst.inc" +.endif + + ; step 3: switch through all supported cpus to verify the pseudo-op is there .p02 From 54f63a0cdc9c2b52e03ceb9939313365ee83914b Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 19 Jun 2025 09:11:30 +0200 Subject: [PATCH 542/707] Fix the behavior of variable symbols in regard to cheap locals. Previously every assignment to a variable symbol opened the same scope for cheap locals. So when redefining a variable symbol, an old cheap local scope was reopened which was unexpected and confusing. The change fixes this so that only the first definition of a variable symbol opens a new scope for cheap locals, but redefinitions of the same symbol do not. --- src/ca65/symentry.c | 9 +++++++-- test/asm/err/bug505.s | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 test/asm/err/bug505.s diff --git a/src/ca65/symentry.c b/src/ca65/symentry.c index 1048bfbc2..c57fcff2a 100644 --- a/src/ca65/symentry.c +++ b/src/ca65/symentry.c @@ -211,6 +211,8 @@ static void SymReplaceExprRefs (SymEntry* S) void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags) /* Define a new symbol */ { + int Redef = 0; /* Flag for symbol redefinition */ + if (S->Flags & SF_IMPORT) { /* Defined symbol is marked as imported external symbol */ Error ("Symbol '%m%p' is already an import", GetSymName (S)); @@ -238,6 +240,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags */ FreeExpr (S->Expr); S->Expr = 0; + Redef = 1; } } @@ -291,8 +294,10 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags } } - /* If this is not a local symbol, remember it as the last global one */ - if ((S->Flags & SF_LOCAL) == 0) { + /* If this is not a local symbol and not a redefinition for a variable + ** symbol, remember it as the last global one. + */ + if ((S->Flags & SF_LOCAL) == 0 && !Redef) { SymLast = S; } } diff --git a/test/asm/err/bug505.s b/test/asm/err/bug505.s new file mode 100644 index 000000000..3125f3966 --- /dev/null +++ b/test/asm/err/bug505.s @@ -0,0 +1,28 @@ +; Test for #525 taken from the issue +; Redefining a variable symbol "reopens" the old name space for cheap locals +; Behavior should be: First definition of a variable symbol opens a new +; scope for cheap locals, redefinitions of the same symbols do not. + +;this starts a new scope for cheap local lables +SomeSymbol .set 4 + + jmp @CheapLocal1 + +@CheapLocal0: + + .byte $8b + +CheapLocalScopeBreaker0: + +CheapLocalScopeBreaker1: + +CheapLocalScopeBreaker2: + +CheapLocalScopeBreaker3: + +;this continues the same cheap scope as before, regardless of the many global labels in between +SomeSymbol .set 5 + +@CheapLocal1: + + lda @CheapLocal0 From 758bdaa4aded54aa27af5ba40af239e0a60d7c58 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 19 Jun 2025 17:59:30 +0200 Subject: [PATCH 543/707] Fixed a typo in the test source. --- test/asm/err/bug505.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/asm/err/bug505.s b/test/asm/err/bug505.s index 3125f3966..8cb0e2f18 100644 --- a/test/asm/err/bug505.s +++ b/test/asm/err/bug505.s @@ -1,6 +1,6 @@ -; Test for #525 taken from the issue +; Test for #505 taken from the issue ; Redefining a variable symbol "reopens" the old name space for cheap locals -; Behavior should be: First definition of a variable symbol opens a new +; Behavior should be: First definition of a variable symbol opens a new ; scope for cheap locals, redefinitions of the same symbols do not. ;this starts a new scope for cheap local lables From 8d763abe9298d9f567f8141fed38d1ed11f76ce2 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 19 Jun 2025 19:58:36 +0200 Subject: [PATCH 544/707] Add notes on TGI_COLOR_BLACK and TGI_COLOR_WHITE --- doc/tgi.sgml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/doc/tgi.sgml b/doc/tgi.sgml index 182ce2807..96709ae31 100644 --- a/doc/tgi.sgml +++ b/doc/tgi.sgml @@ -220,8 +220,12 @@ original aspect ratio. <tag/Header/<tt/<ref id="tgi.h" name="tgi.h">/ <tag/Declaration/<tt/unsigned char tgi_getcolor (void);/ <tag/Description/The actual color is an index to a palette. During tgi_init -you will get a default palette. Note that both the number of colors, and also -the available colors, depend on the platform. +you will get a default palette. +A default palette has always two entries with values equal to TGI_COLOR_BLACK +and TGI_COLOR_WHITE. However, which default palette entries have those two +values is target specific. +Note that both the number of colors, and also the available colors, depend on +the target and/or driver. <tag/Availability/cc65 <tag/See also/<ref id="tgi_setcolor" name="tgi_setcolor">, <ref id="tgi_setpalette" name="tgi_setpalette"> @@ -893,7 +897,9 @@ Palette is a pointer to as many entries as there are colors. <tag/Description/Set the palette (not available with all drivers/hardware). Palette is a pointer to as many entries as there are colors. The values in the palette are target specific, some (hopefully, more or less) portable values are -defined in the TGI_COLOR_XY defines. +defined in the TGI_COLOR_XY defines. Note that different platforms provide +different colors, only TGI_COLOR_BLACK and TGI_COLOR_WHITE are guaranteed to +exist (needed for the default palette). <tag/Notes/<itemize> <item>The function is only available as fastcall function, so it may only be used in presence of a prototype. From ec0595ad2834c60105a0d9e319d6d0b61d7e67d3 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Thu, 19 Jun 2025 19:51:22 +0200 Subject: [PATCH 545/707] Remove useless code LOSCR is a valid and safe softswitch on any Apple II. Thanks Oliver S! --- libsrc/apple2/tgi/a2.hi.s | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libsrc/apple2/tgi/a2.hi.s b/libsrc/apple2/tgi/a2.hi.s index 27c494421..0398701eb 100644 --- a/libsrc/apple2/tgi/a2.hi.s +++ b/libsrc/apple2/tgi/a2.hi.s @@ -222,14 +222,9 @@ DONE: bit TXTSET bit LOWSCR - .ifndef __APPLE2ENH__ - bit machinetype - bpl reset_wndtop - .endif ; Limit SET80COL-HISCR to text bit LORES -reset_wndtop: ; Reset the text window top lda #$00 sta WNDTOP From 02e79d35d73efd31522b5eab986d1919e3560bba Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 19 Jun 2025 21:44:14 +0200 Subject: [PATCH 546/707] no need to fix the assembler, but making da65 produce the same mnemonics ans ca65 uses seems like a good idea :) --- src/da65/opc6502x.c | 6 +++--- test/asm/cpudetect/allinst.inc | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/da65/opc6502x.c b/src/da65/opc6502x.c index 3bdc8a549..c5fb5888c 100644 --- a/src/da65/opc6502x.c +++ b/src/da65/opc6502x.c @@ -188,7 +188,7 @@ const OpcDesc OpcTable_6502X[256] = { { "dey", 1, flNone, OH_Implicit }, /* $88 */ { "nop", 2, flNone, OH_Immediate }, /* $89 */ { "txa", 1, flNone, OH_Implicit }, /* $8a */ - { "xaa", 2, flNone, OH_Immediate }, /* $8b */ + { "ane", 2, flNone, OH_Immediate }, /* $8b */ { "sty", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8c */ { "sta", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8d */ { "stx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8e */ @@ -196,7 +196,7 @@ const OpcDesc OpcTable_6502X[256] = { { "bcc", 2, flLabel, OH_Relative }, /* $90 */ { "sta", 2, flUseLabel, OH_DirectIndirectY }, /* $91 */ { "jam", 1, flNone, OH_Implicit }, /* $92 */ - { "ahx", 2, flUseLabel, OH_DirectIndirectY }, /* $93 */ + { "sha", 2, flUseLabel, OH_DirectIndirectY }, /* $93 */ { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */ { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */ { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */ @@ -208,7 +208,7 @@ const OpcDesc OpcTable_6502X[256] = { { "shy", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9c */ { "sta", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9d */ { "shx", 3, flUseLabel, OH_AbsoluteY }, /* $9e */ - { "ahx", 3, flUseLabel, OH_AbsoluteY }, /* $9f */ + { "sha", 3, flUseLabel, OH_AbsoluteY }, /* $9f */ { "ldy", 2, flNone, OH_Immediate }, /* $a0 */ { "lda", 2, flUseLabel, OH_DirectXIndirect }, /* $a1 */ { "ldx", 2, flNone, OH_Immediate }, /* $a2 */ diff --git a/test/asm/cpudetect/allinst.inc b/test/asm/cpudetect/allinst.inc index d698a053e..c9abecc22 100644 --- a/test/asm/cpudetect/allinst.inc +++ b/test/asm/cpudetect/allinst.inc @@ -229,15 +229,15 @@ LABEL1: sax ($12,x) ; $83 sax $12 ; $87 nop #$12 ; $89 - ;xaa #$12 ; $8b FIXME (implement in assembler) + ane #$12 ; $8b sax $1234 ; $8f jam ; $92 - ;ahx ($12),y ; $93 FIXME (implement in assembler) + sha ($12),y ; $93 sax $12,y ; $97 tas $1234,y ; $9b shy $1234,x ; $9c shx $1234,y ; $9e - ;ahx $1234,y ; $9f FIXME (implement in assembler) + sha $1234,y ; $9f lax ($12,x) ; $a3 lax $12 ; $a7 lax #$12 ; $ab @@ -331,9 +331,10 @@ LABEL: lax $1234 ; $af lax ($12),y ; $b3 lax $12,y ; $b7 - las $1234,y ; $bb lax $1234,y ; $bf + las $1234,y ; $bb + alr #$12 ; $4b arr #$12 ; $6b From c75d1dd7df500f6b4747eaa16d10066afbcf8e9e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 19 Jun 2025 22:42:36 +0200 Subject: [PATCH 547/707] update docs with some more info about the various cpu modes --- doc/ca65.sgml | 281 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 212 insertions(+), 69 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 22f9a03cf..8991db900 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -399,7 +399,7 @@ name="--bin-include-dir">/ option on the command line. -<sect>Input format<p> +<sect>Input format<p><label id="input-format"> <sect1>Assembler syntax<p> @@ -426,21 +426,23 @@ Here are some examples for valid input lines: The assembler accepts <itemize> -<item>all valid 6502 mnemonics when in 6502 mode (the default or after the +<item>all valid 6502 mnemonics when in <ref id="6502-mode" name="6502 mode"> + (the default or after the <tt><ref id=".P02" name=".P02"></tt> command was given). -<item>all valid 6502 mnemonics plus a set of illegal instructions when in - <ref id="6502X-mode" name="6502X mode">. -<item>all valid 6502DTV mnemonics when in 6502DTV mode (after the +<item>all valid 6502 mnemonics, plus a set of illegal instructions, when in + <ref id="6502X-mode" name="6502X mode"> (after the + <tt><ref id=".P02X" name=".P02X"></tt> command was given). +<item>all valid 6502DTV mnemonics when in <ref id="DTV-mode" name="DTV mode"> (after the <tt><ref id=".PDTV" name=".PDTV"></tt> command was given). -<item>all valid 65SC02 mnemonics when in 65SC02 mode (after the +<item>all valid 65SC02 mnemonics when in <ref id="65SC02-mode" name="65SC02 mode"> (after the <tt><ref id=".PSC02" name=".PSC02"></tt> command was given). -<item>all valid 65C02 mnemonics when in 65C02 mode (after the +<item>all valid 65C02 mnemonics when in <ref id="65C02-mode" name="65C02 mode"> (after the <tt><ref id=".PC02" name=".PC02"></tt> command was given). -<item>all valid 65816 mnemonics when in 65816 mode (after the +<item>all valid 65816 mnemonics when in <ref id="65816-mode" name="65816 mode"> (after the <tt><ref id=".P816" name=".P816"></tt> command was given). -<item>all valid 4510 mnemonics when in 4510 mode (after the +<item>all valid 4510 mnemonics when in <ref id="4510-mode" name="4510 mode"> (after the <tt><ref id=".P4510" name=".P4510"></tt> command was given). -<item>all valid M740 mnemonics when in M740 mode (after the +<item>all valid M740 mnemonics when in <ref id="M740-mode" name="M740 mode"> (after the <tt><ref id=".PM740" name=".PM740"></tt> command was given). </itemize> @@ -453,8 +455,206 @@ byte. If omitted, the assembler will only produce only 1 byte. brk #$34 ; 2-bytes: $00 $34 </verb></tscreen> +<sect1>6502 mode<label id="6502-mode"><p> -<sect1>65816 mode<p> +In 6502 mode (which is the default) the assembler accepts all regular "legal" +6502 mnemonics and addressing modes. + +<sect1>6502X mode<label id="6502X-mode"><p> + +6502X mode is an extension to the normal 6502 mode. In this mode, several +mnemonics for undocumented instructions of the NMOS 6502 CPUs are accepted. + +Note: Since these instructions are undocumented, there are no official mnemonics +for them. + +<itemize> +<item><tt>ALR: A:=(A and #{imm})/2;</tt> +<item><tt>ANC: A:= A and #{imm};</tt> Generates opcode $0B. +<item><tt>ANE: A:= (A or CONST) and X and #{imm};</tt> +<item><tt>ARR: A:=(A and #{imm})/2;</tt> +<item><tt>AXS: X:=A and X-#{imm};</tt> +<item><tt>DCP: {addr}:={addr}-1; A-{addr};</tt> +<item><tt>ISC: {addr}:={addr}+1; A:=A-{addr};</tt> +<item><tt>JAM:</tt> +<item><tt>LAS: A,X,S:={addr} and S;</tt> +<item><tt>LAX: A,X:={addr};</tt> +<item><tt>NOP: #{imm}; zp; zp,x; abs; abs,x</tt> +<item><tt>RLA: {addr}:={addr}rol; A:=A and {addr};</tt> +<item><tt>RRA: {addr}:={addr}ror; A:=A adc {addr};</tt> +<item><tt>SAX: {addr}:=A and X;</tt> +<item><tt>SHA: {addr}:=A and X and {addr hi +1};</tt> +<item><tt>SHX: {addr}:=X and {addr hi +1};</tt> +<item><tt>SHY: {addr}:=Y and {addr hi +1};</tt> +<item><tt>SLO: {addr}:={addr}*2; A:=A or {addr};</tt> +<item><tt>SRE: {addr}:={addr}/2; A:=A xor {addr};</tt> +<item><tt>TAS: {addr}:=A and X and {addr hi +1}; SP:=A and X;</tt> +</itemize> + + +<sect1>DTV mode<label id="DTV-mode"><p> + +The C64DTV CPU is based on the 6510, but adds some instructions, and does not +support all undocumented instructions. + +<itemize> +<item><tt>bra {rel}</tt> Generates opcode $12. +<item><tt>sac #{imm}</tt> Generates opcode $32. +<item><tt>sir #{imm}</tt> Generates opcode $42. +</itemize> + +Supported undocumented instructions: + +<itemize> +<item><tt>ALR: A:=(A and #{imm})/2;</tt> +<item><tt>ANC: A:=A and #{imm};</tt> Generates opcode $0B. +<item><tt>ARR: A:=(A and #{imm})/2;</tt> +<item><tt>AXS: X:=A and X-#{imm};</tt> +<item><tt>LAS: A,X,S:={addr} and S;</tt> +<item><tt>LAX: A,X:={addr};</tt> +<item><tt>NOP: #{imm}; zp; zp,x; abs; abs,x</tt> +<item><tt>RLA: {addr}:={addr}rol; A:=A and {addr};</tt> +<item><tt>RRA: {addr}:={addr}ror; A:=A adc {addr};</tt> +<item><tt>SHX: {addr}:=X and {addr hi +1};</tt> +<item><tt>SHY: {addr}:=y and {addr hi +1};</tt> +</itemize> + + +<sect1>65SC02 mode<label id="65SC02-mode"><p> + +65SC02 mode supports all regular 6502 instructions, plus the following: + +<tscreen><verb> +$04 tsb zp +$0c tsb abs16 +$12 ora (zp) +$14 trb zp +$1a inc +$1c trb abs16 +$32 and (zp) +$34 bit zp, x +$3a dec +$3c bit abs16, x +$52 eor (zp) +$5a phy +$64 stz zp +$72 adc (zp) +$74 stz zp, x +$7a ply +$7c jmp (abs16, x) +$80 bra rel8 +$89 bit #imm8 +$92 sta (zp) +$9c stz abs16 +$9e stz abs16, x +$b2 lda (zp) +$d2 cmp (zp) +$da phx +$f2 sbc (zp) +$fa plx +</verb></tscreen> + + +<sect1>65C02 mode<label id="65C02-mode"><p> + +65C02 mode supports all "official" W65C02 opcodes. + +The R65C02 adds bit manipulation instructions: + +<tscreen><verb> +smbB zp set bit in zp location +rmbB zp reset bit in zp location +bbsB zp, rel8 branch if bit is set in zp location +bbrB zp, rel8 branch if bit is reset in zp location +</verb></tscreen> + +And the W65C02 adds those: + +<tscreen><verb> +$cb wai wait for interrupt +$db stp wait for reset +</verb></tscreen> + + +<sect1>4510 mode<label id="4510-mode"><p> + +The 4510 is a microcontroller that is the core of the Commodore C65 aka C64DX. +It contains among other functions a slightly modified 65CE02/4502 CPU, to allow +address mapping for 20 bits of address space (1 megabyte addressable area). + +The 4510 mode supports the complete (legal) 65CE02 instruction set, plus these +three, which were changed/added: +<tscreen><verb> +$5c map "4-byte NOP reserved for future expansion" on 65CE02 +$cb asw $1234 wai on W65C02 +$db phz stp on W65C02 +</verb></tscreen> + +As compared to the description of the CPU in the +<url url="http://www.zimmers.net/anonftp/pub/cbm/c65/c65manualupdated.txt.gz" +name="C65 System Specification"> +<url url="https://raw.githubusercontent.com/MEGA65/c65-specifications/master/c65manualupdated.txt" +name="(updated version)"> uses these changes: +<itemize> +<item><tt>LDA (d,SP),Y</tt> may also be written as <tt>LDA (d,S),Y</tt> +(matching the 65816 notation). +<item>All branch instruction allow now 16 bit offsets. To use a 16 bit +branch you have to prefix these with an "L" (e.g. "<tt>LBNE</tt>" instead of +"<tt>BNE</tt>"). This might change at a later implementation of the assembler. +</itemize> + +For more information about the Commodore C65/C64DX and the 4510 CPU, see +<url url="http://www.zimmers.net/anonftp/pub/cbm/c65/"> and +<url url="https://en.wikipedia.org/wiki/Commodore_65" name="Wikipedia">. + + +<sect1>HUC6280 mode<label id="HUC6280-mode"><p> + +The HUC6280 is a superset of the R65C02. It adds some other instructions: + +<tscreen><verb> +$02 sxy +$03 st0 #{imm} +$13 st1 #{imm} +$22 sax +$23 st2 #{imm} +$42 say +$43 tma #{imm} +$44 bsr {rel} +$53 tam #{imm} +$54 csl +$62 cla +$73 tii {addr}, {addr}, {addr} +$82 clx +$83 tst #{imm}, {zp} +$82 clx +$83 tst #{imm}, {zp} +$93 tst #{imm}, {addr} +$a3 tst #{imm}, {zp}, x +$b3 tst #{imm}, {addr}, x +$c2 cly +$c3 tdd {addr}, {addr}, {addr} +$d3 tin {addr}, {addr}, {addr} +$d4 csh +$e3 tia {addr}, {addr}, {addr} +$f3 tai {addr}, {addr}, {addr} +$f4 set +</verb></tscreen> + +Note that this CPU does not implement <tt>wai</tt> and <tt>stp</tt>. + + +<sect1>M740 mode<label id="M740-mode"><p> + +The M740 is a microcontroller by Mitsubishi, which was marketed for embedded +devices in the mid 80s. It is a superset of 6502, and a subset of 65SC02, plus +some new instructions. + +For more information about the M740 Controllers, see +<url url="https://en.wikipedia.org/wiki/Mitsubishi_740" name="Wikipedia">. + + +<sect1>65816 mode<label id="65816-mode"><p><p> In 65816 mode, several aliases are accepted, in addition to the official mnemonics: @@ -482,64 +682,6 @@ or two far addresses whose high byte will be used. </verb></tscreen> -<sect1>6502X mode<label id="6502X-mode"><p> - -6502X mode is an extension to the normal 6502 mode. In this mode, several -mnemonics for illegal instructions of the NMOS 6502 CPUs are accepted. Since -these instructions are illegal, there are no official mnemonics for them. The -unofficial ones are taken from <url -url="http://www.oxyron.de/html/opcodes02.html">. Please note that only the -ones marked as "stable" are supported. The following table uses information -from the mentioned web page, for more information, see there. - -<itemize> -<item><tt>ALR: A:=(A and #{imm})/2;</tt> -<item><tt>ANC: A:=A and #{imm};</tt> Generates opcode $0B. -<item><tt>ARR: A:=(A and #{imm})/2;</tt> -<item><tt>AXS: X:=A and X-#{imm};</tt> -<item><tt>DCP: {adr}:={adr}-1; A-{adr};</tt> -<item><tt>ISC: {adr}:={adr}+1; A:=A-{adr};</tt> -<item><tt>LAS: A,X,S:={adr} and S;</tt> -<item><tt>LAX: A,X:={adr};</tt> -<item><tt>RLA: {adr}:={adr}rol; A:=A and {adr};</tt> -<item><tt>RRA: {adr}:={adr}ror; A:=A adc {adr};</tt> -<item><tt>SAX: {adr}:=A and X;</tt> -<item><tt>SLO: {adr}:={adr}*2; A:=A or {adr};</tt> -<item><tt>SRE: {adr}:={adr}/2; A:=A xor {adr};</tt> -</itemize> - - -<sect1>4510 mode<p> - -The 4510 is a microcontroller that is the core of the Commodore C65 aka C64DX. -It contains among other functions a slightly modified 65CE02/4502 CPU, to allow -address mapping for 20 bits of address space (1 megabyte addressable area). -As compared to the description of the CPU in the -<url url="http://www.zimmers.net/anonftp/pub/cbm/c65/c65manualupdated.txt.gz" -name="C65 System Specification"> -<url url="https://raw.githubusercontent.com/MEGA65/c65-specifications/master/c65manualupdated.txt" -name="(updated version)"> uses these changes: -<itemize> -<item><tt>LDA (d,SP),Y</tt> may also be written as <tt>LDA (d,S),Y</tt> -(matching the 65816 notataion). -<item>All branch instruction allow now 16 bit offsets. To use a 16 bit -branch you have to prefix these with an "L" (e.g. "<tt>LBNE</tt>" instead of -"<tt>BNE</tt>"). This might change at a later implementation of the assembler. -</itemize> -For more information about the Commodore C65/C64DX and the 4510 CPU, see -<url url="http://www.zimmers.net/anonftp/pub/cbm/c65/"> and -<url url="https://en.wikipedia.org/wiki/Commodore_65" name="Wikipedia">. - - -<sect1>M740 mode<p> - -The M740 is a microcontroller by Mitsubishi, which was marketed for embedded -devices in the mid 80s. - -For more information about the M740 Controllers, see -<url url="https://en.wikipedia.org/wiki/Mitsubishi_740" name="Wikipedia">. - - <sect1>sweet16 mode<label id="sweet16-mode"><p> SWEET 16 is an interpreter for a pseudo 16 bit CPU written by Steve Wozniak @@ -4851,6 +4993,7 @@ it is possible to determine if the instruction is supported, which is the case for the 65SC02, 65C02 and 65816 CPUs (the latter two are upwards compatible to the 65SC02). +see section <ref id="6502-mode" name="6502 format"> and following. <sect1><tt>.MACPACK module</tt><p> From 4f26d6d8b73fc7a5afb9424785210c2798543760 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 19 Jun 2025 22:49:12 +0200 Subject: [PATCH 548/707] typo --- test/asm/cpudetect/allinst.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/asm/cpudetect/allinst.inc b/test/asm/cpudetect/allinst.inc index c9abecc22..ab266915e 100644 --- a/test/asm/cpudetect/allinst.inc +++ b/test/asm/cpudetect/allinst.inc @@ -429,7 +429,7 @@ LABEL: .endscope .endif -; FIXME: hack so these opcodes get fixed anyway, while 4510 is still quirky +; FIXME: hack so these opcodes get tested anyway, while 4510 is still quirky .if (.cpu .bitand CPU_ISET_65SC02) .if (.not .cpu = CPU_4510) ora ($12) ; $12 From de844d48c42d871011a394fc0ff47155fdbdd54f Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Thu, 19 Jun 2025 22:36:16 +0000 Subject: [PATCH 549/707] fixes #2714 --- src/cl65/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index 528e64e56..d1e1baa1b 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -1715,10 +1715,14 @@ int main (int argc, char* argv []) /* Link the given files if requested and if we have any */ if (DoLink && LD65.FileCount > 0) { + /* + ** Link() may not return if there's an error, so we install + ** RemoveTempFiles() as an atexit() handler. + */ + atexit(RemoveTempFiles); Link (); } - RemoveTempFiles (); if (OutputDirectory != NULL) { xfree(OutputDirectory); } From fa4d704ee85eb508b136e978b62afb4a5b92f905 Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Fri, 20 Jun 2025 17:53:52 +0200 Subject: [PATCH 550/707] Update main.c - codestyle --- src/cl65/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cl65/main.c b/src/cl65/main.c index d1e1baa1b..6f2fe03df 100644 --- a/src/cl65/main.c +++ b/src/cl65/main.c @@ -1719,7 +1719,7 @@ int main (int argc, char* argv []) ** Link() may not return if there's an error, so we install ** RemoveTempFiles() as an atexit() handler. */ - atexit(RemoveTempFiles); + atexit (RemoveTempFiles); Link (); } From 00bb9d5376ad9dd37e6a0b4e0edd73525c549994 Mon Sep 17 00:00:00 2001 From: Russell-S-Harper <russell.s.harper@gmail.com> Date: Fri, 20 Jun 2025 18:48:51 -0400 Subject: [PATCH 551/707] Edits to more closely match standard cgets --- include/conio.h | 3 ++- libsrc/conio/cgets.c | 52 +++++++++++++++++++------------------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/include/conio.h b/include/conio.h index 1bf994511..1f88ac3ce 100644 --- a/include/conio.h +++ b/include/conio.h @@ -118,10 +118,11 @@ char *cgets (char *buffer); ** - call cgets ** - buffer[1] will have the number of characters read ** - the actual string starts at buffer + 2 -** - trailing CRLF are removed ** - terminating \0 is appended ** - therefore the maximum number of characters which can be read is the size ** of the buffer - 3! +** - note: CR/LF are NOT echoed, typically a following call to cputs or +** cprintf will need "\r\n" prepended - "standard" behavior ** ** param: buffer - where to save the input ** return: buffer + 2 (i.e. start of the string) if successful, NULL otherwise diff --git a/libsrc/conio/cgets.c b/libsrc/conio/cgets.c index c0f7f8e0c..bb24f97de 100644 --- a/libsrc/conio/cgets.c +++ b/libsrc/conio/cgets.c @@ -6,12 +6,9 @@ */ #include <stddef.h> -#include <string.h> #include <conio.h> - -#ifndef CRLF -#define CRLF "\r\n" -#endif /* CRLF */ +#include <string.h> +#include <ctype.h> enum {CGETS_SIZE, CGETS_READ, CGETS_DATA, CGETS_HDR_LEN = CGETS_DATA}; @@ -25,32 +22,29 @@ char *cgets (char *buffer) ** - call cgets ** - buffer[1] will have the number of characters read ** - the actual string starts at buffer + 2 -** - trailing CRLF are removed ** - terminating \0 is appended ** - therefore the maximum number of characters which can be read is the size ** of the buffer - 3! +** - note: CR/LF are NOT echoed, typically a following call to cputs or +** cprintf will need "\r\n" prepended - this is standard behavior! ** ** param: buffer - where to save the input -** return: buffer + 2 (or start of the string) if successful, NULL otherwise -** see: cgetsx for equivalent functionality but with a saner interface! +** return: buffer + 2 (i.e. start of the string) or NULL if buffer is NULL */ { - /* Default to NULL */ - char *result = NULL; + /* Return buffer + 2 or NULL if buffer is NULL */ + char *result = buffer? buffer + CGETS_HDR_LEN: NULL; - if (buffer && buffer[CGETS_SIZE]) { + if (result) { /* Initialize just in case the caller didn't! */ buffer[CGETS_READ] = 0; buffer[CGETS_DATA] = '\0'; - /* Call cgetsx to do the real work */ - result = cgetsx (buffer + CGETS_HDR_LEN, (unsigned char)buffer[CGETS_SIZE]); + /* Call cgetsx to do the real work, ignore the result! */ + cgetsx (result, (unsigned char)buffer[CGETS_SIZE]); - /* Trim trailing CRLF and set how many characters were read */ - if (result) { - result[strcspn (result, CRLF)] = '\0'; - buffer[CGETS_READ] = (unsigned char)strlen (result); - } + /* Set how many characters were read */ + buffer[CGETS_READ] = (unsigned char)strlen (result); } /* Done */ @@ -61,8 +55,8 @@ static char *cgetsx (char *buffer, int size) /* Like fgets but specifically for the console. Stops when CR/LF or size - 1 ** characters are read. Will append a terminating \0, so at most size - 1 ** characters can be read. Note that this function could be made public and -** have features like cursor vs no-cursor, and/or echo vs echo-pwd vs no-echo -** added to extend the functionality. +** have features added like cursor vs no-cursor, echo vs echo-pwd vs no-echo, +** or CR/LF handling to extend the functionality. ** ** param: buffer - where to save the input ** param: size - the size of buffer @@ -91,27 +85,25 @@ static char *cgetsx (char *buffer, int size) x = wherex (); y = x? y: y - 1; x = x? x - 1: w; - /* Clear the character and the cursor */ + /* Clear the character */ gotoxy (x, y); - cputs (" "); + cputc (' '); gotoxy (x, y); } - /* Handle CRLF */ - } else if (strchr (CRLF, c)) { - /* Clear the cursor and advance to the next line */ - cputs (" " CRLF); - buffer[i] = c; - buffer[++i] = '\0'; - break; /* Handle regular characters */ - } else { + } else if (isprint (c)) { cputc (c); buffer[i] = c; buffer[++i] = '\0'; + /* Handle CR/LF */ + } else if (c == '\r' || c == '\n') { + buffer[i] = '\0'; + break; } } cursor (0); } + /* Done */ return (i > 0)? buffer: NULL; } From 9344d87b0502daaad4ba588f0ee22428dd39eca5 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 00:56:34 +0200 Subject: [PATCH 552/707] part of #1792 - 48GS02 assembler support --- asminc/cpu.mac | 2 + doc/ca65.sgml | 58 +++-- doc/da65.sgml | 7 +- src/ca65/condasm.c | 11 + src/ca65/ea65.c | 33 ++- src/ca65/instr.c | 317 ++++++++++++++++++++--- src/ca65/instr.h | 40 +-- src/ca65/pseudo.c | 10 + src/ca65/scanner.c | 15 +- src/ca65/token.h | 3 + src/common/cpu.c | 2 + src/common/cpu.h | 2 + test/asm/opcodes/45GS02-opcodes.ref | Bin 0 -> 878 bytes test/asm/opcodes/45GS02-opcodes.s | 377 ++++++++++++++++++++++++++++ 14 files changed, 803 insertions(+), 74 deletions(-) create mode 100644 test/asm/opcodes/45GS02-opcodes.ref create mode 100644 test/asm/opcodes/45GS02-opcodes.s diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 818d70df1..e3ab49014 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -10,6 +10,7 @@ CPU_ISET_SWEET16 = $0080 CPU_ISET_HUC6280 = $0100 CPU_ISET_M740 = $0200 CPU_ISET_4510 = $0400 +CPU_ISET_45GS02 = $0800 ; CPU capabilities CPU_NONE = CPU_ISET_NONE @@ -24,4 +25,5 @@ CPU_SWEET16 = CPU_ISET_SWEET16 CPU_HUC6280 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_HUC6280 ; NOTE: 45100 replaces "wai" ($cb) and "stp" ($db) of the 65C02 instruction set CPU_4510 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_4510 +CPU_45GS02 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_4510|CPU_ISET_45GS02 CPU_M740 = CPU_ISET_6502|CPU_ISET_M740 diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 8991db900..8c0c4fa61 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -152,7 +152,7 @@ Here is a description of all the command line options: Set the default for the CPU type. The option takes a parameter, which may be one of - 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510, M740 + 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510, 45GS02, M740 <label id="option-create-dep"> @@ -442,6 +442,8 @@ The assembler accepts <tt><ref id=".P816" name=".P816"></tt> command was given). <item>all valid 4510 mnemonics when in <ref id="4510-mode" name="4510 mode"> (after the <tt><ref id=".P4510" name=".P4510"></tt> command was given). +<item>all valid 45GS02 mnemonics when in <ref id="45GS02-mode" name="45GS02 mode"> (after the + <tt><ref id=".P45GS02" name=".P45GS02"></tt> command was given). <item>all valid M740 mnemonics when in <ref id="M740-mode" name="M740 mode"> (after the <tt><ref id=".PM740" name=".PM740"></tt> command was given). </itemize> @@ -607,6 +609,11 @@ For more information about the Commodore C65/C64DX and the 4510 CPU, see <url url="http://www.zimmers.net/anonftp/pub/cbm/c65/"> and <url url="https://en.wikipedia.org/wiki/Commodore_65" name="Wikipedia">. +<sect1>45GS02 mode<label id="45GS02-mode"><p> + +The 45GS02 is a microcontroller that is the core of the MEGA65. +It is an extension of the 4510 CPU and adds 32-bit addressing and a 32-bit +pseudo register Q that is comprised of the four registers A, X, Y, and Z. <sect1>HUC6280 mode<label id="HUC6280-mode"><p> @@ -3399,6 +3406,12 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH (see <tt><ref id=".P4510" name=".P4510"></tt> command). +<sect1><tt>.IFP45GS02</tt><label id=".IFP45GS02"><p> + + Conditional assembly: Check if the assembler is currently in 45GS02 mode + (see <tt><ref id=".P45GS02" name=".P45GS02"></tt> command). + + <sect1><tt>.IFP816</tt><label id=".IFP816"><p> Conditional assembly: Check if the assembler is currently in 65816 mode @@ -3782,8 +3795,9 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" <tt><ref id="option--cpu" name="--cpu"></tt> command line option. 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> + name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt>, + <tt><ref id=".P4510" name=".P4510"></tt>, and + <tt><ref id=".P45GS02" name=".P45GS02"></tt> <sect1><tt>.P02X</tt><label id=".P02X"><p> @@ -3802,19 +3816,30 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" 6502 instruction sets. See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02" - name=".PSC02"></tt>, <tt><ref id=".PC02" name=".PC02"></tt> and - <tt><ref id=".P816" name=".P816"></tt> + name=".PSC02"></tt>, <tt><ref id=".PC02" name=".PC02"></tt>, + <tt><ref id=".P816" name=".P816"></tt>, and + <tt><ref id=".P45GS02" name=".P45GS02"></tt> +<sect1><tt>.P45GS02</tt><label id=".P45GS02"><p> + + Enable the 45GS02 instruction set. This is a superset of the 4510, 65C02, and + 6502 instruction sets. + + See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02" + name=".PSC02"></tt>, <tt><ref id=".PC02" name=".PC02"></tt>, + <tt><ref id=".P816" name=".P816"></tt>, and + <tt><ref id=".P4510" name=".P4510"></tt> + <sect1><tt>.P816</tt><label id=".P816"><p> Enable the 65816 instruction set. This is a superset of the 65SC02 and 6502 instruction sets. See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02" - name=".PSC02"></tt>, <tt><ref id=".PC02" name=".PC02"></tt> and - <tt><ref id=".P4510" name=".P4510"></tt> - + name=".PSC02"></tt>, <tt><ref id=".PC02" name=".PC02"></tt>, + <tt><ref id=".P4510" name=".P4510"></tt>, and + <tt><ref id=".P45GS02" name=".P45GS02"></tt> <sect1><tt>.PAGELEN, .PAGELENGTH</tt><label id=".PAGELENGTH"><p> @@ -3841,9 +3866,9 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" 6502 and 65SC02 instructions. See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02" - name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt> and - <tt><ref id=".P4510" name=".P4510"></tt> - + name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt>, + <tt><ref id=".P4510" name=".P4510"></tt>, and + <tt><ref id=".P45GS02" name=".P45GS02"></tt> <sect1><tt>.PDTV</tt><label id=".PDTV"><p> @@ -3946,9 +3971,9 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" 6502 instructions. See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PC02" - name=".PC02"></tt>, <tt><ref id=".P816" name=".P816"></tt> and - <tt><ref id=".P4510" name=".P4510"></tt> - + name=".PC02"></tt>, <tt><ref id=".P816" name=".P816"></tt>, + <tt><ref id=".P4510" name=".P4510"></tt>, and + <tt><ref id=".P45GS02" name=".P45GS02"></tt> <sect1><tt>.PUSHCHARMAP</tt><label id=".PUSHCHARMAP"><p> @@ -4195,7 +4220,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" Switch the CPU instruction set. The command is followed by a string that specifies the CPU. Possible values are those that can also be supplied to the <tt><ref id="option--cpu" name="--cpu"></tt> command line option, - namely: 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, 4510, HuC6280 and m740. + namely: 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, 4510, 45GS02, HuC6280 and m740. See: <tt><ref id=".CPU" name=".CPU"></tt>, <tt><ref id=".IFP02" name=".IFP02"></tt>, @@ -4209,6 +4234,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" <tt><ref id=".P02X" name=".P02X"></tt>, <tt><ref id=".P816" name=".P816"></tt>, <tt><ref id=".P4510" name=".P4510"></tt>, + <tt><ref id=".P45GS02" name=".P45GS02"></tt>, <tt><ref id=".PC02" name=".PC02"></tt>, <tt><ref id=".PM740" name=".PM740"></tt>, <tt><ref id=".PSC02" name=".PSC02"></tt> @@ -4948,6 +4974,7 @@ each supported CPU a constant similar to CPU_SWEET16 CPU_HUC6280 CPU_4510 + CPU_45GS02 CPU_6502DTV CPU_M740 </verb></tscreen> @@ -4964,6 +4991,7 @@ another constant is defined: CPU_ISET_SWEET16 CPU_ISET_HUC6280 CPU_ISET_4510 + CPU_ISET_45GS02 CPU_ISET_6502DTV CPU_ISET_M740 </verb></tscreen> diff --git a/doc/da65.sgml b/doc/da65.sgml index b72cd9b66..5da65d82c 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -118,13 +118,14 @@ Here is a description of all the command line options: <item>65816 <item>huc6280 <item>4510 + <item>45GS02 <item>m740 </itemize> 6502x is for the NMOS 6502 with unofficial opcodes. 6502dtv is for the emulated CPU of the C64DTV device. huc6280 is the CPU of the PC engine. - 4510 is the CPU of the Commodore C65. 65816 is the CPU of the SNES. M740 is a - Microcontroller by Mitsubishi. + 4510 is the CPU of the Commodore C65. 45GS02 is the CPU of the MEGA65. + 65816 is the CPU of the SNES. M740 is a Microcontroller by Mitsubishi. <label id="option--formfeeds"> @@ -265,6 +266,8 @@ can produce output that can not be re-assembled, when one or more of those branches point outside of the disassembled memory. This can happen when text or binary data is processed. +Disassembling 45GS02 compound instructions currently not supported. + The 65816 support requires annotating ranges with the M and X flag states. This can be recorded with an emulator that supports Code and Data Logging, for example. Disassemble one bank at a time. diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index a65fbebba..c63e54e3a 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -414,6 +414,16 @@ void DoConditionals (void) CalcOverallIfCond (); break; + case TOK_IFP45GS02: + D = AllocIf (".IFP45GS02", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_45GS02); + } + ExpectSep (); + CalcOverallIfCond (); + break; + case TOK_IFP816: D = AllocIf (".IFP816", 1); NextTok (); @@ -507,6 +517,7 @@ int CheckConditionals (void) case TOK_IFP02: case TOK_IFP02X: case TOK_IFP4510: + case TOK_IFP45GS02: case TOK_IFP816: case TOK_IFPC02: case TOK_IFPDTV: diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c index da11b268a..0e20ccff9 100644 --- a/src/ca65/ea65.c +++ b/src/ca65/ea65.c @@ -101,6 +101,9 @@ void GetEA (EffAddr* A) if (TokIsSep (CurTok.Tok)) { A->AddrModeSet = AM65_IMPLICIT; + if (GetCPU() == CPU_45GS02) { + A->AddrModeSet |= AM65_Q; + } } else if (CurTok.Tok == TOK_HASH) { @@ -114,6 +117,11 @@ void GetEA (EffAddr* A) NextTok (); A->AddrModeSet = AM65_ACCU; + } else if (CurTok.Tok == TOK_Q) { + + NextTok (); + A->AddrModeSet = AM65_Q; + } else if (CurTok.Tok == IndirectEnter) { /* One of the indirect modes */ @@ -160,8 +168,19 @@ void GetEA (EffAddr* A) } } else { /* (adr) */ - A->AddrModeSet = (CPU == CPU_4510) ? AM65_ABS_IND - : AM65_ABS_IND | AM65_ABS_IND_LONG | AM65_DIR_IND; + switch (CPU) { + case CPU_4510: + A->AddrModeSet = AM65_ABS_IND; + break; + + case CPU_45GS02: + A->AddrModeSet = AM65_ABS_IND | AM65_DIR_IND; + break; + + default: + A->AddrModeSet = AM65_ABS_IND | AM65_ABS_IND_LONG | AM65_DIR_IND; + break; + } } } @@ -175,8 +194,14 @@ void GetEA (EffAddr* A) if (CurTok.Tok == TOK_COMMA) { /* [dir],y */ NextTok (); - Consume (TOK_Y, "'Y' expected"); - A->AddrModeSet = AM65_DIR_IND_LONG_Y; + if (GetCPU() == CPU_45GS02) { + Consume(TOK_Z, "'Z' expected"); + A->AddrModeSet = AM65_32BIT_BASE_IND_Z; + } + else { + Consume(TOK_Y, "'Y' expected"); + A->AddrModeSet = AM65_DIR_IND_LONG_Y; + } } else { /* [dir] */ A->AddrModeSet = AM65_DIR_IND_LONG | AM65_ABS_IND_LONG; diff --git a/src/ca65/instr.c b/src/ca65/instr.c index f94740dcb..8e1b4b456 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -154,6 +154,12 @@ static void PutAll (const InsDesc* Ins); static void Put4510 (const InsDesc* Ins); /* Handle instructions of 4510 not matching any EATab */ +static void Put45GS02 (const InsDesc* Ins); +/* Handle [adr],z instructions of 45GS02 */ + +static void Put45GS02_Q (const InsDesc* Ins); +/* Handle Q instructions of 45GS02 */ + static void PutSweet16 (const InsDesc* Ins); /* Handle a generic sweet16 instruction */ @@ -758,6 +764,170 @@ static const struct { } }; + +/* Instruction table for the 45GS02 */ +static const struct { + unsigned Count; + InsDesc Ins[149]; +} InsTab45GS02 = { + /* CAUTION: table must be sorted for bsearch */ + sizeof (InsTab45GS02.Ins) / sizeof (InsTab45GS02.Ins[0]), + { +/* BEGIN SORTED.SH */ + { "ADC", 0x4080A66C, 0x60, 0, Put45GS02 }, + { "ADCQ", 0x0000140C, 0x60, 13, Put45GS02_Q }, + { "AND", 0x4080A66C, 0x20, 0, Put45GS02 }, + { "ANDQ", 0x0000140C, 0x20, 13, Put45GS02_Q }, + { "ASL", 0x0000006e, 0x02, 1, PutAll }, + { "ASLQ", 0x800000ec, 0x00, 14, Put45GS02_Q }, + { "ASR", 0x00000026, 0x43, 0, Put4510 }, + { "ASRQ", 0x80000024, 0x40, 15, Put45GS02_Q }, + { "ASW", 0x00000008, 0xcb, 6, PutAll }, + { "BBR0", 0x00000000, 0x0F, 0, PutBitBranch }, + { "BBR1", 0x00000000, 0x1F, 0, PutBitBranch }, + { "BBR2", 0x00000000, 0x2F, 0, PutBitBranch }, + { "BBR3", 0x00000000, 0x3F, 0, PutBitBranch }, + { "BBR4", 0x00000000, 0x4F, 0, PutBitBranch }, + { "BBR5", 0x00000000, 0x5F, 0, PutBitBranch }, + { "BBR6", 0x00000000, 0x6F, 0, PutBitBranch }, + { "BBR7", 0x00000000, 0x7F, 0, PutBitBranch }, + { "BBS0", 0x00000000, 0x8F, 0, PutBitBranch }, + { "BBS1", 0x00000000, 0x9F, 0, PutBitBranch }, + { "BBS2", 0x00000000, 0xAF, 0, PutBitBranch }, + { "BBS3", 0x00000000, 0xBF, 0, PutBitBranch }, + { "BBS4", 0x00000000, 0xCF, 0, PutBitBranch }, + { "BBS5", 0x00000000, 0xDF, 0, PutBitBranch }, + { "BBS6", 0x00000000, 0xEF, 0, PutBitBranch }, + { "BBS7", 0x00000000, 0xFF, 0, PutBitBranch }, + { "BCC", 0x00020000, 0x90, 0, PutPCRel8 }, + { "BCS", 0x00020000, 0xb0, 0, PutPCRel8 }, + { "BEQ", 0x00020000, 0xf0, 0, PutPCRel8 }, + { "BIT", 0x00A0006C, 0x00, 2, PutAll }, + { "BITQ", 0x0000000c, 0x20, 15, Put45GS02_Q }, + { "BMI", 0x00020000, 0x30, 0, PutPCRel8 }, + { "BNE", 0x00020000, 0xd0, 0, PutPCRel8 }, + { "BPL", 0x00020000, 0x10, 0, PutPCRel8 }, + { "BRA", 0x00020000, 0x80, 0, PutPCRel8 }, + { "BRK", 0x00000001, 0x00, 0, PutAll }, + { "BSR", 0x00040000, 0x63, 0, PutPCRel4510 }, + { "BVC", 0x00020000, 0x50, 0, PutPCRel8 }, + { "BVS", 0x00020000, 0x70, 0, PutPCRel8 }, + { "CLC", 0x00000001, 0x18, 0, PutAll }, + { "CLD", 0x00000001, 0xd8, 0, PutAll }, + { "CLE", 0x00000001, 0x02, 0, PutAll }, + { "CLI", 0x00000001, 0x58, 0, PutAll }, + { "CLV", 0x00000001, 0xb8, 0, PutAll }, + { "CMP", 0x4080A66C, 0xc0, 0, Put45GS02 }, + { "CMPQ", 0x0000140C, 0xC0, 13, Put45GS02_Q }, + { "CPX", 0x0080000C, 0xe0, 1, PutAll }, + { "CPY", 0x0080000C, 0xc0, 1, PutAll }, + { "CPZ", 0x0080000C, 0xd0, 1, Put4510 }, + { "DEA", 0x00000001, 0x00, 3, PutAll }, /* == DEC */ + { "DEC", 0x0000006F, 0x00, 3, PutAll }, + { "DEQ", 0x800000ec, 0xc0, 14, Put45GS02_Q }, + { "DEW", 0x00000004, 0xc3, 9, PutAll }, + { "DEX", 0x00000001, 0xca, 0, PutAll }, + { "DEY", 0x00000001, 0x88, 0, PutAll }, + { "DEZ", 0x00000001, 0x3B, 0, PutAll }, + { "EOM", 0x00000001, 0xea, 0, PutAll }, + { "EOR", 0x4080A66C, 0x40, 0, Put45GS02 }, + { "EORQ", 0x0000140C, 0x40, 13, Put45GS02_Q }, + { "INA", 0x00000001, 0x00, 4, PutAll }, /* == INC */ + { "INC", 0x0000006f, 0x00, 4, PutAll }, + { "INQ", 0x800000ec, 0xe0, 14, Put45GS02_Q }, + { "INW", 0x00000004, 0xe3, 9, PutAll }, + { "INX", 0x00000001, 0xe8, 0, PutAll }, + { "INY", 0x00000001, 0xc8, 0, PutAll }, + { "INZ", 0x00000001, 0x1B, 0, PutAll }, + { "JMP", 0x00010808, 0x4c, 6, PutAll }, + { "JSR", 0x00010808, 0x20, 7, Put4510 }, + { "LBCC", 0x00040000, 0x93, 0, PutPCRel4510 }, + { "LBCS", 0x00040000, 0xb3, 0, PutPCRel4510 }, + { "LBEQ", 0x00040000, 0xf3, 0, PutPCRel4510 }, + { "LBMI", 0x00040000, 0x33, 0, PutPCRel4510 }, + { "LBNE", 0x00040000, 0xd3, 0, PutPCRel4510 }, + { "LBPL", 0x00040000, 0x13, 0, PutPCRel4510 }, + { "LBRA", 0x00040000, 0x83, 0, PutPCRel4510 }, + { "LBVC", 0x00040000, 0x53, 0, PutPCRel4510 }, + { "LBVS", 0x00040000, 0x73, 0, PutPCRel4510 }, + { "LDA", 0x4090A66C, 0xa0, 0, Put45GS02 }, + { "LDQ", 0x4000140C, 0xa0, 13, Put45GS02_Q }, + { "LDX", 0x0080030C, 0xa2, 1, PutAll }, + { "LDY", 0x0080006C, 0xa0, 1, PutAll }, + { "LDZ", 0x00800048, 0xa3, 1, Put4510 }, + { "LSR", 0x0000006F, 0x42, 1, PutAll }, + { "LSRQ", 0x800000ec, 0x40, 14, Put45GS02_Q }, + { "MAP", 0x00000001, 0x5C, 0, PutAll }, + { "NEG", 0x00000001, 0x42, 0, PutAll }, + { "NOP", 0x00000001, 0xea, 0, PutAll }, /* == EOM */ + { "ORA", 0x4080A66C, 0x00, 0, Put45GS02 }, + { "ORQ", 0x0000140C, 0x00, 13, Put45GS02_Q }, + { "PHA", 0x00000001, 0x48, 0, PutAll }, + { "PHD", 0x08000008, 0xf4, 1, PutAll }, /* == PHW */ + { "PHP", 0x00000001, 0x08, 0, PutAll }, + { "PHW", 0x08000008, 0xf4, 1, PutAll }, + { "PHX", 0x00000001, 0xda, 0, PutAll }, + { "PHY", 0x00000001, 0x5a, 0, PutAll }, + { "PHZ", 0x00000001, 0xdb, 0, PutAll }, + { "PLA", 0x00000001, 0x68, 0, PutAll }, + { "PLP", 0x00000001, 0x28, 0, PutAll }, + { "PLX", 0x00000001, 0xfa, 0, PutAll }, + { "PLY", 0x00000001, 0x7a, 0, PutAll }, + { "PLZ", 0x00000001, 0xfb, 0, PutAll }, + { "RMB0", 0x00000004, 0x07, 1, PutAll }, + { "RMB1", 0x00000004, 0x17, 1, PutAll }, + { "RMB2", 0x00000004, 0x27, 1, PutAll }, + { "RMB3", 0x00000004, 0x37, 1, PutAll }, + { "RMB4", 0x00000004, 0x47, 1, PutAll }, + { "RMB5", 0x00000004, 0x57, 1, PutAll }, + { "RMB6", 0x00000004, 0x67, 1, PutAll }, + { "RMB7", 0x00000004, 0x77, 1, PutAll }, + { "ROL", 0x0000006F, 0x22, 1, PutAll }, + { "ROLQ", 0x800000ec, 0x20, 14, Put45GS02_Q }, + { "ROR", 0x0000006F, 0x62, 1, PutAll }, + { "RORQ", 0x800000ec, 0x60, 14, Put45GS02_Q }, + { "ROW", 0x00000008, 0xeb, 6, PutAll }, + { "RTI", 0x00000001, 0x40, 0, PutAll }, + { "RTN", 0x00800000, 0x62, 1, PutAll }, + { "RTS", 0x00000001, 0x60, 0, PutAll }, + { "SBC", 0x4080A66C, 0xe0, 0, Put45GS02 }, + { "SBCQ", 0x0000140C, 0xe0, 13, Put45GS02_Q }, + { "SEC", 0x00000001, 0x38, 0, PutAll }, + { "SED", 0x00000001, 0xf8, 0, PutAll }, + { "SEE", 0x00000001, 0x03, 0, PutAll }, + { "SEI", 0x00000001, 0x78, 0, PutAll }, + { "SMB0", 0x00000004, 0x87, 1, PutAll }, + { "SMB1", 0x00000004, 0x97, 1, PutAll }, + { "SMB2", 0x00000004, 0xA7, 1, PutAll }, + { "SMB3", 0x00000004, 0xB7, 1, PutAll }, + { "SMB4", 0x00000004, 0xC7, 1, PutAll }, + { "SMB5", 0x00000004, 0xD7, 1, PutAll }, + { "SMB6", 0x00000004, 0xE7, 1, PutAll }, + { "SMB7", 0x00000004, 0xF7, 1, PutAll }, + { "STA", 0x4010A66C, 0x80, 0, Put45GS02 }, + { "STQ", 0x0000140C, 0x80, 13, Put45GS02_Q }, + { "STX", 0x0000030c, 0x82, 1, Put4510 }, + { "STY", 0x0000006c, 0x80, 1, Put4510 }, + { "STZ", 0x0000006c, 0x04, 5, PutAll }, + { "TAB", 0x00000001, 0x5b, 0, PutAll }, + { "TAX", 0x00000001, 0xaa, 0, PutAll }, + { "TAY", 0x00000001, 0xa8, 0, PutAll }, + { "TAZ", 0x00000001, 0x4b, 0, PutAll }, + { "TBA", 0x00000001, 0x7b, 0, PutAll }, + { "TRB", 0x0000000c, 0x10, 1, PutAll }, + { "TSB", 0x0000000c, 0x00, 1, PutAll }, + { "TSX", 0x00000001, 0xba, 0, PutAll }, + { "TSY", 0x00000001, 0x0b, 0, PutAll }, + { "TXA", 0x00000001, 0x8a, 0, PutAll }, + { "TXS", 0x00000001, 0x9a, 0, PutAll }, + { "TYA", 0x00000001, 0x98, 0, PutAll }, + { "TYS", 0x00000001, 0x2b, 0, PutAll }, + { "TZA", 0x00000001, 0x6b, 0, PutAll }, +/* END SORTED.SH */ + } +}; + + /* Instruction table for the 65816 */ static const struct { unsigned Count; @@ -1192,6 +1362,7 @@ static const InsTable* InsTabs[CPU_COUNT] = { (const InsTable*) &InsTabHuC6280, (const InsTable*) &InsTabm740, /* Mitsubishi 740 */ (const InsTable*) &InsTab4510, + (const InsTable*) &InsTab45GS02, }; const InsTable* InsTab = (const InsTable*) &InsTab6502; @@ -1199,85 +1370,103 @@ const InsTable* InsTab = (const InsTable*) &InsTab6502; ** addressing mode. (The value in the table is ORed with the base opcode) ** NOTE: each table has one entry per addressing mode! */ -static unsigned char EATab[14][AM65I_COUNT] = { +static unsigned char EATab[16][AM65I_COUNT] = { { /* Table 0 (sec, sed, seo, set, slw, sta, stp, tax, tay, tsx, txa, txs, tya) */ 0x00, 0x00, 0x05, 0x0D, 0x0F, 0x15, 0x1D, 0x1F, 0x00, 0x19, 0x12, 0x00, 0x07, 0x11, 0x17, 0x01, 0x00, 0x00, 0x00, 0x03, 0x13, 0x09, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00 }, { /* Table 1 (rol, ror, stx, sty, tst) */ 0x08, 0x08, 0x04, 0x0C, 0x00, 0x14, 0x1C, 0x00, 0x14, 0x1C, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 2 (bit) */ 0x00, 0x00, 0x24, 0x2C, 0x0F, 0x34, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 3 (dec, dea) */ 0x3A, 0x3A, 0xC6, 0xCE, 0x00, 0xD6, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 4 (inc) */ 0x1A, 0x1A, 0xE6, 0xEE, 0x00, 0xF6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 5 (stz) */ 0x00, 0x00, 0x60, 0x98, 0x00, 0x70, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 6 (jmp, rrf) */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x90, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 7 (jsr) */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 8 */ 0x00, 0x40, 0x01, 0x41, 0x00, 0x09, 0x49, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 9 (dew, inw) */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 10 (NOPs, clbX, sebX) */ 0xea, 0x00, 0x04, 0x0c, 0x00, 0x14, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 11 (LAX) */ 0x08, 0x08, 0x04, 0x0C, 0x00, 0x14, 0x1C, 0x00, 0x14, 0x1C, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 }, { /* Table 12 (m740: JMP) */ 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { /* Table 13 (Q) */ + 0x00, 0x00, 0x05, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00 + }, + { /* Table 14 (Q) */ + 0x00, 0x00, 0x06, 0x0e, 0x00, 0x16, 0x1e, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a + }, + { /* Table 15 */ + 0x00, 0x00, 0x04, 0x0c, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 + } }; /* Table to build the effective SWEET16 opcode from a base opcode and an @@ -1325,6 +1514,8 @@ unsigned char ExtBytes[AM65I_COUNT] = { 2, /* Immidiate word */ 2, /* Direct, Relative short */ 1, /* Special Page */ + 1, /* [Direct],z */ + 0, /* Q */ }; /* Table that encodes the additional bytes for each SWEET16 instruction */ @@ -1968,9 +2159,7 @@ static void PutAll (const InsDesc* Ins) -static void Put4510 (const InsDesc* Ins) -/* Handle all other instructions, with modifications for 4510 */ -{ +static void Emit4510 (EffAddr* A) { /* The 4510 uses all 256 possible opcodes, so the last ones were crammed ** in where an opcode was still undefined. As a result, some of those ** don't follow any rules for encoding the addressmodes. So the EATab @@ -1990,26 +2179,90 @@ static void Put4510 (const InsDesc* Ins) ** $d0 -> $c2 : CPZ #$00 ** $fc -> $23 : JSR ($1234,X) */ + switch (A->Opcode) { + case 0x47: + A->Opcode = 0x44; + break; + case 0x57: + A->Opcode = 0x54; + break; + case 0x93: + A->Opcode = 0x82; + break; + case 0x9C: + A->Opcode = 0x8B; + break; + case 0x9E: + A->Opcode = 0x9B; + break; + case 0xAF: + A->Opcode = 0xAB; + break; + case 0xBF: + A->Opcode = 0xBB; + break; + case 0xB3: + A->Opcode = 0xE2; + break; + case 0xD0: + A->Opcode = 0xC2; + break; + case 0xFC: + A->Opcode = 0x23; + break; + default: /* Keep opcode as it is */ break; + } + + /* No error, output code */ + EmitCode(A); +} + + + +static void Put4510 (const InsDesc* Ins) +/* Handle all other instructions, with modifications for 4510 */ +{ EffAddr A; /* Evaluate the addressing mode used */ if (EvalEA (Ins, &A)) { - switch (A.Opcode) { - case 0x47: A.Opcode = 0x44; break; - case 0x57: A.Opcode = 0x54; break; - case 0x93: A.Opcode = 0x82; break; - case 0x9C: A.Opcode = 0x8B; break; - case 0x9E: A.Opcode = 0x9B; break; - case 0xAF: A.Opcode = 0xAB; break; - case 0xBF: A.Opcode = 0xBB; break; - case 0xB3: A.Opcode = 0xE2; break; - case 0xD0: A.Opcode = 0xC2; break; - case 0xFC: A.Opcode = 0x23; break; - default: /* Keep opcode as it is */ break; - } + Emit4510(&A); + } +} - /* No error, output code */ - EmitCode (&A); + + +static void Put45GS02 (const InsDesc* Ins) +/* Handle all other instructions, with modifications for 45GS02 */ +{ + EffAddr A; + + if (EvalEA(Ins, &A)) { + if (A.AddrModeSet == AM65_32BIT_BASE_IND_Z) { + Emit0(0xEA); /* NOP prefix */ + } + Emit4510(&A); + } +} + + + +static void Put45GS02_Q (const InsDesc* Ins) { + EffAddr A; + + if (EvalEA(Ins, &A)) { + Emit0(0x42); + Emit0(0x42); + if ((A.AddrModeBit == AM65_DIR_IND_LONG) || (A.AddrModeBit == AM65_32BIT_BASE_IND_Z)) { + Emit0(0xEA); /* NOP prefix */ + } + if (A.Opcode == 0xea) { + A.Opcode = 0x1a; + } + else if (A.Opcode == 0xca) { + A.Opcode = 0x3a; + } + EmitCode(&A); } } diff --git a/src/ca65/instr.h b/src/ca65/instr.h index 8e0900c77..9c91fd0cf 100644 --- a/src/ca65/instr.h +++ b/src/ca65/instr.h @@ -59,35 +59,37 @@ ** available on these CPUs are removed before doing any checks. */ #define AM65_IMPLICIT 0x00000003UL /* IMP */ -#define AM65_ACCU 0x00000002UL /* A, BIT, A */ -#define AM65_DIR 0x00000004UL /* ZP, BIT, ZP */ +#define AM65_ACCU 0x00000002UL /* A */ +#define AM65_DIR 0x00000004UL /* ZP */ #define AM65_ABS 0x00000008UL /* ABS */ -#define AM65_ABS_LONG 0x00000010UL /* -- */ +#define AM65_ABS_LONG 0x00000010UL /* adr */ #define AM65_DIR_X 0x00000020UL /* ZP,X */ #define AM65_ABS_X 0x00000040UL /* ABS, X */ -#define AM65_ABS_LONG_X 0x00000080UL /* -- */ +#define AM65_ABS_LONG_X 0x00000080UL /* adr,x */ #define AM65_DIR_Y 0x00000100UL /* ZP, Y */ #define AM65_ABS_Y 0x00000200UL /* ABS, Y */ -#define AM65_DIR_IND 0x00000400UL /* (ZP IND) */ -#define AM65_ABS_IND 0x00000800UL /* (IND) */ -#define AM65_DIR_IND_LONG 0x00001000UL /* -- */ -#define AM65_DIR_IND_Y 0x00002000UL /* IND, Y */ -#define AM65_DIR_IND_LONG_Y 0x00004000UL /* -- */ -#define AM65_DIR_X_IND 0x00008000UL /* IND, X */ -#define AM65_ABS_X_IND 0x00010000UL /* -- */ +#define AM65_DIR_IND 0x00000400UL /* (ZP) or (ZP),z (4510 / 45GS02) */ +#define AM65_ABS_IND 0x00000800UL /* (ABS) */ +#define AM65_DIR_IND_LONG 0x00001000UL /* [ABS] (65816) */ +#define AM65_DIR_IND_Y 0x00002000UL /* (ZP),y */ +#define AM65_DIR_IND_LONG_Y 0x00004000UL /* [adr],y (not 45GS02) */ +#define AM65_DIR_X_IND 0x00008000UL /* (ZP,x) */ +#define AM65_ABS_X_IND 0x00010000UL /* (ABS,x) */ #define AM65_REL 0x00020000UL /* REL */ -#define AM65_REL_LONG 0x00040000UL /* -- */ -#define AM65_STACK_REL 0x00080000UL /* SP ? */ -#define AM65_STACK_REL_IND_Y 0x00100000UL /* ? */ +#define AM65_REL_LONG 0x00040000UL /* LONGREL */ +#define AM65_STACK_REL 0x00080000UL /* adr,s */ +#define AM65_STACK_REL_IND_Y 0x00100000UL /* (rel,s),y */ #define AM65_IMM_ACCU 0x00200000UL #define AM65_IMM_INDEX 0x00400000UL #define AM65_IMM_IMPLICIT 0x00800000UL /* IMM */ -#define AM65_BLOCKMOVE 0x01000000UL /* -- */ -#define AM65_BLOCKXFER 0x02000000UL /* -- */ -#define AM65_ABS_IND_LONG 0x04000000UL /* -- */ +#define AM65_BLOCKMOVE 0x01000000UL +#define AM65_BLOCKXFER 0x02000000UL +#define AM65_ABS_IND_LONG 0x04000000UL /* (adr) [dir] */ #define AM65_IMM_IMPLICIT_WORD 0x08000000UL /* PHW #$1234 (4510 only) */ #define AM65_ZP_REL 0x10000000UL /* ZP, REL (m740) */ #define AM65_SPECIAL_PAGE 0x20000000UL /* $FFxx (m740) */ +#define AM65_32BIT_BASE_IND_Z 0x40000000UL /* LDA [$nn],Z (45GS02 only) */ +#define AM65_Q 0x80000000UL /* Q (45GS02 only) */ /* Bitmask for all ZP operations that have correspondent ABS ops */ #define AM65_SET_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND) @@ -138,7 +140,9 @@ #define AM65I_IMM_IMPLICIT_WORD 27 #define AM65I_ZP_REL 28 #define AM65I_SPECIAL_PAGE 29 -#define AM65I_COUNT 30 +#define AM65I_32BIT_BASE_IND_Z 30 +#define AM65I_Q 31 +#define AM65I_COUNT 32 diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 6cad9ed51..7e52ecb5e 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1594,6 +1594,14 @@ static void DoP4510 (void) +static void DoP45GS02 (void) +/* Switch to 45GS02 CPU */ +{ + SetCPU (CPU_45GS02); +} + + + static void DoPDTV (void) /* Switch to C64DTV CPU */ { @@ -2151,6 +2159,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccKeepToken, DoConditionals }, /* .IFP02 */ { ccKeepToken, DoConditionals }, /* .IFP02X */ { ccKeepToken, DoConditionals }, /* .IFP4510 */ + { ccKeepToken, DoConditionals }, /* .IFP45GS02 */ { ccKeepToken, DoConditionals }, /* .IFP816 */ { ccKeepToken, DoConditionals }, /* .IFPC02 */ { ccKeepToken, DoConditionals }, /* .IFPDTV */ @@ -2186,6 +2195,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoP02 }, /* .P02 */ { ccNone, DoP02X }, /* .P02X */ { ccNone, DoP4510 }, /* .P4510 */ + { ccNone, DoP45GS02 }, /* .P45GS02 */ { ccNone, DoP816 }, /* .P816 */ { ccNone, DoPageLength }, /* .PAGELEN, .PAGELENGTH */ { ccNone, DoUnexpected }, /* .PARAMCOUNT */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 0d90ddc7f..dd0209856 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -223,6 +223,7 @@ struct DotKeyword { { ".IFP02", TOK_IFP02 }, { ".IFP02X", TOK_IFP02X }, { ".IFP4510", TOK_IFP4510 }, + { ".IFP45GS02", TOK_IFP45GS02 }, { ".IFP816", TOK_IFP816 }, { ".IFPC02", TOK_IFPC02 }, { ".IFPDTV", TOK_IFPDTV }, @@ -263,6 +264,7 @@ struct DotKeyword { { ".P02", TOK_P02 }, { ".P02X", TOK_P02X }, { ".P4510", TOK_P4510 }, + { ".P45GS02", TOK_P45GS02 }, { ".P816", TOK_P816 }, { ".PAGELEN", TOK_PAGELENGTH }, { ".PAGELENGTH", TOK_PAGELENGTH }, @@ -1279,12 +1281,19 @@ Again: break; case 'S': - if ((CPU == CPU_4510) || (CPU == CPU_65816)) { + if ((CPU == CPU_4510) || (CPU == CPU_45GS02) || (CPU == CPU_65816)) { CurTok.Tok = TOK_S; return; } break; + case 'Q': + if (CPU == CPU_45GS02) { + CurTok.Tok = TOK_Q; + return; + } + break; + case 'X': CurTok.Tok = TOK_X; return; @@ -1299,7 +1308,7 @@ Again: CurTok.Tok = TOK_OVERRIDE_ZP; return; } else { - if (CPU == CPU_4510) { + if ((CPU == CPU_4510) || (CPU == CPU_45GS02)) { CurTok.Tok = TOK_Z; return; } @@ -1311,7 +1320,7 @@ Again: } break; case 2: - if ((CPU == CPU_4510) && + if ((CPU == CPU_4510 || CPU == CPU_45GS02) && (toupper (SB_AtUnchecked (&CurTok.SVal, 0)) == 'S') && (toupper (SB_AtUnchecked (&CurTok.SVal, 1)) == 'P')) { diff --git a/src/ca65/token.h b/src/ca65/token.h index d4fa3a697..9ca7ea657 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -68,6 +68,7 @@ typedef enum token_t { TOK_Y, /* Y register */ TOK_Z, /* Z register */ TOK_S, /* S register */ + TOK_Q, /* Q pseudo register */ TOK_REG, /* Sweet16 R.. register (in sweet16 mode) */ TOK_ASSIGN, /* := */ @@ -195,6 +196,7 @@ typedef enum token_t { TOK_IFP02, TOK_IFP02X, TOK_IFP4510, + TOK_IFP45GS02, TOK_IFP816, TOK_IFPC02, TOK_IFPDTV, @@ -230,6 +232,7 @@ typedef enum token_t { TOK_P02, TOK_P02X, TOK_P4510, + TOK_P45GS02, TOK_P816, TOK_PAGELENGTH, TOK_PARAMCOUNT, diff --git a/src/common/cpu.c b/src/common/cpu.c index b55a5ab00..2c29eb1c4 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -63,6 +63,7 @@ const char* CPUNames[CPU_COUNT] = { "huc6280", "m740", "4510", + "45GS02" }; /* Tables with CPU instruction sets */ @@ -78,6 +79,7 @@ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_HUC6280, CPU_ISET_6502 | CPU_ISET_M740, CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_4510, + CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_4510 | CPU_ISET_45GS02, }; diff --git a/src/common/cpu.h b/src/common/cpu.h index 2e75feaaf..6d8b72469 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -58,6 +58,7 @@ typedef enum { CPU_HUC6280, /* Used in PC engine */ CPU_M740, /* Mitsubishi 740 series MCUs */ CPU_4510, /* CPU of C65 */ + CPU_45GS02, /* CPU of MEGA65 */ CPU_COUNT /* Number of different CPUs */ } cpu_t; @@ -74,6 +75,7 @@ enum { CPU_ISET_HUC6280 = 1 << CPU_HUC6280, CPU_ISET_M740 = 1 << CPU_M740, CPU_ISET_4510 = 1 << CPU_4510, + CPU_ISET_45GS02 = 1 << CPU_45GS02 }; /* CPU used */ diff --git a/test/asm/opcodes/45GS02-opcodes.ref b/test/asm/opcodes/45GS02-opcodes.ref new file mode 100644 index 0000000000000000000000000000000000000000..a4a78d46cb8d973c2fd2c323ff195d722a3a3664 GIT binary patch literal 878 zcmWm836zgj7{_t%bLV|ugnvEvMb^p;m96*AeMm@k%|!||^d_Rn5``LBDxpF9h-smJ zwibm_8BsDtWlPy6TPdU{|FVrjihAxj_jm3&pYy%v+zOr#A`5&7AcTsQyvi3;A*@PR zjW7lJ!uX;9L#b2*)kO_a6E3cmM78VGC9G#<eJd{keJSB(egm7Go#f;|Ludq-!xdM0 zjhi$jY)06e@G8)8tb*K7D@CG(Xeq9SR@Wp^>o#qzyw=KgR$d4C`Wt-HJ`XH(fR51V zMz8ZtHxqUt>`K@T^eyqNL4Md>sUG4sk%-%&=N(DZtM{FKtn6#$U7+vo=l8F4k5U6* zAPj=RaPJUr=zaIw>|un%2}gi_Abv0?2uCXQkQgOKi!m_v;Us$G(Q!%6V^)s0asudy z@#B7BsxUQ4smU+}o`5Iesi(bXp0)Bh!Xm<{gwKPX7Ecd~!xxl#QM@Ex&YA%;UrD0$ zt4TDAaJH3mtegvap7)yny7z|nCd`Mo;B8p2&|CBl;k$&33Ev}pAM^+DlAt79s?>*K znOL6n5q!KNi9T6rWvP{)TKQQLtpdH;``rJ+`x4f`T383`VZ&G6#;*y#A>2f`nQ#l} zt?{;?Ec{lf?XW}a6uV&ecS-d9o*xK*v~sVN`#|sae)12b4y1mDU*I4df?wgc!(Jxy zJK-OMM+lD+9s_+mJ`t3MCzbj$U6IdU;*>ZIXZ}v2v;X`{$mg7u=dJt?bfy4}8OR%! zkTC^gjmZ?GGr0^6dCeT=I?PQQ6R=b^rkcYVjP*+y+Z&U|-h(ZN@1_Z5%J^Q(+vLJB z_qvS3*2b)3-0W~C<KEJACZECbx;V^tWj>d+jXA`4)Zr<{^IVoN%;zn3SmMeOE<3Pv zHm0k?gt0G|$ma8^Iz(3@myK8&8`IojOU8EY?}HeJ8Z+GCXvXpUyqxVI?})>4_q;rv PDQ1|$D{@%uusHoc1B4WF literal 0 HcmV?d00001 diff --git a/test/asm/opcodes/45GS02-opcodes.s b/test/asm/opcodes/45GS02-opcodes.s new file mode 100644 index 000000000..6d42b80c4 --- /dev/null +++ b/test/asm/opcodes/45GS02-opcodes.s @@ -0,0 +1,377 @@ +.setcpu "45GS02" + + brk + ora ($05,x) + cle + see + tsb $02 + ora $02 + asl $02 + rmb0 $02 + php + ora #$01 + asl + tsy + tsb $1234 + ora $1234 + asl $1234 + bbr0 $02,*+$34 + + bpl *+$32 + ora ($06),y + ora ($07),z + lbpl *+$3133 ; bpl *+$3133 + trb $02 + ora $03,x + asl $03,x + rmb1 $02 + clc + ora $1456,y + inc + inz + trb $1234 + ora $1345,x + asl $1345,x + bbr1 $02,*+$34 + + jsr $1234 + and ($05,x) + jsr ($2345) + jsr ($2456,x) + bit $02 + and $02 + rol $02 + rmb2 $02 + plp + and #$01 + rol + tys + bit $1234 + and $1234 + rol $1234 + bbr2 $02,*+$34 + + bmi *+$32 + and ($06),y + and ($07),z + lbmi *+$3133 ; bmi *+$3133 + bit $03,x + and $03,x + rol $03,x + rmb3 $02 + sec + and $1456,y + dec + dez + bit $1345,x + and $1345,x + rol $1345,x + bbr3 $02,*+$34 + + rti + eor ($05,x) + neg + asr + asr $02 + eor $02 + lsr $02 + rmb4 $02 + pha + eor #$01 + lsr + taz + jmp $1234 + eor $1234 + lsr $1234 + bbr4 $02,*+$34 + + bvc *+$32 + eor ($06),y + eor ($07),z + lbvc *+$3133 ; bvc *+$3133 + asr $03,x + eor $03,x + lsr $03,x + rmb5 $02 + cli + eor $1456,y + phy + tab + map + eor $1345,x + lsr $1345,x + bbr5 $02,*+$34 + + rts + adc ($05,x) + rtn #$09 + bsr *+$3133 + stz $02 + adc $02 + ror $02 + rmb6 $02 + pla + adc #$01 + ror + tza + jmp ($2345) + adc $1234 + ror $1234 + bbr6 $02,*+$34 + + bvs *+$32 + adc ($06),y + adc ($07),z + lbvs *+$3133 ; bvs *+$3133 + stz $03,x + adc $03,x + ror $03,x + rmb7 $02 + sei + adc $1456,y + ply + tba + jmp ($2456,x) + adc $1345,x + ror $1345,x + bbr7 $02,*+$34 + + bra *+$32 + sta ($05,x) + sta ($0f,s),y + sta ($0f,sp),y + lbra *+$3133 ; bra *+$3133 + sty $02 + sta $02 + stx $02 + smb0 $02 + dey + bit #$01 + txa + sty $1345,x + sty $1234 + sta $1234 + stx $1234 + bbs0 $02,*+$34 + + bcc *+$32 + sta ($06),y + sta ($07),z + lbcc *+$3133 ; bcc *+$3133 + sty $03,x + sta $03,x + stx $04,y + smb1 $02 + tya + sta $1456,y + txs + stx $1456,y + stz $1234 + sta $1345,x + stz $1345,x + bbs1 $02,*+$34 + + ldy #$01 + lda ($05,x) + ldx #$01 + ldz #$01 + ldy $02 + lda $02 + ldx $02 + smb2 $02 + tay + lda #$01 + tax + ldz $1234 + ldy $1234 + lda $1234 + ldx $1234 + bbs2 $02,*+$34 + + bcs *+$32 + lda ($06),y + lda ($07),z + lbcs *+$3133 ; bcs *+$3133 + ldy $03,x + lda $03,x + ldx $04,y + smb3 $02 + clv + lda $1456,y + tsx + ldz $1345,x + ldy $1345,x + lda $1345,x + ldx $1456,y + bbs3 $02,*+$34 + + cpy #$01 + cmp ($05,x) + cpz #$01 + dew $02 + cpy $02 + cmp $02 + dec $02 + smb4 $02 + iny + cmp #$01 + dex + asw $1234 + cpy $1234 + cmp $1234 + dec $1234 + bbs4 $02,*+$34 + + bne *+$32 + cmp ($06),y + cmp ($07),z + lbne *+$3133 ; bne *+$3133 + cpz $02 + cmp $03,x + dec $03,x + smb5 $02 + cld + cmp $1456,y + phx + phz + cpz $1234 + cmp $1345,x + dec $1345,x + bbs5 $02,*+$34 + + cpx #$01 + sbc ($05,x) + lda ($0f,s),y + lda ($0f,sp),y + inw $02 + cpx $02 + sbc $02 + inc $02 + smb6 $02 + inx + sbc #$01 + eom + nop + row $1234 + cpx $1234 + sbc $1234 + inc $1234 + bbs6 $02,*+$34 + + beq *+$32 + sbc ($06),y + sbc ($07),z + lbeq *+$3133 ; beq *+$3133 + phd #$089a + phw #$089a + sbc $03,x + inc $03,x + smb7 $02 + sed + sbc $1456,y + plx + plz + phd $1234 + phw $1234 + sbc $1345,x + inc $1345,x + bbs7 $02,*+$34 + + adc [$12],z + + adcq $12 + adcq $3456 + adcq ($78) + adcq [$9a] + + and [$12],z + + andq $12 + andq $3456 + andq ($78) + andq [$9a] + + aslq $12 + aslq + aslq $3456 + aslq $78,x + aslq $9abc,x + + asrq + asrq $12 + asrq $34,x + + bitq $12 + bitq $3456 + + cmp [$12],z + + cmpq $12 + cmpq $3456 + cmpq ($78) + cmpq [$9a] + + deq + deq $12 + deq $3456 + deq $78,x + deq $9abc,x + + eor [$12],z + + eorq $12 + eorq $3456 + eorq ($78) + eorq [$9a] + + inq + inq $12 + inq $3456 + inq $78,x + inq $9abc,x + + lda [$12],z + + ldq $12 + ldq $3456 + ldq ($78),z + ldq [$9a],z + + lsrq $12 + lsrq + lsrq $3456 + lsrq $78,x + lsrq $9abc,x + + ora [$12],z + + orq $12 + orq $3456 + orq ($78) + orq [$9a] + + rolq $12 + rolq + rolq $3456 + rolq $78,x + rolq $9abc,x + + rorq $12 + rorq + rorq $3456 + rorq $78,x + rorq $9abc,x + + sbc [$12],z + + sbcq $12 + sbcq $3456 + sbcq ($78) + sbcq [$9a] + + sta [$12],z ; EA 92 12 + + stq $12 + stq $3456 + stq ($78) + stq [$9a] From 76c8f0d860f2ab56ca85049bcaa7864f8775ff07 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 01:39:33 +0200 Subject: [PATCH 553/707] fix test, add 45GS02 instructions --- test/asm/cpudetect/45GS02-cpudetect.ref | Bin 0 -> 80 bytes test/asm/cpudetect/allinst.inc | 91 ++++++++++++++++++++++-- test/asm/cpudetect/cpudetect.s | 9 +++ 3 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 test/asm/cpudetect/45GS02-cpudetect.ref diff --git a/test/asm/cpudetect/45GS02-cpudetect.ref b/test/asm/cpudetect/45GS02-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..e9aa843cda2fb487e49b4380205f4b31d1ffb805 GIT binary patch literal 80 tcmZ>A;x!Rsa1IEK_Y8Ioi8nJfFhb@9JEQVZxF)8C1_;F_rtZN8MgT636pjD@ literal 0 HcmV?d00001 diff --git a/test/asm/cpudetect/allinst.inc b/test/asm/cpudetect/allinst.inc index ab266915e..e58577b7e 100644 --- a/test/asm/cpudetect/allinst.inc +++ b/test/asm/cpudetect/allinst.inc @@ -636,7 +636,7 @@ LABEL3: .endif -; The 4502 is a superset of the 65CE02. Opcode 5c (originally a "4-byte NOP +; The 4510 is a superset of the 65CE02. Opcode 5c (originally a "4-byte NOP ; reserved for future expansion") has been changed to the "map" instruction, ; now using implied addressing. ; @@ -656,9 +656,92 @@ LABEL3: .endif -; TODO: MEGA65 -; The m65 instruction set extends the 4502 instruction set using prefix bytes. -; Therefore, the "normal" opcode table is the same as for the 4502 cpu +; The 45GS02 instruction set extends the 4510 instruction set using prefix bytes. +; Therefore, the "normal" opcode table is the same as for the 4510 cpu + +.if (.cpu .bitand CPU_ISET_45GS02) + .scope + + orq $12 ; $42 $42 $05 + aslq $12 ; $42 $42 $06 + aslq ; $42 $42 $0a + orq $1234 ; $42 $42 $0d + aslq $1234 ; $42 $42 $0f + orq ($12) ; $42 $42 $12 + aslq $12,x ; $42 $42 $16 + inq ; $42 $42 $1a + aslq $124,x ; $42 $42 $1e + bitq $12 ; $42 $42 $24 + andq $12 ; $42 $42 $25 + rolq $12 ; $42 $42 $26 + rolq ; $42 $42 $2a + bitq $1234 ; $42 $42 $2c + andq $1234 ; $42 $42 $2d + rolq $1234 ; $42 $42 $2e + andq ($12) ; $42 $42 $32 + rolq $12, x ; $42 $42 $36 + deq ; $42 $42 $3a + rolq $1234, x ; $42 $42 $3e + asrq ; $42 $42 $43 + asrq $12 ; $42 $42 $44 + eorq $12 ; $42 $42 $45 + lsrq $12 ; $42 $42 $46 + lsrq ; $42 $42 $4a + eorq $1234 ; $42 $42 $4d + lsrq $1234 ; $42 $42 $4e + eorq ($12) ; $42 $42 $52 + asrq $12, x ; $42 $42 $54 + lsrq $12, x ; $42 $42 $56 + lsrq $1234, x ; $42 $42 $5e + adcq $12 ; $42 $42 $65 + rorq $12 ; $42 $42 $66 + rorq ; $42 $42 $6a + adcq $1234 ; $42 $42 $6d + rorq $1234 ; $42 $42 $6e + adcq ($12) ; $42 $42 $72 + rorq $12, x ; $42 $42 $76 + rorq $1234, x ; $42 $42 $7e + stq $12 ; $42 $42 $85 + stq $1234 ; $42 $42 $8d + stq ($12) ; $42 $42 $92 + ldq $12 ; $42 $42 $a5 + ldq $1234 ; $42 $42 $ad + ldq ($12), z ; $42 $42 $b2 + cmpq $12 ; $42 $42 $c5 + deq $12 ; $42 $42 $c6 + cmpq $1234 ; $42 $42 $cd + deq $1234 ; $42 $42 $ce + cmpq ($12) ; $42 $42 $d2 + deq $12, x ; $42 $42 $d6 + deq $1234, x ; $42 $42 $de + sbcq $12 ; $42 $42 $e5 + inq $12 ; $42 $42 $e6 + sbcq $1234 ; $42 $42 $ed + inq $1234 ; $42 $42 $ee + sbcq ($12) ; $42 $42 $f2 + inq $12, x ; $42 $42 $f6 + inq $1234, x ; $42 $42 $fe + + ora [$12], z ; $ea $12 + and [$12], z ; $ea $32 + eor [$12], z ; $ea $52 + adc [$12], z ; $ea $72 + sta [$12], z ; $ea $92 + lda [$12], z ; $ea $b2 + cmp [$12], z ; $ea $d2 + sbc [$12], z ; $ea $f2 + + orq [$12] ; $42 $42 $ea $12 + andq [$12] ; $42 $42 $ea $32 + eorq [$12] ; $42 $42 $ea $52 + adcq [$12] ; $42 $42 $ea $72 + stq [$12] ; $42 $42 $ea $92 + ldq [$12], z ; $42 $42 $ea $b2 + cmpq [$12] ; $42 $42 $ea $d2 + sbcq [$12] ; $42 $42 $ea $f2 + + .endscope +.endif ; The HUC6280 is a superset of the R65C02. It adds some other instructions: diff --git a/test/asm/cpudetect/cpudetect.s b/test/asm/cpudetect/cpudetect.s index a017e652d..545e2fa56 100644 --- a/test/asm/cpudetect/cpudetect.s +++ b/test/asm/cpudetect/cpudetect.s @@ -28,6 +28,10 @@ taz .endif +.ifp45GS02 + orq $1234 +.endif + .ifpdtv sac #$00 .endif @@ -76,6 +80,10 @@ .byte 0,"CPU_ISET_4510" .endif +.if (.cpu .bitand CPU_ISET_45GS02) + .byte 0,"CPU_ISET_45GS02" +.endif + .if (.cpu .bitand CPU_ISET_6502DTV) .byte 0,"CPU_ISET_6502DTV" .endif @@ -98,5 +106,6 @@ .pc02 .p816 .p4510 +.p45GS02 .pdtv .pm740 From 8bfaaa60baac9900b29035102428d1d8ed530357 Mon Sep 17 00:00:00 2001 From: Russell-S-Harper <russell.s.harper@gmail.com> Date: Sat, 21 Jun 2025 06:01:13 -0400 Subject: [PATCH 554/707] Revising to align with stdio fgets --- include/conio.h | 26 +++++++-------- libsrc/conio/cgets.c | 77 +++++++++++++------------------------------- 2 files changed, 33 insertions(+), 70 deletions(-) diff --git a/include/conio.h b/include/conio.h index 1f88ac3ce..1bd59b052 100644 --- a/include/conio.h +++ b/include/conio.h @@ -110,22 +110,18 @@ char cgetc (void); ** 1 (see below), a blinking cursor is displayed while waiting. */ -char *cgets (char *buffer); -/* Get a string of characters directly from the console. The standard interface -** is quirky: +char* __fastcall__ cgets (char *buffer, int size); +/* Get a string of characters directly from the console. The function returns +** when size - 1 characters or either CR/LF are read. Note the parameters are +** more aligned with stdio fgets() as opposed to the quirky "standard" conio +** cgets(). Besides providing saner parameters, the function also echoes CRLF +** when either CR/LF are read but does NOT append either in the buffer. This is +** to correspond to stdio fgets() which echoes CRLF, but prevents a "gotcha" +** where the buffer might not be able to accommodate both CR and LF at the end. ** -** - set buffer[0] to the size of the buffer - 2, must be > 0 -** - call cgets -** - buffer[1] will have the number of characters read -** - the actual string starts at buffer + 2 -** - terminating \0 is appended -** - therefore the maximum number of characters which can be read is the size -** of the buffer - 3! -** - note: CR/LF are NOT echoed, typically a following call to cputs or -** cprintf will need "\r\n" prepended - "standard" behavior -** -** param: buffer - where to save the input -** return: buffer + 2 (i.e. start of the string) if successful, NULL otherwise +** param: buffer - where to save the input, must be non-NULL +** param: size - size of the buffer, must be > 1 +** return: buffer if successful, NULL on error ** author: Russell-S-Harper */ diff --git a/libsrc/conio/cgets.c b/libsrc/conio/cgets.c index bb24f97de..52e2da343 100644 --- a/libsrc/conio/cgets.c +++ b/libsrc/conio/cgets.c @@ -2,7 +2,7 @@ ** Modified: <iso-date> <author> ** Notes: <e.g. revisions made to support target, edge cases, bugs, etc.> ** -** char *cgets(char *buffer); +** char* __fastcall__ cgets (char *buffer, int size); */ #include <stddef.h> @@ -10,57 +10,22 @@ #include <string.h> #include <ctype.h> -enum {CGETS_SIZE, CGETS_READ, CGETS_DATA, CGETS_HDR_LEN = CGETS_DATA}; +#ifndef CRLF +#define CRLF "\r\n" +#endif /* CRLF */ -static char *cgetsx (char *buffer, int size); - -char *cgets (char *buffer) -/* Get a string of characters directly from the console. The standard interface -** is quirky: +char* __fastcall__ cgets (char *buffer, int size) +/* Get a string of characters directly from the console. The function returns +** when size - 1 characters or either CR/LF are read. Note the parameters are +** more aligned with stdio fgets() as opposed to the quirky "standard" conio +** cgets(). Besides providing saner parameters, the function also echoes CRLF +** when either CR/LF are read but does NOT append either in the buffer. This is +** to correspond to stdio fgets() which echoes CRLF, but prevents a "gotcha" +** where the buffer might not be able to accommodate both CR and LF at the end. ** -** - set buffer[0] to the size of the buffer - 2, must be > 0 -** - call cgets -** - buffer[1] will have the number of characters read -** - the actual string starts at buffer + 2 -** - terminating \0 is appended -** - therefore the maximum number of characters which can be read is the size -** of the buffer - 3! -** - note: CR/LF are NOT echoed, typically a following call to cputs or -** cprintf will need "\r\n" prepended - this is standard behavior! -** -** param: buffer - where to save the input -** return: buffer + 2 (i.e. start of the string) or NULL if buffer is NULL -*/ -{ - /* Return buffer + 2 or NULL if buffer is NULL */ - char *result = buffer? buffer + CGETS_HDR_LEN: NULL; - - if (result) { - /* Initialize just in case the caller didn't! */ - buffer[CGETS_READ] = 0; - buffer[CGETS_DATA] = '\0'; - - /* Call cgetsx to do the real work, ignore the result! */ - cgetsx (result, (unsigned char)buffer[CGETS_SIZE]); - - /* Set how many characters were read */ - buffer[CGETS_READ] = (unsigned char)strlen (result); - } - - /* Done */ - return result; -} - -static char *cgetsx (char *buffer, int size) -/* Like fgets but specifically for the console. Stops when CR/LF or size - 1 -** characters are read. Will append a terminating \0, so at most size - 1 -** characters can be read. Note that this function could be made public and -** have features added like cursor vs no-cursor, echo vs echo-pwd vs no-echo, -** or CR/LF handling to extend the functionality. -** -** param: buffer - where to save the input -** param: size - the size of buffer -** return: buffer if successful, NULL otherwise +** param: buffer - where to save the input, must be non-NULL +** param: size - size of the buffer, must be > 1 +** return: buffer if successful, NULL on error */ { int i = 0; @@ -73,8 +38,14 @@ static char *cgetsx (char *buffer, int size) /* Actually just the last column! */ --w; cursor (1); - for (i = 0, --size; i < size; ) { + for (buffer[i] = '\0', --size; i < size; ) { c = cgetc (); + /* Handle CR/LF */ + if (strchr (CRLF, c)) { + /* Echo CRLF, but don't append either CR/LF */ + cputs (CRLF); + break; + } /* Handle backspace */ if (c == '\b') { if (i > 0) { @@ -95,10 +66,6 @@ static char *cgetsx (char *buffer, int size) cputc (c); buffer[i] = c; buffer[++i] = '\0'; - /* Handle CR/LF */ - } else if (c == '\r' || c == '\n') { - buffer[i] = '\0'; - break; } } cursor (0); From 7f40affb59acefe4d8a9c8cb6a85868602c5ac90 Mon Sep 17 00:00:00 2001 From: Russell-S-Harper <russell.s.harper@gmail.com> Date: Sat, 21 Jun 2025 08:48:41 -0400 Subject: [PATCH 555/707] Adding documentation and some minor reformatting to ensure consistency --- doc/funcref.sgml | 39 +++++++++++++++++++++++++++++++++++++++ include/conio.h | 2 +- libsrc/conio/cgets.c | 4 ++-- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 5eab5adcd..7e632f71f 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -289,6 +289,7 @@ function. <item><ref id="cclear" name="cclear"> <item><ref id="cclearxy" name="cclearxy"> <item><ref id="cgetc" name="cgetc"> +<item><ref id="cgets" name="cgets"> <item><ref id="chline" name="chline"> <item><ref id="chlinexy" name="chlinexy"> <item><ref id="clrscr" name="clrscr"> @@ -2715,6 +2716,44 @@ see anything that you type. (See the description of <tt/cbm_k_scnkey()/.) </quote> +<sect1>cgets<label id="cgets"><p> + +<quote> +<descrip> +<tag/Function/Input a string directly to the console. +<tag/Header/<tt/<ref id="conio.h" name="conio.h">/ +<tag/Declaration/<tt/char* __fastcall__ cgets (const char* buffer, int size);/ +<tag/Description/The function inputs a string of at most <tt/size - 1/ +characters from the console into <tt/buffer/. It returns when <tt/size - 1/ +characters or either <tt/CR/ or <tt/LF/ are entered. It also handles both +multi-line input and backspacing. +<tag/Notes/<itemize> +<item>The function echoes <tt/CRLF/ when either <tt/CR/ or <tt/LF/ are read +but does NOT append either in <tt/buffer/. +<item>The function is only available as fastcall function, so it may only +be used in the presence of a prototype. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="cgetc" name="cgetc"> +<tag/Example/<verb> +#include <conio.h> + +int main () +{ + char buffer[200], *p; + + cputs ("Type a lot and backspace a lot: "); + if (p = cgets (buffer, sizeof(buffer))) + cputs (p); + + return 0; +} +</verb> +</descrip> +</quote> + + <sect1>chline<label id="chline"><p> <quote> diff --git a/include/conio.h b/include/conio.h index 1bd59b052..3e1614cc1 100644 --- a/include/conio.h +++ b/include/conio.h @@ -110,7 +110,7 @@ char cgetc (void); ** 1 (see below), a blinking cursor is displayed while waiting. */ -char* __fastcall__ cgets (char *buffer, int size); +char* __fastcall__ cgets (char* buffer, int size); /* Get a string of characters directly from the console. The function returns ** when size - 1 characters or either CR/LF are read. Note the parameters are ** more aligned with stdio fgets() as opposed to the quirky "standard" conio diff --git a/libsrc/conio/cgets.c b/libsrc/conio/cgets.c index 52e2da343..290a6b131 100644 --- a/libsrc/conio/cgets.c +++ b/libsrc/conio/cgets.c @@ -2,7 +2,7 @@ ** Modified: <iso-date> <author> ** Notes: <e.g. revisions made to support target, edge cases, bugs, etc.> ** -** char* __fastcall__ cgets (char *buffer, int size); +** char* __fastcall__ cgets (char* buffer, int size); */ #include <stddef.h> @@ -14,7 +14,7 @@ #define CRLF "\r\n" #endif /* CRLF */ -char* __fastcall__ cgets (char *buffer, int size) +char* __fastcall__ cgets (char* buffer, int size) /* Get a string of characters directly from the console. The function returns ** when size - 1 characters or either CR/LF are read. Note the parameters are ** more aligned with stdio fgets() as opposed to the quirky "standard" conio From 37144ed01426ffd755532b8db1d2db5a0e0cfac4 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 20:35:25 +0200 Subject: [PATCH 556/707] fix akkumulator addressing for some compound instructions --- src/ca65/instr.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 8e1b4b456..ca44f5509 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -779,9 +779,9 @@ static const struct { { "AND", 0x4080A66C, 0x20, 0, Put45GS02 }, { "ANDQ", 0x0000140C, 0x20, 13, Put45GS02_Q }, { "ASL", 0x0000006e, 0x02, 1, PutAll }, - { "ASLQ", 0x800000ec, 0x00, 14, Put45GS02_Q }, + { "ASLQ", 0x800000ee, 0x00, 14, Put45GS02_Q }, { "ASR", 0x00000026, 0x43, 0, Put4510 }, - { "ASRQ", 0x80000024, 0x40, 15, Put45GS02_Q }, + { "ASRQ", 0x80000026, 0x40, 15, Put45GS02_Q }, { "ASW", 0x00000008, 0xcb, 6, PutAll }, { "BBR0", 0x00000000, 0x0F, 0, PutBitBranch }, { "BBR1", 0x00000000, 0x1F, 0, PutBitBranch }, @@ -824,7 +824,7 @@ static const struct { { "CPZ", 0x0080000C, 0xd0, 1, Put4510 }, { "DEA", 0x00000001, 0x00, 3, PutAll }, /* == DEC */ { "DEC", 0x0000006F, 0x00, 3, PutAll }, - { "DEQ", 0x800000ec, 0xc0, 14, Put45GS02_Q }, + { "DEQ", 0x800000ee, 0xc0, 14, Put45GS02_Q }, { "DEW", 0x00000004, 0xc3, 9, PutAll }, { "DEX", 0x00000001, 0xca, 0, PutAll }, { "DEY", 0x00000001, 0x88, 0, PutAll }, @@ -834,7 +834,7 @@ static const struct { { "EORQ", 0x0000140C, 0x40, 13, Put45GS02_Q }, { "INA", 0x00000001, 0x00, 4, PutAll }, /* == INC */ { "INC", 0x0000006f, 0x00, 4, PutAll }, - { "INQ", 0x800000ec, 0xe0, 14, Put45GS02_Q }, + { "INQ", 0x800000ee, 0xe0, 14, Put45GS02_Q }, { "INW", 0x00000004, 0xe3, 9, PutAll }, { "INX", 0x00000001, 0xe8, 0, PutAll }, { "INY", 0x00000001, 0xc8, 0, PutAll }, @@ -856,7 +856,7 @@ static const struct { { "LDY", 0x0080006C, 0xa0, 1, PutAll }, { "LDZ", 0x00800048, 0xa3, 1, Put4510 }, { "LSR", 0x0000006F, 0x42, 1, PutAll }, - { "LSRQ", 0x800000ec, 0x40, 14, Put45GS02_Q }, + { "LSRQ", 0x800000ee, 0x40, 14, Put45GS02_Q }, { "MAP", 0x00000001, 0x5C, 0, PutAll }, { "NEG", 0x00000001, 0x42, 0, PutAll }, { "NOP", 0x00000001, 0xea, 0, PutAll }, /* == EOM */ @@ -883,9 +883,9 @@ static const struct { { "RMB6", 0x00000004, 0x67, 1, PutAll }, { "RMB7", 0x00000004, 0x77, 1, PutAll }, { "ROL", 0x0000006F, 0x22, 1, PutAll }, - { "ROLQ", 0x800000ec, 0x20, 14, Put45GS02_Q }, + { "ROLQ", 0x800000ee, 0x20, 14, Put45GS02_Q }, { "ROR", 0x0000006F, 0x62, 1, PutAll }, - { "RORQ", 0x800000ec, 0x60, 14, Put45GS02_Q }, + { "RORQ", 0x800000ee, 0x60, 14, Put45GS02_Q }, { "ROW", 0x00000008, 0xeb, 6, PutAll }, { "RTI", 0x00000001, 0x40, 0, PutAll }, { "RTN", 0x00800000, 0x62, 1, PutAll }, @@ -1455,14 +1455,14 @@ static unsigned char EATab[16][AM65I_COUNT] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00 }, - { /* Table 14 (Q) */ - 0x00, 0x00, 0x06, 0x0e, 0x00, 0x16, 0x1e, 0x00, + { /* Table 14 (45GS02: ASLQ) */ + 0x0a, 0x0a, 0x06, 0x0e, 0x00, 0x16, 0x1e, 0x00, 0x00, 0x00, 0x12, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a }, - { /* Table 15 */ - 0x00, 0x00, 0x04, 0x0c, 0x00, 0x14, 0x00, 0x00, + { /* Table 15 (45GS02: ASRQ) */ + 0x03, 0x03, 0x04, 0x0c, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 From 3321910848133dd87a51769aa5441580b824d1f8 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 20:37:31 +0200 Subject: [PATCH 557/707] implement 45GS02 compound instrictions in the disassembler --- src/da65/handler.c | 181 +++++++++++ src/da65/handler.h | 10 + src/da65/main.c | 55 +++- src/da65/opc45GS02.c | 565 +++++++++++++++++++++++++++++++++ src/da65/opc45GS02.h | 58 ++++ src/da65/opctable.c | 2 + test/asm/cpudetect/allinst.inc | 5 +- 7 files changed, 866 insertions(+), 10 deletions(-) create mode 100644 src/da65/opc45GS02.c create mode 100644 src/da65/opc45GS02.h diff --git a/src/da65/handler.c b/src/da65/handler.c index 45c152697..3d1d0d7d0 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -226,6 +226,82 @@ void OH_Implicit (const OpcDesc* D) +void OH_Implicit_ea_45GS02 (const OpcDesc* D) +/* handle disassembling EOM prefixed opcodes, $ea $xx */ +{ + /* Get byte after EOM */ + unsigned opc = GetCodeByte (PC+1); + static const char *mnemonics[8] = { + "ora", "and", "eor", "adc", "sta", "lda", "cmp", "sbc" + }; + + if ((opc & 0x1f) == 0x12) { + unsigned zp = GetCodeByte (PC+2); + + Indent (MCol); + Output ("%s", mnemonics[(opc >> 5) & 7]); + + Indent (ACol); + Output ("[$%02X],z", zp); + + /* Add the code stuff as comment */ + LineComment (PC, 3); + + /* End the line */ + LineFeed (); + } else { + OH_Implicit (D); + } +} + + + +void OH_Implicit_42_45GS02 (const OpcDesc* D) +/* handle disassembling NEG NEG prefixed opcodes, $42 42 ($ea) $xx */ +{ + /* Get bytes after NEG */ + unsigned n1 = GetCodeByte (PC+1); + unsigned opc = GetCodeByte (PC+2); + /* NEG:NEG:NOP (42 42 ea) prefix */ + static const char *mnemonics[8] = { + "orq", "andq", "eorq", "adcq", "stq", "ldq", "cmpq", "sbcq" + }; + + if (n1 == 0x42) { + /* detected 0x42 0x42 */ + if (opc == 0xea) { + /* detected 0x42 0x42 0xea */ + unsigned opc = GetCodeByte (PC+3); + if ((opc & 0x1f) == 0x12) { + unsigned zp = GetCodeByte (PC+4); + + Indent (MCol); + Output ("%s", mnemonics[(opc >> 5) & 7]); + + Indent (ACol); + Output ("[$%02X]", zp); /* with or without ,z ? */ + + /* Add the code stuff as comment */ + LineComment (PC, 5); + + /* End the line */ + LineFeed (); + return; + } + } else { + /* use another table for these */ + OpcDesc* NewDesc = &OpcTable_45GS02_extended[opc]; + NewDesc->Handler (NewDesc); + return; + } + } + + /* no prefix detected */ + OH_Implicit (D); +} + + + void OH_Immediate (const OpcDesc* D) { OneLine (D, "#$%02X", GetCodeByte (PC+1)); @@ -276,6 +352,20 @@ void OH_Direct (const OpcDesc* D) +void OH_Direct_Q (const OpcDesc* D) +{ + /* Get the operand */ + unsigned Addr = GetCodeByte (PC+3); + + /* Generate a label in pass 1 */ + GenerateLabel (D->Flags, Addr); + + /* Output the line */ + OneLine (D, "%s", GetAddrArg (D->Flags, Addr)); +} + + + void OH_DirectX (const OpcDesc* D) { /* Get the operand */ @@ -290,6 +380,20 @@ void OH_DirectX (const OpcDesc* D) +void OH_DirectX_Q (const OpcDesc* D) +{ + /* Get the operand */ + unsigned Addr = GetCodeByte (PC+3); + + /* Generate a label in pass 1 */ + GenerateLabel (D->Flags, Addr); + + /* Output the line */ + OneLine (D, "%s,x", GetAddrArg (D->Flags, Addr)); +} + + + void OH_DirectY (const OpcDesc* D) { /* Get the operand */ @@ -318,6 +422,20 @@ void OH_Absolute (const OpcDesc* D) +void OH_Absolute_Q (const OpcDesc* D) +{ + /* Get the operand */ + unsigned Addr = GetCodeWord (PC+3); + + /* Generate a label in pass 1 */ + GenerateLabel (D->Flags, Addr); + + /* Output the line */ + OneLine (D, "%s%s", GetAbsOverride (D->Flags, Addr), GetAddrArg (D->Flags, Addr)); +} + + + void OH_AbsoluteX (const OpcDesc* D) { /* Get the operand */ @@ -332,6 +450,20 @@ void OH_AbsoluteX (const OpcDesc* D) +void OH_AbsoluteX_Q (const OpcDesc* D) +{ + /* Get the operand */ + unsigned Addr = GetCodeWord (PC+3); + + /* Generate a label in pass 1 */ + GenerateLabel (D->Flags, Addr); + + /* Output the line */ + OneLine (D, "%s%s,x", GetAbsOverride (D->Flags, Addr), GetAddrArg (D->Flags, Addr)); +} + + + void OH_AbsoluteY (const OpcDesc* D) { /* Get the operand */ @@ -472,6 +604,20 @@ void OH_DirectIndirectZ (const OpcDesc* D) +void OH_DirectIndirectZ_Q (const OpcDesc* D) +{ + /* Get the operand */ + unsigned Addr = GetCodeByte (PC+3); + + /* Generate a label in pass 1 */ + GenerateLabel (D->Flags, Addr); + + /* Output the line */ + OneLine (D, "(%s),z", GetAddrArg (D->Flags, Addr)); +} + + + void OH_DirectXIndirect (const OpcDesc* D) { /* Get the operand */ @@ -531,6 +677,41 @@ void OH_BitBranch (const OpcDesc* D) xfree (BranchLabel); } + + +void OH_BitBranch_Q (const OpcDesc* D) +{ + char* BranchLabel; + + /* Get the operands */ + unsigned char TestAddr = GetCodeByte (PC+3); + signed char BranchOffs = GetCodeByte (PC+4); + + /* Calculate the target address for the branch */ + unsigned BranchAddr = (((int) PC+5) + BranchOffs) & 0xFFFF; + + /* Generate labels in pass 1. The bit branch codes are special in that + ** they don't really match the remainder of the 6502 instruction set (they + ** are a Rockwell addon), so we must pass additional flags as direct + ** value to the second GenerateLabel call. + */ + GenerateLabel (D->Flags, TestAddr); + GenerateLabel (flLabel, BranchAddr); + + /* Make a copy of an operand, so that + ** the other operand can't overwrite it. + ** [GetAddrArg() uses a statically-stored buffer.] + */ + BranchLabel = xstrdup (GetAddrArg (flLabel, BranchAddr)); + + /* Output the line */ + OneLine (D, "%s,%s", GetAddrArg (D->Flags, TestAddr), BranchLabel); + + xfree (BranchLabel); +} + + + void OH_BitBranch_m740 (const OpcDesc* D) /* <bit> zp, rel ** NOTE: currently <bit> is part of the instruction diff --git a/src/da65/handler.h b/src/da65/handler.h index fb0c40200..6286d4e40 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -103,6 +103,16 @@ void OH_AccumulatorBitBranch (const OpcDesc*); void OH_JmpDirectIndirect (const OpcDesc* D); void OH_SpecialPage (const OpcDesc*); +/* 45GS02 */ +void OH_Direct_Q (const OpcDesc*); +void OH_DirectIndirectZ_Q (const OpcDesc* D); +void OH_Absolute_Q (const OpcDesc* D); +void OH_AbsoluteX_Q (const OpcDesc* D); +void OH_BitBranch_Q (const OpcDesc* D); +void OH_DirectX_Q (const OpcDesc* D); +void OH_Implicit_ea_45GS02 (const OpcDesc* D); +void OH_Implicit_42_45GS02 (const OpcDesc* D); + /* Handlers for special instructions */ void OH_Rts (const OpcDesc*); void OH_JmpAbsolute (const OpcDesc*); diff --git a/src/da65/main.c b/src/da65/main.c index 67a01dc3b..e315a3a90 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -59,6 +59,7 @@ #include "infofile.h" #include "labels.h" #include "opctable.h" +#include "opc45GS02.h" #include "output.h" #include "scanner.h" #include "segment.h" @@ -360,6 +361,49 @@ static void OptVersion (const char* Opt attribute ((unused)), +static unsigned HandleChangedLength(const OpcDesc* D, unsigned PC) +/* Instructions that have flSizeChanges set may use a different size than what +** the table says. This function adjusts the PC accordingly, so after this only +** the size from the table needs to be added to make up for the correct value +*/ +{ + if (D->Flags & flSizeChanges) { + if (CPU == CPU_45GS02) { + if ((D->Handler == OH_Implicit_42_45GS02)) { + if (GetCodeByte (PC+1) == 0x42) { + unsigned opc = GetCodeByte (PC+2); + if (opc == 0xea) { + /* 42 42 ea */ + if ((GetCodeByte (PC+3) & 0x1f) == 0x12) { + PC += 4; + } + } else { + /* 42 42 xx */ + const OpcDesc* ED = &OpcTable_45GS02_extended[opc]; + if (ED->Handler != OH_Illegal) { + PC += (ED->Size - 1); + } + } + } + }else if ((D->Handler == OH_Implicit_ea_45GS02)) { + if ((GetCodeByte (PC+1) & 0x1f) == 0x12) { + PC += 2; + } + } + } else if (CPU == CPU_65816) { + if ((D->Handler == OH_Immediate65816M && + GetAttr (PC) & atMem16) || + (D->Handler == OH_Immediate65816X && + GetAttr (PC) & atIdx16)) { + PC++; + } + } + } + return PC; +} + + + static void OneOpcode (unsigned RemainingBytes) /* Disassemble one opcode */ { @@ -435,6 +479,7 @@ static void OneOpcode (unsigned RemainingBytes) ++PC; } else { D->Handler (D); + PC = HandleChangedLength (D, PC); PC += D->Size; } break; @@ -466,14 +511,8 @@ static void OneOpcode (unsigned RemainingBytes) } /* Output the insn */ D->Handler (D); - if (CPU == CPU_65816 && (D->Flags & flSizeChanges)) { - if ((D->Handler == OH_Immediate65816M && - GetAttr (PC) & atMem16) || - (D->Handler == OH_Immediate65816X && - GetAttr (PC) & atIdx16)) { - PC++; - } - } + + PC = HandleChangedLength (D, PC); PC += D->Size; break; } diff --git a/src/da65/opc45GS02.c b/src/da65/opc45GS02.c new file mode 100644 index 000000000..a831d539c --- /dev/null +++ b/src/da65/opc45GS02.c @@ -0,0 +1,565 @@ +/*****************************************************************************/ +/* */ +/* opc45GS02.c */ +/* */ +/* 45GS10 opcode description table */ +/* */ +/* */ +/* */ +/* (C) 2003-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +/* da65 */ +#include "handler.h" +#include "opc45GS02.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all compound instructions with NEG:NEG prefix */ +const OpcDesc OpcTable_45GS02_extended[256] = { + { "", 1+2, flIllegal, OH_Illegal, }, /* $00 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $01 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $02 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $03 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $04 */ + { "orq", 2+2, flUseLabel, OH_Direct_Q }, /* $05 */ + { "aslq", 2+2, flUseLabel, OH_Direct_Q }, /* $06 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $07 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $08 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $09 */ + { "aslq", 1+2, flNone, OH_Accumulator }, /* $0a */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $0b */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $0c */ + { "orq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $0d */ + { "aslq", 3+2, flUseLabel, OH_BitBranch_Q }, /* $0e */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $0f */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $10 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $11 */ + { "orq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $12 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $13 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $14 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $15 */ + { "aslq", 2+2, flUseLabel, OH_DirectX_Q }, /* $16 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $17 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $18 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $19 */ + { "inq", 1+2, flNone, OH_Accumulator }, /* $1a */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $1b */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $1c */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $1d */ + { "aslq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $1e */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $1f */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $20 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $21 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $22 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $23 */ + { "bitq", 2+2, flUseLabel, OH_Direct_Q }, /* $24 */ + { "andq", 2+2, flUseLabel, OH_Direct_Q }, /* $25 */ + { "rolq", 2+2, flUseLabel, OH_Direct_Q }, /* $26 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $27 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $28 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $29 */ + { "rolq", 1+2, flNone, OH_Accumulator }, /* $2a */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $2b */ + { "bitq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $2c */ + { "andq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $2d */ + { "rolq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $2e */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $2f */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $30 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $31 */ + { "andq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $32 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $33 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $34 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $35 */ + { "rolq", 2+2, flUseLabel, OH_DirectX_Q }, /* $36 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $37 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $38 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $39 */ + { "deq", 1+2, flNone, OH_Accumulator }, /* $3a */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $3b */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $3c */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $3d */ + { "rolq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $3e */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $3f */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $40 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $41 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $42 */ + { "asrq", 1+2, flNone, OH_Accumulator }, /* $43 */ + { "asrq", 2+2, flUseLabel, OH_Direct_Q }, /* $44 */ + { "eorq", 2+2, flUseLabel, OH_Direct_Q }, /* $45 */ + { "lsrq", 2+2, flUseLabel, OH_Direct_Q }, /* $46 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $47 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $48 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $49 */ + { "lsrq", 1+2, flNone, OH_Accumulator }, /* $4a */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $4b */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $4c */ + { "eorq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $4d */ + { "lsrq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $4e */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $4f */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $50 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $51 */ + { "eorq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $52 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $53 */ + { "asrq", 2+2, flUseLabel, OH_DirectX_Q }, /* $54 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $55 */ + { "lsrq", 2+2, flUseLabel, OH_DirectX_Q }, /* $56 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $57 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $58 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $59 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $5a */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $5b */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $5c */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $5d */ + { "lsrq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $5e */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $5f */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $60 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $61 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $62 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $63 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $64 */ + { "adcq", 2+2, flUseLabel, OH_Direct_Q }, /* $65 */ + { "rorq", 2+2, flUseLabel, OH_Direct_Q }, /* $66 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $67 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $68 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $69 */ + { "rorq", 1+2, flNone, OH_Accumulator }, /* $6a */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $6b */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $6c */ + { "adcq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $6d */ + { "rorq", 3+2, flUseLabel, OH_Absolute_Q }, /* $6e */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $6f */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $70 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $71 */ + { "adcq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $72 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $73 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $74 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $75 */ + { "rorq", 2+2, flUseLabel, OH_DirectX_Q }, /* $76 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $77 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $78 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $79 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $7a */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $7b */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $7c */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $7d */ + { "rorq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $7e */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $7f */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $80 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $81 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $82 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $83 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $84 */ + { "stq", 2+2, flUseLabel, OH_Direct_Q }, /* $85 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $86 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $87 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $88 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $89 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $8a */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $8b */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $8c */ + { "stq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $8d */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $8e */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $8f */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $90 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $91 */ + { "stq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $92 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $93 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $94 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $95 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $96 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $97 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $98 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $99 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $9a */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $9b */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $9c */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $9d */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $9e */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $9f */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $a0 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $a1 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $a2 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $a3 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $a4 */ + { "ldq", 2+2, flUseLabel, OH_Direct_Q }, /* $a5 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $a6 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $a7 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $a8 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $a9 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $aa */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $ab */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $ac */ + { "ldq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $ad */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $ae */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $af */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $b0 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $b1 */ + { "ldq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $b2 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $b3 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $b4 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $b5 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $b6 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $b7 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $b8 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $b9 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $ba */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $bb */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $bc */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $bd */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $be */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $bf */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $c0 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $c1 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $c2 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $c3 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $c4 */ + { "cmpq", 2+2, flUseLabel, OH_Direct_Q }, /* $c5 */ + { "deq", 2+2, flUseLabel, OH_Direct_Q }, /* $c6 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $c7 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $c8 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $c9 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $ca */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $cb */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $cc */ + { "cmpq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $cd */ + { "deq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $ce */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $cf */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $d0 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $d1 */ + { "cmpq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $d2 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $d3 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $d4 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $d5 */ + { "deq", 2+2, flUseLabel, OH_DirectX_Q }, /* $d6 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $d7 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $d8 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $d9 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $da */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $db */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $dc */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $dd */ + { "deq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $de */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $df */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $e0 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $e1 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $e2 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $e3 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $e4 */ + { "sbcq", 2+2, flUseLabel, OH_Direct_Q }, /* $e5 */ + { "inq", 2+2, flUseLabel, OH_Direct_Q }, /* $e6 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $e7 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $e8 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $e9 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $ea */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $eb */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $ec */ + { "sbcq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $ed */ + { "inq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $ee */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $ef */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $f0 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $f1 */ + { "sbcq", 2+2, flUseLabel, OH_DirectIndirectZ_Q }, /* $f2 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $f3 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $f4 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $f5 */ + { "inq", 2+2, flUseLabel, OH_DirectX_Q }, /* $f6 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $f7 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $f8 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $f9 */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $fa */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $fb */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $fc */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $fd */ + { "inq", 3+2, flUseLabel|flAbsOverride, OH_AbsoluteX_Q }, /* $fe */ + { "", 1+2, flIllegal, OH_Illegal, }, /* $ff */ +}; + +const OpcDesc OpcTable_45GS02[256] = { + { "brk", 1, flNone, OH_Implicit }, /* $00 */ + { "ora", 2, flUseLabel, OH_DirectXIndirect }, /* $01 */ + { "cle", 1, flNone, OH_Implicit }, /* $02 */ + { "see", 1, flNone, OH_Implicit }, /* $03 */ + { "tsb", 2, flUseLabel, OH_Direct }, /* $04 */ + { "ora", 2, flUseLabel, OH_Direct }, /* $05 */ + { "asl", 2, flUseLabel, OH_Direct }, /* $06 */ + { "rmb0", 2, flUseLabel, OH_Direct }, /* $07 */ + { "php", 1, flNone, OH_Implicit }, /* $08 */ + { "ora", 2, flNone, OH_Immediate }, /* $09 */ + { "asl", 1, flNone, OH_Accumulator }, /* $0a */ + { "tsy", 1, flNone, OH_Implicit }, /* $0b */ + { "tsb", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0c */ + { "ora", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0d */ + { "asl", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0e */ + { "bbr0", 3, flUseLabel, OH_BitBranch }, /* $0f */ + { "bpl", 2, flLabel, OH_Relative }, /* $10 */ + { "ora", 2, flUseLabel, OH_DirectIndirectY }, /* $11 */ + { "ora", 2, flUseLabel, OH_DirectIndirectZ }, /* $12 */ + { "lbpl", 3, flLabel, OH_RelativeLong4510 }, /* $13 */ + { "trb", 2, flUseLabel, OH_Direct }, /* $14 */ + { "ora", 2, flUseLabel, OH_DirectX }, /* $15 */ + { "asl", 2, flUseLabel, OH_DirectX }, /* $16 */ + { "rmb1", 2, flUseLabel, OH_Direct }, /* $17 */ + { "clc", 1, flNone, OH_Implicit }, /* $18 */ + { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */ + { "inc", 1, flNone, OH_Accumulator }, /* $1a */ + { "inz", 1, flNone, OH_Implicit }, /* $1b */ + { "trb", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $1c */ + { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */ + { "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */ + { "bbr1", 3, flUseLabel, OH_BitBranch }, /* $1f */ + { "jsr", 3, flLabel, OH_Absolute }, /* $20 */ + { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */ + { "jsr", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $22 */ + { "jsr", 3, flLabel, OH_JmpAbsoluteXIndirect }, /* $23 */ + { "bit", 2, flUseLabel, OH_Direct }, /* $24 */ + { "and", 2, flUseLabel, OH_Direct }, /* $25 */ + { "rol", 2, flUseLabel, OH_Direct }, /* $26 */ + { "rmb2", 2, flUseLabel, OH_Direct }, /* $27 */ + { "plp", 1, flNone, OH_Implicit }, /* $28 */ + { "and", 2, flNone, OH_Immediate }, /* $29 */ + { "rol", 1, flNone, OH_Accumulator }, /* $2a */ + { "tys", 1, flNone, OH_Implicit }, /* $2b */ + { "bit", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2c */ + { "and", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2d */ + { "rol", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2e */ + { "bbr2", 3, flUseLabel, OH_BitBranch }, /* $2f */ + { "bmi", 2, flLabel, OH_Relative }, /* $30 */ + { "and", 2, flUseLabel, OH_DirectIndirectY }, /* $31 */ + { "and", 2, flUseLabel, OH_DirectIndirectZ }, /* $32 */ + { "lbmi", 3, flLabel, OH_RelativeLong4510 }, /* $33 */ + { "bit", 2, flUseLabel, OH_DirectX }, /* $34 */ + { "and", 2, flUseLabel, OH_DirectX }, /* $35 */ + { "rol", 2, flUseLabel, OH_DirectX }, /* $36 */ + { "rmb3", 2, flUseLabel, OH_Direct }, /* $37 */ + { "sec", 1, flNone, OH_Implicit }, /* $38 */ + { "and", 3, flUseLabel, OH_AbsoluteY }, /* $39 */ + { "dec", 1, flNone, OH_Accumulator }, /* $3a */ + { "dez", 1, flNone, OH_Implicit }, /* $3b */ + { "bit", 3, flUseLabel, OH_AbsoluteX }, /* $3c */ + { "and", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3d */ + { "rol", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3e */ + { "bbr3", 3, flUseLabel, OH_BitBranch }, /* $3f */ + { "rti", 1, flNone, OH_Rts }, /* $40 */ + { "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */ + { "neg", 1, flSizeChanges, OH_Implicit_42_45GS02 }, /* $42 */ + { "asr", 1, flNone, OH_Accumulator }, /* $43 */ + { "asr", 2, flUseLabel, OH_Direct }, /* $44 */ + { "eor", 2, flUseLabel, OH_Direct }, /* $45 */ + { "lsr", 2, flUseLabel, OH_Direct }, /* $46 */ + { "rmb4", 2, flUseLabel, OH_Direct }, /* $47 */ + { "pha", 1, flNone, OH_Implicit }, /* $48 */ + { "eor", 2, flNone, OH_Immediate }, /* $49 */ + { "lsr", 1, flNone, OH_Accumulator }, /* $4a */ + { "taz", 1, flNone, OH_Implicit }, /* $4b */ + { "jmp", 3, flLabel, OH_JmpAbsolute }, /* $4c */ + { "eor", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4d */ + { "lsr", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4e */ + { "bbr4", 3, flUseLabel, OH_BitBranch }, /* $4f */ + { "bvc", 2, flLabel, OH_Relative }, /* $50 */ + { "eor", 2, flUseLabel, OH_DirectIndirectY }, /* $51 */ + { "eor", 2, flUseLabel, OH_DirectIndirectZ }, /* $52 */ + { "lbvc", 3, flLabel, OH_RelativeLong4510 }, /* $53 */ + { "asr", 2, flUseLabel, OH_DirectX }, /* $54 */ + { "eor", 2, flUseLabel, OH_DirectX }, /* $55 */ + { "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */ + { "rmb5", 2, flUseLabel, OH_Direct }, /* $57 */ + { "cli", 1, flNone, OH_Implicit }, /* $58 */ + { "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */ + { "phy", 1, flNone, OH_Implicit }, /* $5a */ + { "tab", 1, flNone, OH_Implicit }, /* $5b */ + { "map", 1, flNone, OH_Implicit }, /* $5c */ + { "eor", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5d */ + { "lsr", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5e */ + { "bbr5", 3, flUseLabel, OH_BitBranch }, /* $5f */ + { "rts", 1, flNone, OH_Rts }, /* $60 */ + { "adc", 2, flUseLabel, OH_DirectXIndirect }, /* $61 */ + { "rtn", 2, flNone, OH_Immediate }, /* $62 */ + { "bsr", 3, flLabel, OH_RelativeLong4510 }, /* $63 */ + { "stz", 2, flUseLabel, OH_Direct }, /* $64 */ + { "adc", 2, flUseLabel, OH_Direct }, /* $65 */ + { "ror", 2, flUseLabel, OH_Direct }, /* $66 */ + { "rmb6", 2, flUseLabel, OH_Direct, }, /* $67 */ + { "pla", 1, flNone, OH_Implicit }, /* $68 */ + { "adc", 2, flNone, OH_Immediate }, /* $69 */ + { "ror", 1, flNone, OH_Accumulator }, /* $6a */ + { "tza", 1, flNone, OH_Implicit }, /* $6b */ + { "jmp", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $6c */ + { "adc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6d */ + { "ror", 3, flUseLabel, OH_Absolute }, /* $6e */ + { "bbr6", 3, flUseLabel, OH_BitBranch }, /* $6f */ + { "bvs", 2, flLabel, OH_Relative }, /* $70 */ + { "adc", 2, flUseLabel, OH_DirectIndirectY }, /* $71 */ + { "adc", 2, flUseLabel, OH_DirectIndirectZ }, /* $72 */ + { "lbvs", 3, flLabel, OH_RelativeLong4510 }, /* $73 */ + { "stz", 2, flUseLabel, OH_DirectX }, /* $74 */ + { "adc", 2, flUseLabel, OH_DirectX }, /* $75 */ + { "ror", 2, flUseLabel, OH_DirectX }, /* $76 */ + { "rmb7", 2, flUseLabel, OH_Direct }, /* $77 */ + { "sei", 1, flNone, OH_Implicit }, /* $78 */ + { "adc", 3, flUseLabel, OH_AbsoluteY }, /* $79 */ + { "ply", 1, flNone, OH_Implicit }, /* $7a */ + { "tba", 1, flNone, OH_Implicit }, /* $7b */ + { "jmp", 3, flLabel, OH_AbsoluteXIndirect }, /* $7c */ + { "adc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7d */ + { "ror", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7e */ + { "bbr7", 3, flUseLabel, OH_BitBranch }, /* $7f */ + { "bra", 2, flLabel, OH_Relative }, /* $80 */ + { "sta", 2, flUseLabel, OH_DirectXIndirect }, /* $81 */ + { "sta", 2, flNone, OH_StackRelativeIndirectY4510}, /* $82 */ + { "lbra", 3, flLabel, OH_RelativeLong4510 }, /* $83 */ + { "sty", 2, flUseLabel, OH_Direct }, /* $84 */ + { "sta", 2, flUseLabel, OH_Direct }, /* $85 */ + { "stx", 2, flUseLabel, OH_Direct }, /* $86 */ + { "smb0", 2, flUseLabel, OH_Direct }, /* $87 */ + { "dey", 1, flNone, OH_Implicit }, /* $88 */ + { "bit", 2, flNone, OH_Immediate }, /* $89 */ + { "txa", 1, flNone, OH_Implicit }, /* $8a */ + { "sty", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $8b */ + { "sty", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8c */ + { "sta", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8d */ + { "stx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8e */ + { "bbs0", 3, flUseLabel, OH_BitBranch }, /* $8f */ + { "bcc", 2, flLabel, OH_Relative }, /* $90 */ + { "sta", 2, flUseLabel, OH_DirectIndirectY }, /* $91 */ + { "sta", 2, flUseLabel, OH_DirectIndirectZ }, /* $92 */ + { "lbcc", 3, flLabel, OH_RelativeLong4510 }, /* $93 */ + { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */ + { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */ + { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */ + { "smb1", 2, flUseLabel, OH_Direct }, /* $97 */ + { "tya", 1, flNone, OH_Implicit }, /* $98 */ + { "sta", 3, flUseLabel, OH_AbsoluteY }, /* $99 */ + { "txs", 1, flNone, OH_Implicit }, /* $9a */ + { "stx", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $9b */ + { "stz", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $9c */ + { "sta", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9d */ + { "stz", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9e */ + { "bbs1", 3, flUseLabel, OH_BitBranch }, /* $9f */ + { "ldy", 2, flNone, OH_Immediate }, /* $a0 */ + { "lda", 2, flUseLabel, OH_DirectXIndirect }, /* $a1 */ + { "ldx", 2, flNone, OH_Immediate }, /* $a2 */ + { "ldz", 2, flNone, OH_Immediate }, /* $a3 */ + { "ldy", 2, flUseLabel, OH_Direct }, /* $a4 */ + { "lda", 2, flUseLabel, OH_Direct }, /* $a5 */ + { "ldx", 2, flUseLabel, OH_Direct }, /* $a6 */ + { "smb2", 2, flUseLabel, OH_Direct }, /* $a7 */ + { "tay", 1, flNone, OH_Implicit }, /* $a8 */ + { "lda", 2, flNone, OH_Immediate }, /* $a9 */ + { "tax", 1, flNone, OH_Implicit }, /* $aa */ + { "ldz", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ab */ + { "ldy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ac */ + { "lda", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ad */ + { "ldx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ae */ + { "bbs2", 3, flUseLabel, OH_BitBranch }, /* $af */ + { "bcs", 2, flLabel, OH_Relative }, /* $b0 */ + { "lda", 2, flUseLabel, OH_DirectIndirectY }, /* $b1 */ + { "lda", 2, flUseLabel, OH_DirectIndirectZ }, /* $b2 */ + { "lbcs", 3, flLabel, OH_RelativeLong4510 }, /* $b3 */ + { "ldy", 2, flUseLabel, OH_DirectX }, /* $b4 */ + { "lda", 2, flUseLabel, OH_DirectX }, /* $b5 */ + { "ldx", 2, flUseLabel, OH_DirectY }, /* $b6 */ + { "smb3", 2, flUseLabel, OH_Direct }, /* $b7 */ + { "clv", 1, flNone, OH_Implicit }, /* $b8 */ + { "lda", 3, flUseLabel, OH_AbsoluteY }, /* $b9 */ + { "tsx", 1, flNone, OH_Implicit }, /* $ba */ + { "ldz", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bb */ + { "ldy", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bc */ + { "lda", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bd */ + { "ldx", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $be */ + { "bbs3", 3, flUseLabel, OH_BitBranch }, /* $bf */ + { "cpy", 2, flNone, OH_Immediate }, /* $c0 */ + { "cmp", 2, flUseLabel, OH_DirectXIndirect }, /* $c1 */ + { "cpz", 2, flNone, OH_Immediate }, /* $c2 */ + { "dew", 2, flUseLabel, OH_Direct }, /* $c3 */ + { "cpy", 2, flUseLabel, OH_Direct }, /* $c4 */ + { "cmp", 2, flUseLabel, OH_Direct }, /* $c5 */ + { "dec", 2, flUseLabel, OH_Direct }, /* $c6 */ + { "smb4", 2, flUseLabel, OH_Direct }, /* $c7 */ + { "iny", 1, flNone, OH_Implicit }, /* $c8 */ + { "cmp", 2, flNone, OH_Immediate }, /* $c9 */ + { "dex", 1, flNone, OH_Implicit }, /* $ca */ + { "asw", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cb */ + { "cpy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cc */ + { "cmp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cd */ + { "dec", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ce */ + { "bbs4", 3, flUseLabel, OH_BitBranch }, /* $cf */ + { "bne", 2, flLabel, OH_Relative }, /* $d0 */ + { "cmp", 2, flUseLabel, OH_DirectIndirectY }, /* $d1 */ + { "cmp", 2, flUseLabel, OH_DirectIndirectZ }, /* $d2 */ + { "lbne", 3, flLabel, OH_RelativeLong4510 }, /* $d3 */ + { "cpz", 2, flUseLabel, OH_Direct }, /* $d4 */ + { "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */ + { "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */ + { "smb5", 2, flUseLabel, OH_Direct }, /* $d7 */ + { "cld", 1, flNone, OH_Implicit }, /* $d8 */ + { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */ + { "phx", 1, flNone, OH_Implicit }, /* $da */ + { "phz", 1, flNone, OH_Implicit }, /* $db */ + { "cpz", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $dc */ + { "cmp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dd */ + { "dec", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $de */ + { "bbs5", 3, flUseLabel, OH_BitBranch }, /* $df */ + { "cpx", 2, flNone, OH_Immediate }, /* $e0 */ + { "sbc", 2, flUseLabel, OH_DirectXIndirect }, /* $e1 */ + { "lda", 2, flNone, OH_StackRelativeIndirectY4510}, /* $e2 */ + { "inw", 2, flUseLabel, OH_Direct }, /* $e3 */ + { "cpx", 2, flUseLabel, OH_Direct }, /* $e4 */ + { "sbc", 2, flUseLabel, OH_Direct }, /* $e5 */ + { "inc", 2, flUseLabel, OH_Direct }, /* $e6 */ + { "smb6", 2, flUseLabel, OH_Direct }, /* $e7 */ + { "inx", 1, flNone, OH_Implicit }, /* $e8 */ + { "sbc", 2, flNone, OH_Immediate }, /* $e9 */ + { "eom", 1, flSizeChanges, OH_Implicit_ea_45GS02 }, /* $ea */ + { "row", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $eb */ + { "cpx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ec */ + { "sbc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ed */ + { "inc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ee */ + { "bbs6", 3, flUseLabel, OH_BitBranch }, /* $ef */ + { "beq", 2, flLabel, OH_Relative }, /* $f0 */ + { "sbc", 2, flUseLabel, OH_DirectIndirectY }, /* $f1 */ + { "sbc", 2, flUseLabel, OH_DirectIndirectZ }, /* $f2 */ + { "lbeq", 3, flLabel, OH_RelativeLong4510 }, /* $f3 */ + { "phw", 3, flNone, OH_ImmediateWord }, /* $f4 */ + { "sbc", 2, flUseLabel, OH_DirectX }, /* $f5 */ + { "inc", 2, flUseLabel, OH_DirectX }, /* $f6 */ + { "smb7", 2, flUseLabel, OH_Direct }, /* $f7 */ + { "sed", 1, flNone, OH_Implicit }, /* $f8 */ + { "sbc", 3, flUseLabel, OH_AbsoluteY }, /* $f9 */ + { "plx", 1, flNone, OH_Implicit }, /* $fa */ + { "plz", 1, flNone, OH_Implicit }, /* $fb */ + { "phw", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $fc */ + { "sbc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fd */ + { "inc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fe */ + { "bbs7", 3, flUseLabel, OH_BitBranch }, /* $ff */ +}; diff --git a/src/da65/opc45GS02.h b/src/da65/opc45GS02.h new file mode 100644 index 000000000..624e4bbd9 --- /dev/null +++ b/src/da65/opc45GS02.h @@ -0,0 +1,58 @@ +/*****************************************************************************/ +/* */ +/* opc45GS02.h */ +/* */ +/* 45GS10 opcode description table */ +/* */ +/* */ +/* */ +/* (C) 2003 Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef OPC45GS02_H +#define OPC45GS02_H + + + +#include "opcdesc.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all opcodes */ +extern const OpcDesc OpcTable_45GS02[256]; +extern const OpcDesc OpcTable_45GS02_extended[256]; + + +/* End of opc45GS02.h */ + +#endif diff --git a/src/da65/opctable.c b/src/da65/opctable.c index d9068d253..445f8880c 100644 --- a/src/da65/opctable.c +++ b/src/da65/opctable.c @@ -36,6 +36,7 @@ /* da65 */ #include "error.h" #include "opc4510.h" +#include "opc45GS02.h" #include "opc6502.h" #include "opc6502x.h" #include "opc6502dtv.h" @@ -78,6 +79,7 @@ void SetOpcTable (cpu_t CPU) case CPU_HUC6280: OpcTable = OpcTable_HuC6280; break; case CPU_M740: OpcTable = OpcTable_M740; break; case CPU_4510: OpcTable = OpcTable_4510; break; + case CPU_45GS02: OpcTable = OpcTable_45GS02; break; default: Error ("Unsupported CPU"); } } diff --git a/test/asm/cpudetect/allinst.inc b/test/asm/cpudetect/allinst.inc index e58577b7e..8e27a5429 100644 --- a/test/asm/cpudetect/allinst.inc +++ b/test/asm/cpudetect/allinst.inc @@ -651,6 +651,7 @@ LABEL3: map ; $5c ("4-byte NOP reserved for future expansion" on 65CE02) asw $1234 ; $cb (wai on W65C02) phz ; $db (stp on W65C02) + eom ; $ea "end of mapping" - but really just a NOP .endscope .endif @@ -666,11 +667,11 @@ LABEL3: aslq $12 ; $42 $42 $06 aslq ; $42 $42 $0a orq $1234 ; $42 $42 $0d - aslq $1234 ; $42 $42 $0f + aslq $1234 ; $42 $42 $0e orq ($12) ; $42 $42 $12 aslq $12,x ; $42 $42 $16 inq ; $42 $42 $1a - aslq $124,x ; $42 $42 $1e + aslq $1234,x ; $42 $42 $1e bitq $12 ; $42 $42 $24 andq $12 ; $42 $42 $25 rolq $12 ; $42 $42 $26 From 2244a5ab0a018f4c5c2f0608d7cfabdcdf861054 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 20:44:37 +0200 Subject: [PATCH 558/707] include header :) --- src/da65/handler.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/da65/handler.c b/src/da65/handler.c index 3d1d0d7d0..b1664efa5 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -47,6 +47,7 @@ #include "handler.h" #include "labels.h" #include "opctable.h" +#include "opc45GS02.h" #include "output.h" From 5e414edb50018992daee92647b5e83923656020b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 20:47:57 +0200 Subject: [PATCH 559/707] are we more pedantic than local make? --- src/da65/handler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index b1664efa5..e6132e945 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -291,7 +291,7 @@ void OH_Implicit_42_45GS02 (const OpcDesc* D) } } else { /* use another table for these */ - OpcDesc* NewDesc = &OpcTable_45GS02_extended[opc]; + const OpcDesc* NewDesc = &OpcTable_45GS02_extended[opc]; NewDesc->Handler (NewDesc); return; } From c35405f14b05602ef1cd49d61e93dcaf106d3cbf Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 20:52:03 +0200 Subject: [PATCH 560/707] add new sourcefile(s) --- src/da65.vcxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 9d2b0ded6..6610f907c 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -94,6 +94,7 @@ <ClCompile Include="da65\labels.c" /> <ClCompile Include="da65\main.c" /> <ClCompile Include="da65\opc4510.c" /> + <ClCompile Include="da65\opc45GS02.c" /> <ClCompile Include="da65\opc6502.c" /> <ClCompile Include="da65\opc6502x.c" /> <ClCompile Include="da65\opc6502dtv.c" /> @@ -119,6 +120,7 @@ <ClInclude Include="da65\infofile.h" /> <ClInclude Include="da65\labels.h" /> <ClInclude Include="da65\opc4510.h" /> + <ClInclude Include="da65\opc45GS02.h" /> <ClInclude Include="da65\opc6502.h" /> <ClInclude Include="da65\opc6502x.h" /> <ClInclude Include="da65\opc6502dtv.h" /> @@ -136,4 +138,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> \ No newline at end of file +</Project> From 698045c7c2989c6b1040dd76c83cc626b1eeeb54 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 21:55:21 +0200 Subject: [PATCH 561/707] updated the docs --- doc/ca65.sgml | 15 +++++++-- doc/da65.sgml | 93 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 84 insertions(+), 24 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 8c0c4fa61..99459d5ab 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -151,8 +151,19 @@ Here is a description of all the command line options: Set the default for the CPU type. The option takes a parameter, which may be one of - - 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510, 45GS02, M740 + <itemize> + <item>6502 - NMOS 6502 (all legal instructions) + <item>6502X - NMOS 6502 with all undocumented instructions + <item>6502DTV - the emulated CPU of the C64DTV device + <item>65SC02 - first CMOS instruction set (no bit manipulation, no wai/stp) + <item>65C02 - full CMOS instruction set (has bit manipulation and wai/stp) + <item>65816 - the CPU of the SNES, and the SCPU + <item>HuC6280 - the CPU of the PC engine + <item>4510 - the CPU of the Commodore C65 + <item>45GS02 - the CPU of the Commodore MEGA65 + <item>M740 - a Microcontroller by Mitsubishi + <item>sweet16 - an interpreter for a pseudo 16 bit CPU + </itemize> <label id="option-create-dep"> diff --git a/doc/da65.sgml b/doc/da65.sgml index 5da65d82c..95ffbc24b 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -110,23 +110,18 @@ Here is a description of all the command line options: Set the CPU type. The option takes a parameter, which may be one of <itemize> - <item>6502 - <item>6502x - <item>6502dtv - <item>65sc02 - <item>65c02 - <item>65816 - <item>huc6280 - <item>4510 - <item>45GS02 - <item>m740 + <item>6502 - NMOS 6502 (all legal instructions) + <item>6502X - NMOS 6502 with all undocumented instructions + <item>6502DTV - the emulated CPU of the C64DTV device + <item>65SC02 - first CMOS instruction set (no bit manipulation, no wai/stp) + <item>65C02 - full CMOS instruction set (has bit manipulation and wai/stp) + <item>65816 - the CPU of the SNES, and the SCPU + <item>HuC6280 - the CPU of the PC engine + <item>4510 - the CPU of the Commodore C65 + <item>45GS02 - the CPU of the Commodore MEGA65 + <item>M740 - a Microcontroller by Mitsubishi </itemize> - 6502x is for the NMOS 6502 with unofficial opcodes. 6502dtv is for the - emulated CPU of the C64DTV device. huc6280 is the CPU of the PC engine. - 4510 is the CPU of the Commodore C65. 45GS02 is the CPU of the MEGA65. - 65816 is the CPU of the SNES. M740 is a Microcontroller by Mitsubishi. - <label id="option--formfeeds"> <tag><tt>-F, --formfeeds</tt></tag> @@ -249,24 +244,78 @@ Here is a description of all the command line options: <sect1>Supported CPUs<p> +With the command line option <tt><ref id="option--cpu" name="--cpu"></tt>, the +disassembler may be told which CPU to support: + + <itemize> + <item><ref id="6502-mode" name="6502 mode"> - NMOS 6502 (all legal instructions) + <item><ref id="6502X-mode" name="6502X mode"> - NMOS 6502 with all undocumented instructions + <item><ref id="DTV-mode" name="6502DTV"> - the emulated CPU of the C64DTV device + <item><ref id="65SC02-mode" name="65SC02"> - first CMOS instruction set (no bit manipulation, no wai/stp) + <item><ref id="65C02-mode" name="65C02"> - full CMOS instruction set (has bit manipulation and wai/stp) + <item><ref id="65816-mode" name="65816"> - the CPU of the SNES, and the SCPU + <item><ref id="HUC6280-mode" name="HuC6280"> - the CPU of the PC engine + <item><ref id="4510-mode" name="4510"> - the CPU of the Commodore C65 + <item><ref id="45GS02-mode" name="45GS02"> - the CPU of the Commodore MEGA65 + <item><ref id="M740-mode" name="M740"> - a Microcontroller by Mitsubishi + </itemize> + +for more details on the various CPUs, see <tt><htmlurl url="ca65.html#6502-mode" name="here"></tt>. + + +<sect1>6502 mode<label id="6502-mode"><p> + The default (no CPU given on the command line or in the <tt/GLOBAL/ section of the info file) is the 6502 CPU. The disassembler knows all "official" opcodes for this CPU. Invalid opcodes are translated into <tt/.byte/ commands. -With the command line option <tt><ref id="option--cpu" name="--cpu"></tt>, the -disassembler may be told to recognize either the 65SC02 or 65C02 CPUs. The -latter understands the same opcodes as the former, plus 16 additional bit -manipulation and bit test-and-branch commands. Using 6502x as CPU the illegal -opcodes of 6502 CPU are detected and displayed. 6502dtv setting recognizes the -emulated CPU instructions of the C64DTV device. +<sect1>6502X mode<label id="6502X-mode"><p> +Using 6502X as CPU the illegal opcodes of 6502 CPU are detected and displayed. + + +<sect1>DTV mode<label id="DTV-mode"><p> + +6502DTV setting recognizes the emulated CPU instructions of the C64DTV device. + + +<sect1>65SC02 mode<label id="65SC02-mode"><p> + +The first CMOS instruction set, without bit manipulation or wai/stp. + + +<sect1>65C02 mode<label id="65C02-mode"><p> + +The 65C02 understands the same opcodes as the 65SC02, plus 16 additional bit +manipulation and bit test-and-branch commands. + +This mode also supports wai/stp. + + +<sect1>4510 mode<label id="4510-mode"><p> When disassembling 4510 code, due to handling of 16-bit wide branches, da65 can produce output that can not be re-assembled, when one or more of those branches point outside of the disassembled memory. This can happen when text or binary data is processed. -Disassembling 45GS02 compound instructions currently not supported. + +<sect1>45GS02 mode<label id="45GS02-mode"><p> + +All compound instructions are supported. + + +<sect1>HUC6280 mode<label id="HUC6280-mode"><p> + +All special opcodes are supported. + + +<sect1>M740 mode<label id="M740-mode"><p> + +All special opcodes are supported. + + +<sect1>65816 mode<label id="65816-mode"><p><p> The 65816 support requires annotating ranges with the M and X flag states. This can be recorded with an emulator that supports Code and Data Logging, From 12e40f4aff00e4a4eec01e83162dfcc4532957ee Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 22:05:30 +0200 Subject: [PATCH 562/707] fix some codestyle --- src/ca65/ea65.c | 8 ++++---- src/ca65/instr.c | 24 +++++++++++++----------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c index 0e20ccff9..898b344ca 100644 --- a/src/ca65/ea65.c +++ b/src/ca65/ea65.c @@ -101,7 +101,7 @@ void GetEA (EffAddr* A) if (TokIsSep (CurTok.Tok)) { A->AddrModeSet = AM65_IMPLICIT; - if (GetCPU() == CPU_45GS02) { + if (GetCPU () == CPU_45GS02) { A->AddrModeSet |= AM65_Q; } @@ -194,12 +194,12 @@ void GetEA (EffAddr* A) if (CurTok.Tok == TOK_COMMA) { /* [dir],y */ NextTok (); - if (GetCPU() == CPU_45GS02) { - Consume(TOK_Z, "'Z' expected"); + if (GetCPU () == CPU_45GS02) { + Consume (TOK_Z, "'Z' expected"); A->AddrModeSet = AM65_32BIT_BASE_IND_Z; } else { - Consume(TOK_Y, "'Y' expected"); + Consume (TOK_Y, "'Y' expected"); A->AddrModeSet = AM65_DIR_IND_LONG_Y; } } else { diff --git a/src/ca65/instr.c b/src/ca65/instr.c index ca44f5509..9941517f3 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -2214,7 +2214,7 @@ static void Emit4510 (EffAddr* A) { } /* No error, output code */ - EmitCode(A); + EmitCode (A); } @@ -2226,7 +2226,7 @@ static void Put4510 (const InsDesc* Ins) /* Evaluate the addressing mode used */ if (EvalEA (Ins, &A)) { - Emit4510(&A); + Emit4510 (&A); } } @@ -2237,24 +2237,26 @@ static void Put45GS02 (const InsDesc* Ins) { EffAddr A; - if (EvalEA(Ins, &A)) { + if (EvalEA (Ins, &A)) { if (A.AddrModeSet == AM65_32BIT_BASE_IND_Z) { - Emit0(0xEA); /* NOP prefix */ + Emit0 (0xEA); /* NOP prefix */ } - Emit4510(&A); + Emit4510 (&A); } } -static void Put45GS02_Q (const InsDesc* Ins) { +static void Put45GS02_Q (const InsDesc* Ins) +{ EffAddr A; if (EvalEA(Ins, &A)) { - Emit0(0x42); - Emit0(0x42); - if ((A.AddrModeBit == AM65_DIR_IND_LONG) || (A.AddrModeBit == AM65_32BIT_BASE_IND_Z)) { - Emit0(0xEA); /* NOP prefix */ + Emit0 (0x42); + Emit0 (0x42); + if ((A.AddrModeBit == AM65_DIR_IND_LONG) || + (A.AddrModeBit == AM65_32BIT_BASE_IND_Z)) { + Emit0 (0xEA); /* NOP prefix */ } if (A.Opcode == 0xea) { A.Opcode = 0x1a; @@ -2262,7 +2264,7 @@ static void Put45GS02_Q (const InsDesc* Ins) { else if (A.Opcode == 0xca) { A.Opcode = 0x3a; } - EmitCode(&A); + EmitCode (&A); } } From 4820b716c7d4764182a2a039a68a1436aafe4e36 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 22:12:53 +0200 Subject: [PATCH 563/707] use sect2 for cpu subsections --- doc/ca65.sgml | 22 +++++++++++----------- doc/da65.sgml | 20 ++++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 99459d5ab..1503b2f39 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -468,12 +468,12 @@ byte. If omitted, the assembler will only produce only 1 byte. brk #$34 ; 2-bytes: $00 $34 </verb></tscreen> -<sect1>6502 mode<label id="6502-mode"><p> +<sect2>6502 mode<label id="6502-mode"><p> In 6502 mode (which is the default) the assembler accepts all regular "legal" 6502 mnemonics and addressing modes. -<sect1>6502X mode<label id="6502X-mode"><p> +<sect2>6502X mode<label id="6502X-mode"><p> 6502X mode is an extension to the normal 6502 mode. In this mode, several mnemonics for undocumented instructions of the NMOS 6502 CPUs are accepted. @@ -505,7 +505,7 @@ for them. </itemize> -<sect1>DTV mode<label id="DTV-mode"><p> +<sect2>DTV mode<label id="DTV-mode"><p> The C64DTV CPU is based on the 6510, but adds some instructions, and does not support all undocumented instructions. @@ -533,7 +533,7 @@ Supported undocumented instructions: </itemize> -<sect1>65SC02 mode<label id="65SC02-mode"><p> +<sect2>65SC02 mode<label id="65SC02-mode"><p> 65SC02 mode supports all regular 6502 instructions, plus the following: @@ -568,7 +568,7 @@ $fa plx </verb></tscreen> -<sect1>65C02 mode<label id="65C02-mode"><p> +<sect2>65C02 mode<label id="65C02-mode"><p> 65C02 mode supports all "official" W65C02 opcodes. @@ -589,7 +589,7 @@ $db stp wait for reset </verb></tscreen> -<sect1>4510 mode<label id="4510-mode"><p> +<sect2>4510 mode<label id="4510-mode"><p> The 4510 is a microcontroller that is the core of the Commodore C65 aka C64DX. It contains among other functions a slightly modified 65CE02/4502 CPU, to allow @@ -620,13 +620,13 @@ For more information about the Commodore C65/C64DX and the 4510 CPU, see <url url="http://www.zimmers.net/anonftp/pub/cbm/c65/"> and <url url="https://en.wikipedia.org/wiki/Commodore_65" name="Wikipedia">. -<sect1>45GS02 mode<label id="45GS02-mode"><p> +<sect2>45GS02 mode<label id="45GS02-mode"><p> The 45GS02 is a microcontroller that is the core of the MEGA65. It is an extension of the 4510 CPU and adds 32-bit addressing and a 32-bit pseudo register Q that is comprised of the four registers A, X, Y, and Z. -<sect1>HUC6280 mode<label id="HUC6280-mode"><p> +<sect2>HUC6280 mode<label id="HUC6280-mode"><p> The HUC6280 is a superset of the R65C02. It adds some other instructions: @@ -662,7 +662,7 @@ $f4 set Note that this CPU does not implement <tt>wai</tt> and <tt>stp</tt>. -<sect1>M740 mode<label id="M740-mode"><p> +<sect2>M740 mode<label id="M740-mode"><p> The M740 is a microcontroller by Mitsubishi, which was marketed for embedded devices in the mid 80s. It is a superset of 6502, and a subset of 65SC02, plus @@ -672,7 +672,7 @@ For more information about the M740 Controllers, see <url url="https://en.wikipedia.org/wiki/Mitsubishi_740" name="Wikipedia">. -<sect1>65816 mode<label id="65816-mode"><p><p> +<sect2>65816 mode<label id="65816-mode"><p><p> In 65816 mode, several aliases are accepted, in addition to the official mnemonics: @@ -700,7 +700,7 @@ or two far addresses whose high byte will be used. </verb></tscreen> -<sect1>sweet16 mode<label id="sweet16-mode"><p> +<sect2>sweet16 mode<label id="sweet16-mode"><p> SWEET 16 is an interpreter for a pseudo 16 bit CPU written by Steve Wozniak for the Apple ][ machines. It is available in the Apple ][ ROM. ca65 can diff --git a/doc/da65.sgml b/doc/da65.sgml index 95ffbc24b..7300d3d71 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -263,28 +263,28 @@ disassembler may be told which CPU to support: for more details on the various CPUs, see <tt><htmlurl url="ca65.html#6502-mode" name="here"></tt>. -<sect1>6502 mode<label id="6502-mode"><p> +<sect2>6502 mode<label id="6502-mode"><p> The default (no CPU given on the command line or in the <tt/GLOBAL/ section of the info file) is the 6502 CPU. The disassembler knows all "official" opcodes for this CPU. Invalid opcodes are translated into <tt/.byte/ commands. -<sect1>6502X mode<label id="6502X-mode"><p> +<sect2>6502X mode<label id="6502X-mode"><p> Using 6502X as CPU the illegal opcodes of 6502 CPU are detected and displayed. -<sect1>DTV mode<label id="DTV-mode"><p> +<sect2>DTV mode<label id="DTV-mode"><p> 6502DTV setting recognizes the emulated CPU instructions of the C64DTV device. -<sect1>65SC02 mode<label id="65SC02-mode"><p> +<sect2>65SC02 mode<label id="65SC02-mode"><p> The first CMOS instruction set, without bit manipulation or wai/stp. -<sect1>65C02 mode<label id="65C02-mode"><p> +<sect2>65C02 mode<label id="65C02-mode"><p> The 65C02 understands the same opcodes as the 65SC02, plus 16 additional bit manipulation and bit test-and-branch commands. @@ -292,7 +292,7 @@ manipulation and bit test-and-branch commands. This mode also supports wai/stp. -<sect1>4510 mode<label id="4510-mode"><p> +<sect2>4510 mode<label id="4510-mode"><p> When disassembling 4510 code, due to handling of 16-bit wide branches, da65 can produce output that can not be re-assembled, when one or more of those @@ -300,22 +300,22 @@ branches point outside of the disassembled memory. This can happen when text or binary data is processed. -<sect1>45GS02 mode<label id="45GS02-mode"><p> +<sect2>45GS02 mode<label id="45GS02-mode"><p> All compound instructions are supported. -<sect1>HUC6280 mode<label id="HUC6280-mode"><p> +<sect2>HUC6280 mode<label id="HUC6280-mode"><p> All special opcodes are supported. -<sect1>M740 mode<label id="M740-mode"><p> +<sect2>M740 mode<label id="M740-mode"><p> All special opcodes are supported. -<sect1>65816 mode<label id="65816-mode"><p><p> +<sect2>65816 mode<label id="65816-mode"><p><p> The 65816 support requires annotating ranges with the M and X flag states. This can be recorded with an emulator that supports Code and Data Logging, From 6b554362a531d44e8c19f7f4cc2fc0c3f676c9db Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 22:23:19 +0200 Subject: [PATCH 564/707] codestyle/comment --- src/da65/main.c | 4 +++- src/da65/opc45GS02.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/da65/main.c b/src/da65/main.c index e315a3a90..cf31c0baa 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -371,6 +371,7 @@ static unsigned HandleChangedLength(const OpcDesc* D, unsigned PC) if (CPU == CPU_45GS02) { if ((D->Handler == OH_Implicit_42_45GS02)) { if (GetCodeByte (PC+1) == 0x42) { + /* NEG:NEG prefix (0x42 0x42) */ unsigned opc = GetCodeByte (PC+2); if (opc == 0xea) { /* 42 42 ea */ @@ -385,7 +386,8 @@ static unsigned HandleChangedLength(const OpcDesc* D, unsigned PC) } } } - }else if ((D->Handler == OH_Implicit_ea_45GS02)) { + } else if ((D->Handler == OH_Implicit_ea_45GS02)) { + /* NOP prefix (0xea) */ if ((GetCodeByte (PC+1) & 0x1f) == 0x12) { PC += 2; } diff --git a/src/da65/opc45GS02.c b/src/da65/opc45GS02.c index a831d539c..90b6a56ab 100644 --- a/src/da65/opc45GS02.c +++ b/src/da65/opc45GS02.c @@ -45,7 +45,7 @@ -/* Descriptions for all compound instructions with NEG:NEG prefix */ +/* Descriptions for all compound instructions with NEG:NEG prefix (0x42 0x42) */ const OpcDesc OpcTable_45GS02_extended[256] = { { "", 1+2, flIllegal, OH_Illegal, }, /* $00 */ { "", 1+2, flIllegal, OH_Illegal, }, /* $01 */ From 4a11fa791a24c01866d3038f817bce605304304d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 21 Jun 2025 22:33:43 +0200 Subject: [PATCH 565/707] more codestyle --- src/ca65/instr.c | 2 +- src/da65/main.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 9941517f3..4f818b047 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -2251,7 +2251,7 @@ static void Put45GS02_Q (const InsDesc* Ins) { EffAddr A; - if (EvalEA(Ins, &A)) { + if (EvalEA (Ins, &A)) { Emit0 (0x42); Emit0 (0x42); if ((A.AddrModeBit == AM65_DIR_IND_LONG) || diff --git a/src/da65/main.c b/src/da65/main.c index cf31c0baa..545cc657b 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -369,7 +369,7 @@ static unsigned HandleChangedLength(const OpcDesc* D, unsigned PC) { if (D->Flags & flSizeChanges) { if (CPU == CPU_45GS02) { - if ((D->Handler == OH_Implicit_42_45GS02)) { + if (D->Handler == OH_Implicit_42_45GS02) { if (GetCodeByte (PC+1) == 0x42) { /* NEG:NEG prefix (0x42 0x42) */ unsigned opc = GetCodeByte (PC+2); @@ -386,7 +386,7 @@ static unsigned HandleChangedLength(const OpcDesc* D, unsigned PC) } } } - } else if ((D->Handler == OH_Implicit_ea_45GS02)) { + } else if (D->Handler == OH_Implicit_ea_45GS02) { /* NOP prefix (0xea) */ if ((GetCodeByte (PC+1) & 0x1f) == 0x12) { PC += 2; From c3b75f0ac11e44034bd7ac6bbca328a493577da2 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 22 Jun 2025 01:15:10 +0200 Subject: [PATCH 566/707] comment --- src/ca65/instr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 4f818b047..c19be11b2 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1377,7 +1377,7 @@ static unsigned char EATab[16][AM65I_COUNT] = { 0x00, 0x00, 0x00, 0x03, 0x13, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00 }, - { /* Table 1 (rol, ror, stx, sty, tst) */ + { /* Table 1 (rol, ror, stx, sty, tst, cpx, cpy) */ 0x08, 0x08, 0x04, 0x0C, 0x00, 0x14, 0x1C, 0x00, 0x14, 0x1C, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, From 2ae30b5b507eec3c67975cc3cd1439ff99792c1c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 22 Jun 2025 01:15:40 +0200 Subject: [PATCH 567/707] cleanup --- src/da65/handler.c | 33 --------------------------------- src/da65/handler.h | 1 - 2 files changed, 34 deletions(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index e6132e945..84229594f 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -680,39 +680,6 @@ void OH_BitBranch (const OpcDesc* D) -void OH_BitBranch_Q (const OpcDesc* D) -{ - char* BranchLabel; - - /* Get the operands */ - unsigned char TestAddr = GetCodeByte (PC+3); - signed char BranchOffs = GetCodeByte (PC+4); - - /* Calculate the target address for the branch */ - unsigned BranchAddr = (((int) PC+5) + BranchOffs) & 0xFFFF; - - /* Generate labels in pass 1. The bit branch codes are special in that - ** they don't really match the remainder of the 6502 instruction set (they - ** are a Rockwell addon), so we must pass additional flags as direct - ** value to the second GenerateLabel call. - */ - GenerateLabel (D->Flags, TestAddr); - GenerateLabel (flLabel, BranchAddr); - - /* Make a copy of an operand, so that - ** the other operand can't overwrite it. - ** [GetAddrArg() uses a statically-stored buffer.] - */ - BranchLabel = xstrdup (GetAddrArg (flLabel, BranchAddr)); - - /* Output the line */ - OneLine (D, "%s,%s", GetAddrArg (D->Flags, TestAddr), BranchLabel); - - xfree (BranchLabel); -} - - - void OH_BitBranch_m740 (const OpcDesc* D) /* <bit> zp, rel ** NOTE: currently <bit> is part of the instruction diff --git a/src/da65/handler.h b/src/da65/handler.h index 6286d4e40..fc82595c6 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -108,7 +108,6 @@ void OH_Direct_Q (const OpcDesc*); void OH_DirectIndirectZ_Q (const OpcDesc* D); void OH_Absolute_Q (const OpcDesc* D); void OH_AbsoluteX_Q (const OpcDesc* D); -void OH_BitBranch_Q (const OpcDesc* D); void OH_DirectX_Q (const OpcDesc* D); void OH_Implicit_ea_45GS02 (const OpcDesc* D); void OH_Implicit_42_45GS02 (const OpcDesc* D); From 233c784c03105bda6f8dfd6b70597510435c58f3 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 22 Jun 2025 01:16:03 +0200 Subject: [PATCH 568/707] fix aslq in the disassembler --- src/da65/opc45GS02.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/da65/opc45GS02.c b/src/da65/opc45GS02.c index 90b6a56ab..21650f53d 100644 --- a/src/da65/opc45GS02.c +++ b/src/da65/opc45GS02.c @@ -61,7 +61,7 @@ const OpcDesc OpcTable_45GS02_extended[256] = { { "", 1+2, flIllegal, OH_Illegal, }, /* $0b */ { "", 1+2, flIllegal, OH_Illegal, }, /* $0c */ { "orq", 3+2, flUseLabel|flAbsOverride, OH_Absolute_Q }, /* $0d */ - { "aslq", 3+2, flUseLabel, OH_BitBranch_Q }, /* $0e */ + { "aslq", 3+2, flUseLabel, OH_Absolute_Q }, /* $0e */ { "", 1+2, flIllegal, OH_Illegal, }, /* $0f */ { "", 1+2, flIllegal, OH_Illegal, }, /* $10 */ { "", 1+2, flIllegal, OH_Illegal, }, /* $11 */ From 1d7bc938f2a3f0790c1e16921beb039cb1b5720e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 22 Jun 2025 01:18:41 +0200 Subject: [PATCH 569/707] add roundtrip disasm tests for all cpus --- test/dasm/45GS02-disass.s | 381 +++++++++++++++++++++++++++++++++++++ test/dasm/6502-disass.s | 8 + test/dasm/6502DTV-disass.s | 188 ++++++++++++++++++ test/dasm/6502X-disass.s | 30 +++ test/dasm/65C02-disass.s | 214 +++++++++++++++++++++ test/dasm/65SC02-disass.s | 181 ++++++++++++++++++ test/dasm/huc6280-disass.s | 250 ++++++++++++++++++++++++ test/dasm/m740-disass.s | 8 + test/dasm/readme.txt | 9 + 9 files changed, 1269 insertions(+) create mode 100644 test/dasm/45GS02-disass.s create mode 100644 test/dasm/6502-disass.s create mode 100644 test/dasm/6502DTV-disass.s create mode 100644 test/dasm/6502X-disass.s create mode 100644 test/dasm/65C02-disass.s create mode 100644 test/dasm/65SC02-disass.s create mode 100644 test/dasm/huc6280-disass.s create mode 100644 test/dasm/m740-disass.s create mode 100644 test/dasm/readme.txt diff --git a/test/dasm/45GS02-disass.s b/test/dasm/45GS02-disass.s new file mode 100644 index 000000000..1ed174a2f --- /dev/null +++ b/test/dasm/45GS02-disass.s @@ -0,0 +1,381 @@ +.setcpu "45GS02" + +ZP = $12 +ABS = $1234 + + brk + ora ($05,x) + cle + see + tsb $02 + ora $02 + asl $02 + rmb0 $02 + php + ora #$01 + asl + tsy + tsb $1234 + ora $1234 + asl $1234 + bbr0 $02, L0 +L0: + bpl L0 + ora ($06),y + ora ($07),z + lbpl *+$3133 ; bpl *+$3133 + trb $02 + ora $03,x + asl $03,x + rmb1 $02 + clc + ora $1456,y + inc + inz + trb $1234 + ora $1345,x + asl $1345,x + bbr1 $02,L1 +L1: + jsr $1234 + and ($05,x) + jsr ($2345) + jsr ($2456,x) + bit $02 + and $02 + rol $02 + rmb2 $02 + plp + and #$01 + rol + tys + bit $1234 + and $1234 + rol $1234 + bbr2 $02,L2 +L2: + bmi L2 + and ($06),y + and ($07),z + lbmi *+$3133 ; bmi *+$3133 + bit $03,x + and $03,x + rol $03,x + rmb3 $02 + sec + and $1456,y + dec + dez + bit $1345,x + and $1345,x + rol $1345,x + bbr3 $02,L3 +L3: + rti + eor ($05,x) + neg + asr + asr $02 + eor $02 + lsr $02 + rmb4 $02 + pha + eor #$01 + lsr + taz + jmp $1234 + eor $1234 + lsr $1234 + bbr4 $02,L4 +L4: + bvc L4 + eor ($06),y + eor ($07),z + lbvc *+$3133 ; bvc *+$3133 + asr $03,x + eor $03,x + lsr $03,x + rmb5 $02 + cli + eor $1456,y + phy + tab + map + eor $1345,x + lsr $1345,x + bbr5 $02,L5 +L5: + rts + adc ($05,x) + rtn #$09 + bsr *+$3133 + stz $02 + adc $02 + ror $02 + rmb6 $02 + pla + adc #$01 + ror + tza + jmp ($2345) + adc $1234 + ror $1234 + bbr6 $02,L6 +L6: + bvs L6 + adc ($06),y + adc ($07),z + lbvs *+$3133 ; bvs *+$3133 + stz $03,x + adc $03,x + ror $03,x + rmb7 $02 + sei + adc $1456,y + ply + tba + jmp ($2456,x) + adc $1345,x + ror $1345,x + bbr7 $02,L7 +L7: + bra L7 + sta ($05,x) + sta ($0f,s),y + sta ($0f,sp),y + lbra *+$3133 ; bra *+$3133 + sty $02 + sta $02 + stx $02 + smb0 $02 + dey + bit #$01 + txa + sty $1345,x + sty $1234 + sta $1234 + stx $1234 + bbs0 $02,L8 +L8: + bcc L8 + sta ($06),y + sta ($07),z + lbcc *+$3133 ; bcc *+$3133 + sty $03,x + sta $03,x + stx $04,y + smb1 $02 + tya + sta $1456,y + txs + stx $1456,y + stz $1234 + sta $1345,x + stz $1345,x + bbs1 $02,L9 +L9: + ldy #$01 + lda ($05,x) + ldx #$01 + ldz #$01 + ldy $02 + lda $02 + ldx $02 + smb2 $02 + tay + lda #$01 + tax + ldz $1234 + ldy $1234 + lda $1234 + ldx $1234 + bbs2 $02,L10 +L10: + bcs L10 + lda ($06),y + lda ($07),z + lbcs *+$3133 ; bcs *+$3133 + ldy $03,x + lda $03,x + ldx $04,y + smb3 $02 + clv + lda $1456,y + tsx + ldz $1345,x + ldy $1345,x + lda $1345,x + ldx $1456,y + bbs3 $02,L11 +L11: + cpy #$01 + cmp ($05,x) + cpz #$01 + dew $02 + cpy $02 + cmp $02 + dec $02 + smb4 $02 + iny + cmp #$01 + dex + asw $1234 + cpy $1234 + cmp $1234 + dec $1234 + bbs4 $02,L12 +L12: + bne L12 + cmp ($06),y + cmp ($07),z + lbne *+$3133 ; bne *+$3133 + cpz $02 + cmp $03,x + dec $03,x + smb5 $02 + cld + cmp $1456,y + phx + phz + cpz $1234 + cmp $1345,x + dec $1345,x + bbs5 $02,L13 +L13: + cpx #$01 + sbc ($05,x) + lda ($0f,s),y + lda ($0f,sp),y + inw $02 + cpx $02 + sbc $02 + inc $02 + smb6 $02 + inx + sbc #$01 + eom + nop + row $1234 + cpx $1234 + sbc $1234 + inc $1234 + bbs6 $02,L14 +L14: + beq L14 + sbc ($06),y + sbc ($07),z + lbeq *+$3133 ; beq *+$3133 + phd #$089a + phw #$089a + sbc $03,x + inc $03,x + smb7 $02 + sed + sbc $1456,y + plx + plz + phd $1234 + phw $1234 + sbc $1345,x + inc $1345,x + bbs7 $02,L15 +L15: + + adc [$12],z + + adcq $12 + adcq $3456 + adcq ($78) + adcq [$9a] + + and [$12],z + + andq $12 + andq $3456 + andq ($78) + andq [$9a] + + aslq $12 + aslq + aslq $3456 + aslq $78,x + aslq $9abc,x + + asrq + asrq $12 + asrq $34,x + + bitq $12 + bitq $3456 + + cmp [$12],z + + cmpq $12 + cmpq $3456 + cmpq ($78) + cmpq [$9a] + + deq + deq $12 + deq $3456 + deq $78,x + deq $9abc,x + + eor [$12],z + + eorq $12 + eorq $3456 + eorq ($78) + eorq [$9a] + + inq + inq $12 + inq $3456 + inq $78,x + inq $9abc,x + + lda [$12],z + + ldq $12 + ldq $3456 + ldq ($78),z + ldq [$9a],z + + lsrq $12 + lsrq + lsrq $3456 + lsrq $78,x + lsrq $9abc,x + + ora [$12],z + + orq $12 + orq $3456 + orq ($78) + orq [$9a] + + rolq $12 + rolq + rolq $3456 + rolq $78,x + rolq $9abc,x + + rorq $12 + rorq + rorq $3456 + rorq $78,x + rorq $9abc,x + + sbc [$12],z + + sbcq $12 + sbcq $3456 + sbcq ($78) + sbcq [$9a] + + sta [$12],z ; EA 92 12 + + stq $12 + stq $3456 + stq ($78) + stq [$9a] diff --git a/test/dasm/6502-disass.s b/test/dasm/6502-disass.s new file mode 100644 index 000000000..794eead76 --- /dev/null +++ b/test/dasm/6502-disass.s @@ -0,0 +1,8 @@ + + .setcpu "6502" + + .repeat 256, cnt + + .byte 0 + cnt, $02, $ea, $00 + + .endrepeat diff --git a/test/dasm/6502DTV-disass.s b/test/dasm/6502DTV-disass.s new file mode 100644 index 000000000..5254923c5 --- /dev/null +++ b/test/dasm/6502DTV-disass.s @@ -0,0 +1,188 @@ +.setcpu "6502DTV" + + brk + ora ($12,x) + nop $12 + ora $12 + asl $12 + php + ora #$12 + asl a + anc #$12 + nop $3456 + ora $3456 + asl $3456 + bpl *+2 + ora ($12),y + bra *+2 + nop $12,x + ora $12,x + asl $12,x + clc + ora $3456,y + nop $3456,x + ora $3456,x + asl $3456,x + jsr $3456 + and ($12,x) + rla ($12,x) + bit $12 + and $12 + rol $12 + rla $12 + plp + and #$12 + rol a + bit $3456 + and $3456 + rol $3456 + rla $3456 + bmi *+2 + and ($12),y + sac #$12 + rla ($12),y + and $12,x + rol $12,x + rla $12,x + sec + and $3456,y + rla $3456,y + and $3456,x + rol $3456,x + rla $3456,x + rti + eor ($12,x) + sir #$12 + eor $12 + lsr $12 + pha + eor #$12 + lsr a + alr #$12 + jmp $3456 + eor $3456 + lsr $3456 + bvc *+2 + eor ($12),y + eor $12,x + lsr $12,x + cli + eor $3456,x + lsr $3456,x + rts + adc ($12,x) + rra ($12,x) + adc $12 + ror $12 + rra $12 + pla + adc #$12 + ror a + arr #$12 + jmp ($3456) + adc $3456 + ror $3456 + rra $3456 + bvs *+2 + adc ($12),y + rra ($12),y + adc $12,x + ror $12,x + rra $12,x + sei + adc $3456,y + rra $3456,y + adc $3456,x + ror $3456,x + rra $3456,x + nop #$12 + sta ($12,x) + sty $12 + sta $12 + stx $12 + dey + txa + sty $3456 + sta $3456 + stx $3456 + bcc *+2 + sta ($12),y + sty $12,x + sta $12,x + stx $12,y + tya + sta $3456,y + txs + shy $3456,x + sta $3456,x + shx $3456,y + ldy #$12 + lda ($12,x) + ldx #$12 + lax ($12,x) + ldy $12 + lda $12 + ldx $12 + lax $12 + tay + lda #$12 + tax + lax #$12 + ldy $3456 + lda $3456 + ldx $3456 + lax $3456 + bcs *+2 + lda ($12),y + lax ($12),y + ldy $12,x + lda $12,x + ldx $12,y + lax $12,y + clv + lda $3456,y + tsx + las $3456,y + ldy $3456,x + lda $3456,x + ldx $3456,y + lax $3456,y + cpy #$12 + cmp ($12,x) + cpy $12 + cmp $12 + dec $12 + iny + cmp #$12 + dex + axs #$12 + cpy $3456 + cmp $3456 + dec $3456 + bne *+2 + cmp ($12),y + cmp $12,x + dec $12,x + cld + cmp $3456,y + cmp $3456,x + dec $3456,x + cpx #$12 + sbc ($12,x) + cpx $12 + sbc $12 + inc $12 + inx + sbc #$12 + nop + cpx $3456 + sbc $3456 + inc $3456 + beq *+2 + sbc ($12),y + sbc $12,x + inc $12,x + sed + sbc $3456,y + sbc $3456,x + inc $3456,x diff --git a/test/dasm/6502X-disass.s b/test/dasm/6502X-disass.s new file mode 100644 index 000000000..f102144c4 --- /dev/null +++ b/test/dasm/6502X-disass.s @@ -0,0 +1,30 @@ + + .setcpu "6502X" + + .repeat 256, cnt + + ; generate a pattern with all opcodes. however, for the full cycle to work, + ; we must take care of the "duplicate" opcodes, ie use only the favourite one. + .if ((cnt & $0f) = $02) + .byte $02 ; all JAM + .elseif ((cnt & $1f) = $1a) + .byte $ea ; all NOP + .elseif (cnt = $2b) + .byte $0b ; both ANC #imm + .elseif (cnt = $89) + .byte $80 ; both NOP #imm + .elseif (cnt = $eb) + .byte $e9 ; both SBC #imm + .elseif (cnt = $34) || (cnt = $54) || (cnt = $74) || (cnt = $d4) || (cnt = $f4) + .byte $14 ; all NOP zp, x + .elseif (cnt = $3c) || (cnt = $5c) || (cnt = $7c) || (cnt = $dc) || (cnt = $fc) + .byte $1c ; all NOP abs, x + .elseif (cnt = $44) || (cnt = $64) + .byte $04 ; all NOP zp + .else + .byte cnt + .endif + + .byte $02, $ea, $00 + + .endrepeat diff --git a/test/dasm/65C02-disass.s b/test/dasm/65C02-disass.s new file mode 100644 index 000000000..0613921d5 --- /dev/null +++ b/test/dasm/65C02-disass.s @@ -0,0 +1,214 @@ +.setcpu "65C02" + + brk + ora ($12,x) + tsb $12 + ora $12 + asl $12 + rmb0 $12 + php + ora #$12 + asl a + tsb $3456 + ora $3456 + asl $3456 + bbr0 $12,*+2 + bpl *+2 + ora ($12),y + ora ($12) + trb $12 + ora $12,x + asl $12,x + rmb1 $12 + clc + ora $3456,y + inc a + trb $3456 + ora $3456,x + asl $3456,x + bbr1 $12,*+2 + jsr $3456 + and ($12,x) + bit $12 + and $12 + rol $12 + rmb2 $12 + plp + and #$12 + rol a + bit $3456 + and $3456 + rol $3456 + bbr2 $12,*+2 + bmi *+2 + and ($12),y + and ($12) + bit $12,x + and $12,x + rol $12,x + rmb3 $12 + sec + and $3456,y + dec a + bit $3456,x + and $3456,x + rol $3456,x + bbr3 $12,*+2 + rti + eor ($12,x) + eor $12 + lsr $12 + rmb4 $12 + pha + eor #$12 + lsr a + jmp $3456 + eor $3456 + lsr $3456 + bbr4 $12,*+2 + bvc *+2 + eor ($12),y + eor ($12) + eor $12,x + lsr $12,x + rmb5 $12 + cli + eor $3456,y + phy + eor $3456,x + lsr $3456,x + bbr5 $12,*+2 + rts + adc ($12,x) + stz $12 + adc $12 + ror $12 + rmb6 $12 + pla + adc #$12 + ror a + jmp ($3456) + adc $3456 + ror $3456 + bbr6 $12,*+2 + bvs *+2 + adc ($12),y + adc ($12) + stz $12,x + adc $12,x + ror $12,x + rmb7 $12 + sei + adc $3456,y + ply + jmp ($3456,x) + adc $3456,x + ror $3456,x + bbr7 $12,*+2 + bra *+2 + sta ($12,x) + sty $12 + sta $12 + stx $12 + smb0 $12 + dey + bit #$12 + txa + sty $3456 + sta $3456 + stx $3456 + bbs0 $12,*+2 + bcc *+2 + sta ($12),y + sta ($12) + sty $12,x + sta $12,x + stx $12,y + smb1 $12 + tya + sta $3456,y + txs + stz $3456 + sta $3456,x + stz $3456,x + bbs1 $12,*+2 + ldy #$12 + lda ($12,x) + ldx #$12 + ldy $12 + lda $12 + ldx $12 + smb2 $12 + tay + lda #$12 + tax + ldy $3456 + lda $3456 + ldx $3456 + bbs2 $12,*+2 + bcs *+2 + lda ($12),y + lda ($12) + ldy $12,x + lda $12,x + ldx $12,y + smb3 $12 + clv + lda $3456,y + tsx + ldy $3456,x + lda $3456,x + ldx $3456,y + bbs3 $12,*+2 + cpy #$12 + cmp ($12,x) + cpy $12 + cmp $12 + dec $12 + smb4 $12 + iny + cmp #$12 + dex + cpy $3456 + cmp $3456 + dec $3456 + bbs4 $12,*+2 + bne *+2 + cmp ($12),y + cmp ($12) + cmp $12,x + dec $12,x + smb5 $12 + cld + cmp $3456,y + phx + cmp $3456,x + dec $3456,x + bbs5 $12,*+2 + cpx #$12 + sbc ($12,x) + cpx $12 + sbc $12 + inc $12 + smb6 $12 + inx + sbc #$12 + nop + cpx $3456 + sbc $3456 + inc $3456 + bbs6 $12,*+2 + beq *+2 + sbc ($12),y + sbc ($12) + sbc $12,x + inc $12,x + smb7 $12 + sed + sbc $3456,y + plx + sbc $3456,x + inc $3456,x +L0: + bbs7 $12,L0 + nop diff --git a/test/dasm/65SC02-disass.s b/test/dasm/65SC02-disass.s new file mode 100644 index 000000000..46e96aaf9 --- /dev/null +++ b/test/dasm/65SC02-disass.s @@ -0,0 +1,181 @@ +.setcpu "65SC02" + + brk + ora ($12,x) + tsb $12 + ora $12 + asl $12 + php + ora #$12 + asl a + tsb $3456 + ora $3456 + asl $3456 + bpl *+2 + ora ($12),y + ora ($12) + trb $12 + ora $12,x + asl $12,x + clc + ora $3456,y + inc a + trb $3456 + ora $3456,x + asl $3456,x + jsr $3456 + and ($12,x) + bit $12 + and $12 + rol $12 + plp + and #$12 + rol a + bit $3456 + and $3456 + rol $3456 + bmi *+2 + and ($12),y + and ($12) + bit $12,x + and $12,x + rol $12,x + sec + and $3456,y + dec a + bit $3456,x + and $3456,x + rol $3456,x + rti + eor ($12,x) + eor $12 + lsr $12 + pha + eor #$12 + lsr a + jmp $3456 + eor $3456 + lsr $3456 + bvc *+2 + eor ($12),y + eor ($12) + eor $12,x + lsr $12,x + cli + eor $3456,y + phy + eor $3456,x + lsr $3456,x + rts + adc ($12,x) + stz $12 + adc $12 + ror $12 + pla + adc #$12 + ror a + jmp ($3456) + adc $3456 + ror $3456 + bvs *+2 + adc ($12),y + adc ($12) + stz $12,x + adc $12,x + ror $12,x + sei + adc $3456,y + ply + jmp ($3456,x) + adc $3456,x + ror $3456,x + bra *+2 + sta ($12,x) + sty $12 + sta $12 + stx $12 + dey + bit #$12 + txa + sty $3456 + sta $3456 + stx $3456 + bcc *+2 + sta ($12),y + sta ($12) + sty $12,x + sta $12,x + stx $12,y + tya + sta $3456,y + txs + stz $3456 + sta $3456,x + stz $3456,x + ldy #$12 + lda ($12,x) + ldx #$12 + ldy $12 + lda $12 + ldx $12 + tay + lda #$12 + tax + ldy $3456 + lda $3456 + ldx $3456 + bcs *+2 + lda ($12),y + lda ($12) + ldy $12,x + lda $12,x + ldx $12,y + clv + lda $3456,y + tsx + ldy $3456,x + lda $3456,x + ldx $3456,y + cpy #$12 + cmp ($12,x) + cpy $12 + cmp $12 + dec $12 + iny + cmp #$12 + dex + cpy $3456 + cmp $3456 + dec $3456 + bne *+2 + cmp ($12),y + cmp ($12) + cmp $12,x + dec $12,x + cld + cmp $3456,y + phx + cmp $3456,x + dec $3456,x + cpx #$12 + sbc ($12,x) + cpx $12 + sbc $12 + inc $12 + inx + sbc #$12 + nop + cpx $3456 + sbc $3456 + inc $3456 + beq *+2 + sbc ($12),y + sbc ($12) + sbc $12,x + inc $12,x + sed + sbc $3456,y + plx + sbc $3456,x + inc $3456,x + diff --git a/test/dasm/huc6280-disass.s b/test/dasm/huc6280-disass.s new file mode 100644 index 000000000..4ae7b067d --- /dev/null +++ b/test/dasm/huc6280-disass.s @@ -0,0 +1,250 @@ +.setcpu "huc6280" + + brk + ora ($12,x) + sxy + st0 #$12 + tsb $12 + ora $12 + asl $12 + rmb0 $12 + php + ora #$12 + asl a + tsb $3456 + ora $3456 + asl $3456 + bbr0 $12,L0 +L0: + bpl *+2 + ora ($12),y + ora ($12) + st1 #$12 + trb $12 + ora $12,x + asl $12,x + rmb1 $12 + clc + ora $3456,y + inc a + trb $3456 + ora $3456,x + asl $3456,x + bbr1 $12,L1 +L1: + jsr $3456 + and ($12,x) + sax + st2 #$12 + bit $12 + and $12 + rol $12 + rmb2 $12 + plp + and #$12 + rol a + bit $3456 + and $3456 + rol $3456 + bbr2 $12,L2 +L2: + bmi *+2 + and ($12),y + and ($12) + bit $12,x + and $12,x + rol $12,x + rmb3 $12 + sec + and $3456,y + dec a + bit $3456,x + and $3456,x + rol $3456,x + bbr3 $12,L3 +L3: + rti + eor ($12,x) + say + tma #$02 + bsr *+2 + eor $12 + lsr $12 + rmb4 $12 + pha + eor #$12 + lsr a + jmp $3456 + eor $3456 + lsr $3456 + bbr4 $12,L4 +L4: + bvc *+2 + eor ($12),y + eor ($12) + tam #$12 + csl + eor $12,x + lsr $12,x + rmb5 $12 + cli + eor $3456,y + phy + eor $3456,x + lsr $3456,x + bbr5 $12,L5 +L5: + rts + adc ($12,x) + cla + stz $12 + adc $12 + ror $12 + rmb6 $12 + pla + adc #$12 + ror a + jmp ($3456) + adc $3456 + ror $3456 + bbr6 $12,L6 +L6: + bvs *+2 + adc ($12),y + adc ($12) + tii $3333,$7373,$1111 + stz $12,x + adc $12,x + ror $12,x + rmb7 $12 + sei + adc $3456,y + ply + jmp ($3456,x) + adc $3456,x + ror $3456,x + bbr7 $12,L7 +L7: + bra *+2 + sta ($12,x) + clx + tst #$12,$EA + sty $12 + sta $12 + stx $12 + smb0 $12 + dey + bit #$12 + txa + sty $3456 + sta $3456 + stx $3456 + bbs0 $12,LS0 +LS0: + bcc *+2 + sta ($12),y + sta ($12) + tst #$12,$EAEA + sty $12,x + sta $12,x + stx $12,y + smb1 $12 + tya + sta $3456,y + txs + stz $3456 + sta $3456,x + stz $3456,x + bbs1 $12,LS1 +LS1: + ldy #$12 + lda ($12,x) + ldx #$12 + tst #$12,$EA,x + ldy $12 + lda $12 + ldx $12 + smb2 $12 + tay + lda #$12 + tax + ldy $3456 + lda $3456 + ldx $3456 + bbs2 $12,LS2 +LS2: + bcs *+2 + lda ($12),y + lda ($12) + tst #$12,$EAEA,x + ldy $12,x + lda $12,x + ldx $12,y + smb3 $12 + clv + lda $3456,y + tsx + ldy $3456,x + lda $3456,x + ldx $3456,y + bbs3 $12,LS3 +LS3: + cpy #$12 + cmp ($12,x) + cly + tdd $3333,$C3C3,$1111 + cpy $12 + cmp $12 + dec $12 + smb4 $12 + iny + cmp #$12 + dex + cpy $3456 + cmp $3456 + dec $3456 + bbs4 $12,LS4 +LS4: + bne *+2 + cmp ($12),y + cmp ($12) + tin $3333,$D3D3,$1111 + cmp $12,x + dec $12,x + smb5 $12 + cld + cmp $3456,y + phx + cmp $3456,x + dec $3456,x + bbs5 $12,LS5 +LS5: + cpx #$12 + sbc ($12,x) + tia $3333,$E3E3,$1111 + cpx $12 + sbc $12 + inc $12 + smb6 $12 + inx + sbc #$12 + nop + cpx $3456 + sbc $3456 + inc $3456 + bbs6 $12,LS6 +LS6: + beq *+2 + sbc ($12),y + sbc ($12) + tai $3333,$F3F3,$1111 + sbc $12,x + inc $12,x + smb7 $12 + sed + sbc $3456,y + plx + sbc $3456,x + inc $3456,x +LS7: + bbs7 $12,LS7 diff --git a/test/dasm/m740-disass.s b/test/dasm/m740-disass.s new file mode 100644 index 000000000..ea0f19f8d --- /dev/null +++ b/test/dasm/m740-disass.s @@ -0,0 +1,8 @@ + + .setcpu "M740" + + .repeat 256, cnt + + .byte 0 + cnt, $12, $02, $ea + + .endrepeat diff --git a/test/dasm/readme.txt b/test/dasm/readme.txt new file mode 100644 index 000000000..9e001ec8c --- /dev/null +++ b/test/dasm/readme.txt @@ -0,0 +1,9 @@ + +Per CPU, a test binary is produced (using the assembler), which should contain +all possible instructions. That file is then disassembled, and assembled again, +and finally the resulting binary compared with the binary produced in the first +step. + +Given that we assume the assembler works (this is tested in other/previous +tests), this proves that the disassembler works, and can produce output that the +assembler will understand - and produce an identical binary from. From 7854a534349ba5607f868eb4ffa4bf58c9b5830b Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Wed, 18 Jun 2025 11:53:44 +0200 Subject: [PATCH 570/707] When studying expressions and recalculating the address size for a symbol expression, use the symbol address size only if it is smaller than the one that was calculated. --- src/ca65/studyexpr.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ca65/studyexpr.c b/src/ca65/studyexpr.c index 40e9b7aab..f4376e221 100644 --- a/src/ca65/studyexpr.c +++ b/src/ca65/studyexpr.c @@ -610,12 +610,13 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D) DumpExpr (Expr, SymResolve); } - /* If the symbol has an explicit address size, use it. This may - ** lead to range errors later (maybe even in the linker stage), if - ** the user lied about the address size, but for now we trust him. + /* If the symbol has an explicit address size that is smaller than + ** the one found, use it. This may lead to range errors later + ** (maybe even in the linker stage) if the user lied about the + ** address size, but for now we trust him. */ AddrSize = GetSymAddrSize (Sym); - if (AddrSize != ADDR_SIZE_DEFAULT) { + if (AddrSize != ADDR_SIZE_DEFAULT && AddrSize < D->AddrSize) { D->AddrSize = AddrSize; } } From b9a703749cb77c0d0be0d7222ffec68a02f88a60 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 22 Jun 2025 11:50:47 +0200 Subject: [PATCH 571/707] Replace all tables by hash tables. This allows to remove the ugly special casing of "long addresses" and prepares the code base for use with the full address range of the 65816. Use fixed size data types for addresses and target data words of known size. Many other minor improvements. --- src/da65/attrtab.c | 175 ++++++++++++++++---------- src/da65/attrtab.h | 24 ++-- src/da65/code.c | 41 +++--- src/da65/code.h | 24 ++-- src/da65/comments.c | 136 +++++++++++++------- src/da65/comments.h | 7 +- src/da65/data.c | 46 +++---- src/da65/data.h | 14 +-- src/da65/global.c | 3 +- src/da65/global.h | 7 +- src/da65/handler.c | 120 +++++++++--------- src/da65/handler.h | 4 +- src/da65/infofile.c | 50 ++++---- src/da65/labels.c | 299 ++++++++++++++++++++++++++------------------ src/da65/labels.h | 23 ++-- src/da65/main.c | 11 +- src/da65/output.c | 41 +++--- src/da65/output.h | 10 +- src/da65/scanner.c | 4 +- src/da65/scanner.h | 2 +- src/da65/segment.c | 8 +- src/da65/segment.h | 6 +- 22 files changed, 612 insertions(+), 443 deletions(-) diff --git a/src/da65/attrtab.c b/src/da65/attrtab.c index 002965dff..1ba694038 100644 --- a/src/da65/attrtab.c +++ b/src/da65/attrtab.c @@ -33,6 +33,11 @@ +#include <inttypes.h> + +/* common */ +#include "xmalloc.h" + /* da65 */ #include "cpu.h" #include "error.h" @@ -46,14 +51,78 @@ -/* Attribute table */ -static unsigned short AttrTab[0x10000]; +/* Attribute structure how it is found in the attribute table */ +typedef struct Attribute Attribute; +struct Attribute { + struct Attribute* Next; /* Next entry in linked list */ + uint32_t Addr; /* The full address */ + attr_t Attr; /* Actual attribute */ +}; -/* 65816 attribute table */ -#define MAX_LONG_ATTRS 256 -static unsigned short LongAttrVal[MAX_LONG_ATTRS]; -static unsigned LongAttrAddr[MAX_LONG_ATTRS]; -static unsigned LongAttrsUsed; +/* Attributes use a hash table and a linear list for collision resolution. The +** hash function is easy and effective. It evaluates just the lower bits of +** the address. +*/ +#define ATTR_HASH_SIZE 8192u /* Must be power of two */ +static Attribute* AttributeTab[ATTR_HASH_SIZE]; + + + +/*****************************************************************************/ +/* struct Attribute */ +/*****************************************************************************/ + + + +static Attribute* NewAttribute (uint32_t Addr, attr_t Attr) +/* Create a new attribute structure and return it */ +{ + /* Create a new attribute */ + Attribute* A = xmalloc (sizeof (Attribute)); + + /* Fill in the data */ + A->Next = 0; + A->Addr = Addr; + A->Attr = Attr; + + /* Return the attribute just created */ + return A; +} + + + +static uint32_t GetAttributeHash (uint32_t Addr) +/* Get the hash for an attribute at the given address */ +{ + return (Addr & (ATTR_HASH_SIZE - 1)); +} + + + +static Attribute* FindAttribute (uint32_t Addr) +/* Search for an attribute for the given address and return it. Returns NULL +** if no attribute exists for the address. +*/ +{ + Attribute* A = AttributeTab[GetAttributeHash (Addr)]; + while (A) { + if (A->Addr == Addr) { + break; + } + A = A->Next; + } + return A; +} + + + +static void InsertAttribute (Attribute* A) +/* Insert an attribute into the hash table */ +{ + uint32_t Hash = GetAttributeHash (A->Addr); + A->Next = AttributeTab[Hash]; + AttributeTab[Hash] = A; +} @@ -63,51 +132,43 @@ static unsigned LongAttrsUsed; -void AddrCheck (unsigned Addr) +void AddrCheck (uint32_t Addr) /* Check if the given address has a valid range */ { if (Addr >= 0x10000 && CPU != CPU_65816) { - Error ("Address out of range: %08X", Addr); + Error ("Address out of range: $%04" PRIX32, Addr); } } -unsigned char IsLongAddr (unsigned Addr) -/* Is it 24-bit? */ -{ - return Addr >= 0x10000 && CPU == CPU_65816; -} - - -attr_t GetAttr (unsigned Addr) +attr_t GetAttr (uint32_t Addr) /* Return the attribute for the given address */ { + /* As a small optimization we cache the last used attribute so when the + ** function is called several times with the same address we do already + ** know it. + */ + static const Attribute* A = 0; + if (A != 0 && A->Addr == Addr) { + return A->Attr; + } + /* Check the given address */ AddrCheck (Addr); - if (IsLongAddr (Addr)) { - unsigned i; - for (i = 0; i < LongAttrsUsed; i++) { - if (LongAttrAddr[i] == Addr) { - return LongAttrVal[i]; - } - } - - return 0; - } - /* Return the attribute */ - return AttrTab[Addr]; + A = FindAttribute (Addr); + return A? A->Attr : atDefault; } -int SegmentDefined (unsigned Start, unsigned End) +int SegmentDefined (uint32_t Start, uint32_t End) /* Return true if the atSegment bit is set somewhere in the given range */ { while (Start <= End) { - if (AttrTab[Start++] & atSegment) { + if (GetAttr (Start++) & atSegment) { return 1; } } @@ -116,7 +177,7 @@ int SegmentDefined (unsigned Start, unsigned End) -int IsSegmentEnd (unsigned Addr) +int IsSegmentEnd (uint32_t Addr) /* Return true if a segment ends at the given address */ { return (GetAttr (Addr) & atSegmentEnd) != 0x0000; @@ -124,7 +185,7 @@ int IsSegmentEnd (unsigned Addr) -int IsSegmentStart (unsigned Addr) +int IsSegmentStart (uint32_t Addr) /* Return true if a segment starts at the given address */ { return (GetAttr (Addr) & atSegmentStart) != 0x0000; @@ -155,7 +216,7 @@ unsigned GetGranularity (attr_t Style) -void MarkRange (unsigned Start, unsigned End, attr_t Attr) +void MarkRange (uint32_t Start, uint32_t End, attr_t Attr) /* Mark a range with the given attribute */ { /* Do it easy here... */ @@ -166,53 +227,33 @@ void MarkRange (unsigned Start, unsigned End, attr_t Attr) -void MarkAddr (unsigned Addr, attr_t Attr) +void MarkAddr (uint32_t Addr, attr_t Attr) /* Mark an address with an attribute */ { /* Check the given address */ AddrCheck (Addr); - if (IsLongAddr (Addr)) { - unsigned i; - for (i = 0; i < LongAttrsUsed; i++) { - if (LongAttrAddr[i] == Addr) { - - /* We must not have more than one style bit */ - if (Attr & atStyleMask) { - if (LongAttrVal[i] & atStyleMask) { - Error ("Duplicate style for long address %06X", Addr); - } - } - LongAttrVal[i] |= Attr; - - return; - } - } - - if (LongAttrsUsed >= MAX_LONG_ATTRS) { - Error ("Too many long addresses"); - } - LongAttrVal[LongAttrsUsed] |= Attr; - LongAttrAddr[LongAttrsUsed] = Addr; - LongAttrsUsed++; - - return; - } + /* Get an existing attribute entry */ + Attribute* A = FindAttribute (Addr); /* We must not have more than one style bit */ - if (Attr & atStyleMask) { - if (AttrTab[Addr] & atStyleMask) { - Error ("Duplicate style for address %04X", Addr); + if (A != 0 && (Attr & atStyleMask) != 0) { + if ((A->Attr & atStyleMask) != 0) { + Error ("Duplicate style for address %04" PRIX32, Addr); } } /* Set the style */ - AttrTab[Addr] |= Attr; + if (A) { + A->Attr |= Attr; + } else { + InsertAttribute (NewAttribute (Addr, Attr)); + } } -attr_t GetStyleAttr (unsigned Addr) +attr_t GetStyleAttr (uint32_t Addr) /* Return the style attribute for the given address */ { /* Check the given address */ @@ -224,7 +265,7 @@ attr_t GetStyleAttr (unsigned Addr) -attr_t GetLabelAttr (unsigned Addr) +attr_t GetLabelAttr (uint32_t Addr) /* Return the label attribute for the given address */ { /* Check the given address */ diff --git a/src/da65/attrtab.h b/src/da65/attrtab.h index 4a0ea8225..ec44fd3b3 100644 --- a/src/da65/attrtab.h +++ b/src/da65/attrtab.h @@ -38,6 +38,10 @@ +#include <stdint.h> + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -95,37 +99,37 @@ typedef enum attr_t { -void AddrCheck (unsigned Addr); +void AddrCheck (uint32_t Addr); /* Check if the given address has a valid range */ -unsigned char IsLongAddr (unsigned Addr); +unsigned char IsLongAddr (uint32_t Addr); /* Check if the given address is 24-bit */ -attr_t GetAttr (unsigned Addr); +attr_t GetAttr (uint32_t Addr); /* Return the attribute for the given address */ -int SegmentDefined (unsigned Start, unsigned End); +int SegmentDefined (uint32_t Start, unsigned End); /* Return true if the atSegment bit is set somewhere in the given range */ -int IsSegmentEnd (unsigned Addr); +int IsSegmentEnd (uint32_t Addr); /* Return true if a segment ends at the given address */ -int IsSegmentStart (unsigned Addr); +int IsSegmentStart (uint32_t Addr); /* Return true if a segment starts at the given address */ unsigned GetGranularity (attr_t Style); /* Get the granularity for the given style */ -void MarkRange (unsigned Start, unsigned End, attr_t Attr); +void MarkRange (uint32_t Start, uint32_t End, attr_t Attr); /* Mark a range with the given attribute */ -void MarkAddr (unsigned Addr, attr_t Attr); +void MarkAddr (uint32_t Addr, attr_t Attr); /* Mark an address with an attribute */ -attr_t GetStyleAttr (unsigned Addr); +attr_t GetStyleAttr (uint32_t Addr); /* Return the style attribute for the given address */ -attr_t GetLabelAttr (unsigned Addr); +attr_t GetLabelAttr (uint32_t Addr); /* Return the label attribute for the given address */ diff --git a/src/da65/code.c b/src/da65/code.c index a162e6482..6045e83c5 100644 --- a/src/da65/code.c +++ b/src/da65/code.c @@ -53,10 +53,10 @@ -unsigned char CodeBuf [0x10000]; /* Code buffer */ -unsigned long CodeStart; /* Start address */ -unsigned long CodeEnd; /* End address */ -unsigned long PC; /* Current PC */ +uint8_t CodeBuf[0x10000]; /* Code buffer */ +uint32_t CodeStart; /* Start address */ +uint32_t CodeEnd; /* End address */ +uint32_t PC; /* Current PC */ @@ -117,12 +117,13 @@ void LoadCode (void) ** 0x10000 - Size. This is a reasonable default assuming that the file ** is a ROM that contains the hardware vectors at $FFFA. */ - if (StartAddr < 0) { + if (!HaveStartAddr) { if (Size > 0x10000) { StartAddr = 0; } else { StartAddr = 0x10000 - Size; } + HaveStartAddr = 1; } /* Calculate the maximum code size */ @@ -155,7 +156,7 @@ void LoadCode (void) -unsigned char GetCodeByte (unsigned Addr) +uint8_t GetCodeByte (uint32_t Addr) /* Get a byte from the given address */ { PRECONDITION (Addr <= CodeEnd); @@ -164,48 +165,48 @@ unsigned char GetCodeByte (unsigned Addr) -unsigned GetCodeDByte (unsigned Addr) +uint16_t GetCodeDByte (uint32_t Addr) /* Get a dbyte from the given address */ { - unsigned Lo = GetCodeByte (Addr); - unsigned Hi = GetCodeByte (Addr+1); + uint16_t Lo = GetCodeByte (Addr); + uint16_t Hi = GetCodeByte (Addr+1); return (Lo <<8) | Hi; } -unsigned GetCodeWord (unsigned Addr) +uint16_t GetCodeWord (uint32_t Addr) /* Get a word from the given address */ { - unsigned Lo = GetCodeByte (Addr); - unsigned Hi = GetCodeByte (Addr+1); + uint16_t Lo = GetCodeByte (Addr); + uint16_t Hi = GetCodeByte (Addr+1); return Lo | (Hi << 8); } -unsigned long GetCodeDWord (unsigned Addr) +uint32_t GetCodeDWord (uint32_t Addr) /* Get a dword from the given address */ { - unsigned long Lo = GetCodeWord (Addr); - unsigned long Hi = GetCodeWord (Addr+2); + uint32_t Lo = GetCodeWord (Addr); + uint32_t Hi = GetCodeWord (Addr+2); return Lo | (Hi << 16); } -unsigned GetCodeLongAddr (unsigned Addr) +uint32_t GetCodeLongAddr (uint32_t Addr) /* Get a word from the given address */ { - unsigned Lo = GetCodeByte (Addr); - unsigned Mid = GetCodeByte (Addr+1); - unsigned Hi = GetCodeByte (Addr+2); + uint32_t Lo = GetCodeByte (Addr); + uint32_t Mid = GetCodeByte (Addr+1); + uint32_t Hi = GetCodeByte (Addr+2); return Lo | (Mid << 8) | (Hi << 16); } -unsigned GetRemainingBytes (void) +uint32_t GetRemainingBytes (void) /* Return the number of remaining code bytes */ { if (CodeEnd >= PC) { diff --git a/src/da65/code.h b/src/da65/code.h index aa3c6a290..1a4cce2c8 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -38,16 +38,20 @@ +#include <stdint.h> + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ -extern unsigned char CodeBuf [0x10000]; /* Code buffer */ -extern unsigned long CodeStart; /* Start address */ -extern unsigned long CodeEnd; /* End address */ -extern unsigned long PC; /* Current PC */ +extern uint8_t CodeBuf[0x10000]; /* Code buffer */ +extern uint32_t CodeStart; /* Start address */ +extern uint32_t CodeEnd; /* End address */ +extern uint32_t PC; /* Current PC */ @@ -60,22 +64,22 @@ extern unsigned long PC; /* Current PC */ void LoadCode (void); /* Load the code from the given file */ -unsigned char GetCodeByte (unsigned Addr); +uint8_t GetCodeByte (uint32_t Addr); /* Get a byte from the given address */ -unsigned GetCodeDByte (unsigned Addr); +uint16_t GetCodeDByte (uint32_t Addr); /* Get a dbyte from the given address */ -unsigned GetCodeWord (unsigned Addr); +uint16_t GetCodeWord (uint32_t Addr); /* Get a word from the given address */ -unsigned long GetCodeDWord (unsigned Addr); +uint32_t GetCodeDWord (uint32_t Addr); /* Get a dword from the given address */ -unsigned GetCodeLongAddr (unsigned Addr); +uint32_t GetCodeLongAddr (uint32_t Addr); /* Get a 24-bit address from the given address */ -unsigned GetRemainingBytes (void); +uint32_t GetRemainingBytes (void); /* Return the number of remaining code bytes */ int CodeLeft (void); diff --git a/src/da65/comments.c b/src/da65/comments.c index f136ae3d2..f1295d486 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -33,6 +33,9 @@ +#include <inttypes.h> +#include <string.h> + /* common */ #include "xmalloc.h" @@ -49,13 +52,82 @@ -/* Comment table */ -static const char* CommentTab[0x10000]; +/* Comment structure how it is found in the comment table */ +typedef struct Comment Comment; +struct Comment { + struct Comment* Next; /* Next entry in linked list */ + uint32_t Addr; /* The full address */ + char Text[1]; /* Text, dynamically allocated */ +}; -#define MAX_LONG_COMMENTS 256 -static const char* LongCommentVal[MAX_LONG_COMMENTS]; -static unsigned LongCommentAddr[MAX_LONG_COMMENTS]; -static unsigned LongCommentsUsed; +/* Comments use a hash table and a linear list for collision resolution. The +** hash function is easy and effective. It evaluates just the lower bits of +** the address. Since we don't expect many comments, we can keep the table +** small. +*/ +#define COMMENT_HASH_SIZE 256u /* Must be power of two */ +static Comment* CommentTab[COMMENT_HASH_SIZE]; + + + +/*****************************************************************************/ +/* struct Comment */ +/*****************************************************************************/ + + + +static Comment* NewComment (uint32_t Addr, const char* Text) +/* Create a new comment structure and return it */ +{ + /* Get the length of the text */ + unsigned Len = strlen (Text); + + /* Create a new comment */ + Comment* C = xmalloc (sizeof (Comment) + Len); + + /* Fill in the data */ + C->Next = 0; + C->Addr = Addr; + memcpy (C->Text, Text, Len + 1); + + /* Return the comment just created */ + return C; +} + + + +static uint32_t GetCommentHash (uint32_t Addr) +/* Get the hash for a comment at the given address */ +{ + return (Addr & (COMMENT_HASH_SIZE - 1)); +} + + + +static Comment* FindComment (uint32_t Addr) +/* Search for a comment for the given address and return it. Returns NULL if +** no comment exists for the address. +*/ +{ + Comment* C = CommentTab[GetCommentHash (Addr)]; + while (C) { + if (C->Addr == Addr) { + break; + } + C = C->Next; + } + return C; +} + + + +static void InsertComment (Comment* C) +/* Insert a comment into the hash table */ +{ + uint32_t Hash = GetCommentHash (C->Addr); + C->Next = CommentTab[Hash]; + CommentTab[Hash] = C; +} @@ -65,62 +137,30 @@ static unsigned LongCommentsUsed; -static unsigned FindLongIndex (unsigned Addr) -{ - unsigned i; - for (i = 0; i < LongCommentsUsed; i++) { - if (LongCommentAddr[i] == Addr) { - return i; - } - } - return -1; -} - - - -void SetComment (unsigned Addr, const char* Comment) +void SetComment (uint32_t Addr, const char* Text) /* Set a comment for the given address */ { /* Check the given address */ AddrCheck (Addr); - if (IsLongAddr (Addr)) { - if (FindLongIndex (Addr)) { - Warning ("Duplicate comment for address $%06X", Addr); - } else { - if (LongCommentsUsed >= MAX_LONG_COMMENTS) { - Error("Too many long-address comments"); - } - LongCommentVal[LongCommentsUsed] = xstrdup (Comment); - LongCommentAddr[LongCommentsUsed] = Addr; - LongCommentsUsed++; - } + /* If we do already have a comment, warn and ignore the new one */ + Comment* C = FindComment (Addr); + if (C) { + Warning ("Duplicate comment for address $%04" PRIX32, Addr); } else { - /* If we do already have a comment, warn and ignore the new one */ - if (CommentTab[Addr]) { - Warning ("Duplicate comment for address $%04X", Addr); - } else { - CommentTab[Addr] = xstrdup (Comment); - } + InsertComment (NewComment (Addr, Text)); } } -const char* GetComment (unsigned Addr) +const char* GetComment (uint32_t Addr) /* Return the comment for an address */ { /* Check the given address */ AddrCheck (Addr); - if (IsLongAddr (Addr)) { - const unsigned i = FindLongIndex (Addr); - if (i < LongCommentsUsed) { - return LongCommentVal[i]; - } - return NULL; - } - - /* Return the label if any */ - return CommentTab[Addr]; + /* Check for a comment and return it */ + const Comment* C = FindComment (Addr); + return C? C->Text : 0; } diff --git a/src/da65/comments.h b/src/da65/comments.h index 1d95111a9..dfa1654ab 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -38,6 +38,9 @@ +#include <stdint.h> + +/* da65 */ #include "attrtab.h" @@ -48,10 +51,10 @@ -void SetComment (unsigned Addr, const char* Comment); +void SetComment (uint32_t Addr, const char* Text); /* Set a comment for the given address */ -const char* GetComment (unsigned Addr); +const char* GetComment (uint32_t Addr); /* Return the comment for an address */ diff --git a/src/da65/data.c b/src/da65/data.c index f85cd327d..a7389ca5a 100644 --- a/src/da65/data.c +++ b/src/da65/data.c @@ -50,17 +50,17 @@ -static unsigned GetSpan (attr_t Style) +static uint32_t GetSpan (attr_t Style) /* Get the number of bytes for a given style */ { /* Get the number of bytes still available */ - unsigned RemainingBytes = GetRemainingBytes (); + uint32_t RemainingBytes = GetRemainingBytes (); /* Count how many bytes are available. This number is limited by the ** number of remaining bytes, a label, a segment change, or the end of ** the given Style attribute. */ - unsigned Count = 1; + uint32_t Count = 1; while (Count < RemainingBytes) { attr_t Attr; if (MustDefLabel(PC+Count)) { @@ -85,10 +85,10 @@ static unsigned GetSpan (attr_t Style) static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (unsigned)) /* Output a table of bytes */ { - unsigned BytesLeft; + uint32_t BytesLeft; /* Count how many bytes may be output. */ - unsigned Count = GetSpan (Style); + uint32_t Count = GetSpan (Style); /* If the count is less than the member size, print a row of Count data ** bytes. We assume here that there is no member with a size that is less @@ -108,7 +108,7 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u while (BytesLeft > 0) { /* Calculate the number of bytes for the next line */ - unsigned Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft; + uint32_t Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft; /* Output a line with these bytes */ TableFunc (Chunk); @@ -129,7 +129,7 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u -unsigned ByteTable (void) +uint32_t ByteTable (void) /* Output a table of bytes */ { /* Call the low level function */ @@ -138,7 +138,7 @@ unsigned ByteTable (void) -unsigned DByteTable (void) +uint32_t DByteTable (void) /* Output a table of dbytes */ { /* Call the low level function */ @@ -147,7 +147,7 @@ unsigned DByteTable (void) -unsigned WordTable (void) +uint32_t WordTable (void) /* Output a table of words */ { /* Call the low level function */ @@ -156,7 +156,7 @@ unsigned WordTable (void) -unsigned DWordTable (void) +uint32_t DWordTable (void) /* Output a table of double words */ { /* Call the low level function */ @@ -165,18 +165,18 @@ unsigned DWordTable (void) -unsigned AddrTable (void) +uint32_t AddrTable (void) /* Output a table of addresses */ { - unsigned long BytesLeft = GetRemainingBytes (); - unsigned long Start = PC; + uint32_t BytesLeft = GetRemainingBytes (); + uint32_t Start = PC; /* Loop while table bytes left and we don't need to create a label at the ** current position. */ while (BytesLeft && GetStyleAttr (PC) == atAddrTab) { - unsigned Addr; + uint32_t Addr; /* If just one byte is left, define it and bail out */ if (BytesLeft == 1 || GetStyleAttr (PC+1) != atAddrTab) { @@ -231,18 +231,18 @@ unsigned AddrTable (void) -unsigned RtsTable (void) +uint32_t RtsTable (void) /* Output a table of RTS addresses (address - 1) */ { - unsigned long BytesLeft = GetRemainingBytes (); - unsigned long Start = PC; + uint32_t BytesLeft = GetRemainingBytes (); + uint32_t Start = PC; /* Loop while table bytes left and we don't need to create a label at the ** current position. */ while (BytesLeft && GetStyleAttr (PC) == atRtsTab) { - unsigned Addr; + uint32_t Addr; /* If just one byte is left, define it and bail out */ if (BytesLeft == 1 || GetStyleAttr (PC+1) != atRtsTab) { @@ -297,14 +297,14 @@ unsigned RtsTable (void) -unsigned TextTable (void) +uint32_t TextTable (void) /* Output a table of text messages */ { /* Count how many bytes may be output. */ - unsigned ByteCount = GetSpan (atTextTab); + uint32_t ByteCount = GetSpan (atTextTab); /* Output as many data bytes lines as needed. */ - unsigned BytesLeft = ByteCount; + uint32_t BytesLeft = ByteCount; while (BytesLeft > 0) { unsigned I; @@ -312,7 +312,7 @@ unsigned TextTable (void) /* Count the number of characters that can be output as such */ unsigned Count = 0; while (Count < BytesLeft && Count < BytesPerLine*4-1) { - unsigned char C = GetCodeByte (PC + Count); + uint8_t C = GetCodeByte (PC + Count); if (C >= 0x20 && C <= 0x7E && C != '\"') { ++Count; } else { @@ -348,7 +348,7 @@ unsigned TextTable (void) /* Count the number of bytes that must be output as bytes */ Count = 0; while (Count < BytesLeft && Count < BytesPerLine) { - unsigned char C = GetCodeByte (PC + Count); + uint8_t C = GetCodeByte (PC + Count); if (C < 0x20 || C > 0x7E || C == '\"') { ++Count; } else { diff --git a/src/da65/data.h b/src/da65/data.h index 4cec14a03..d9885b780 100644 --- a/src/da65/data.h +++ b/src/da65/data.h @@ -44,25 +44,25 @@ -unsigned ByteTable (void); +uint32_t ByteTable (void); /* Output a table of bytes */ -unsigned DByteTable (void); +uint32_t DByteTable (void); /* Output a table of dbytes */ -unsigned WordTable (void); +uint32_t WordTable (void); /* Output a table of words */ -unsigned DWordTable (void); +uint32_t DWordTable (void); /* Output a table of double words */ -unsigned AddrTable (void); +uint32_t AddrTable (void); /* Output a table of addresses */ -unsigned RtsTable (void); +uint32_t RtsTable (void); /* Output a table of RTS addresses (address - 1) */ -unsigned TextTable (void); +uint32_t TextTable (void); /* Output a table of text messages */ diff --git a/src/da65/global.c b/src/da65/global.c index e258aecdd..7e5cabf54 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -58,7 +58,8 @@ unsigned char UseHexOffs = 0; /* Use hexadecimal label offsets */ unsigned char PassCount = 2; /* How many passed do we do? */ signed char NewlineAfterJMP = -1; /* Add a newline after a JMP insn? */ signed char NewlineAfterRTS = -1; /* Add a newline after a RTS insn? */ -long StartAddr = -1L; /* Start/load address of the program */ +unsigned char HaveStartAddr = 0; /* Flag for start address given */ +uint32_t StartAddr = 0; /* Start/load address of the program */ unsigned char SyncLines = 0; /* Accept line markers in the info file */ long InputOffs = -1L; /* Offset into input file */ long InputSize = -1L; /* Number of bytes to read from input */ diff --git a/src/da65/global.h b/src/da65/global.h index c85c7a79e..2e558d6a9 100644 --- a/src/da65/global.h +++ b/src/da65/global.h @@ -38,6 +38,10 @@ +#include <stdint.h> + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -59,7 +63,8 @@ extern unsigned char UseHexOffs; /* Use hexadecimal label offsets */ extern unsigned char PassCount; /* How many passed do we do? */ extern signed char NewlineAfterJMP;/* Add a newline after a JMP insn? */ extern signed char NewlineAfterRTS;/* Add a newline after a RTS insn? */ -extern long StartAddr; /* Start/load address of the program */ +extern unsigned char HaveStartAddr; /* Flag for start address given */ +extern uint32_t StartAddr; /* Start/load address of the program */ extern unsigned char SyncLines; /* Accept line markers in the info file */ extern long InputOffs; /* Offset into input file */ extern long InputSize; /* Number of bytes to read from input */ diff --git a/src/da65/handler.c b/src/da65/handler.c index 84229594f..836dc2884 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -33,6 +33,7 @@ +#include <inttypes.h> #include <stdarg.h> /* common */ @@ -95,7 +96,7 @@ static void OneLine (const OpcDesc* D, const char* Arg, ...) -static const char* GetAbsOverride (unsigned Flags, unsigned Addr) +static const char* GetAbsOverride (unsigned Flags, uint32_t Addr) /* If the instruction requires an abs override modifier, return the necessary ** string, otherwise return the empty string. */ @@ -111,7 +112,7 @@ static const char* GetAbsOverride (unsigned Flags, unsigned Addr) -static const char* GetAddrArg (unsigned Flags, unsigned Addr) +static const char* GetAddrArg (unsigned Flags, uint32_t Addr) /* Return an address argument - a label if we have one, or the address itself */ { const char* Label = 0; @@ -123,11 +124,11 @@ static const char* GetAddrArg (unsigned Flags, unsigned Addr) } else { static char Buf [32]; if (Addr < 0x100) { - xsprintf (Buf, sizeof (Buf), "$%02X", Addr); + xsprintf (Buf, sizeof (Buf), "$%02" PRIX32, Addr); } else if (Addr < 0x10000) { - xsprintf (Buf, sizeof (Buf), "$%04X", Addr); + xsprintf (Buf, sizeof (Buf), "$%04" PRIX32, Addr); } else { - xsprintf (Buf, sizeof (Buf), "$%06X", Addr); + xsprintf (Buf, sizeof (Buf), "$%06" PRIX32, Addr); } return Buf; } @@ -135,7 +136,7 @@ static const char* GetAddrArg (unsigned Flags, unsigned Addr) -static void GenerateLabel (unsigned Flags, unsigned Addr) +static void GenerateLabel (unsigned Flags, uint32_t Addr) /* Generate a label in pass one if requested */ { /* Generate labels in pass #1, and only if we don't have a label already */ @@ -305,7 +306,7 @@ void OH_Implicit_42_45GS02 (const OpcDesc* D) void OH_Immediate (const OpcDesc* D) { - OneLine (D, "#$%02X", GetCodeByte (PC+1)); + OneLine (D, "#$%02" PRIX8, GetCodeByte (PC+1)); } @@ -313,9 +314,9 @@ void OH_Immediate (const OpcDesc* D) void OH_Immediate65816M (const OpcDesc* D) { if (GetAttr (PC) & atMem16) { - OneLine (D, "#$%04X", GetCodeWord (PC+1)); + OneLine (D, "#$%04" PRIX16, GetCodeWord (PC+1)); } else { - OneLine (D, "#$%02X", GetCodeByte (PC+1)); + OneLine (D, "#$%02" PRIX8, GetCodeByte (PC+1)); } } @@ -324,9 +325,9 @@ void OH_Immediate65816M (const OpcDesc* D) void OH_Immediate65816X (const OpcDesc* D) { if (GetAttr (PC) & atIdx16) { - OneLine (D, "#$%04X", GetCodeWord (PC+1)); + OneLine (D, "#$%04" PRIX16, GetCodeWord (PC+1)); } else { - OneLine (D, "#$%02X", GetCodeByte (PC+1)); + OneLine (D, "#$%02" PRIX8, GetCodeByte (PC+1)); } } @@ -334,7 +335,7 @@ void OH_Immediate65816X (const OpcDesc* D) void OH_ImmediateWord (const OpcDesc* D) { - OneLine (D, "#$%04X", GetCodeWord (PC+1)); + OneLine (D, "#$%04" PRIX16, GetCodeWord (PC+1)); } @@ -342,7 +343,7 @@ void OH_ImmediateWord (const OpcDesc* D) void OH_Direct (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -370,7 +371,7 @@ void OH_Direct_Q (const OpcDesc* D) void OH_DirectX (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -398,7 +399,7 @@ void OH_DirectX_Q (const OpcDesc* D) void OH_DirectY (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -412,7 +413,7 @@ void OH_DirectY (const OpcDesc* D) void OH_Absolute (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+1); + uint32_t Addr = GetCodeWord (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -440,7 +441,7 @@ void OH_Absolute_Q (const OpcDesc* D) void OH_AbsoluteX (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+1); + uint32_t Addr = GetCodeWord (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -468,7 +469,7 @@ void OH_AbsoluteX_Q (const OpcDesc* D) void OH_AbsoluteY (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+1); + uint32_t Addr = GetCodeWord (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -482,7 +483,7 @@ void OH_AbsoluteY (const OpcDesc* D) void OH_AbsoluteLong (const OpcDesc* D attribute ((unused))) { /* Get the operand */ - unsigned Addr = GetCodeLongAddr (PC+1); + uint32_t Addr = GetCodeLongAddr (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -496,7 +497,7 @@ void OH_AbsoluteLong (const OpcDesc* D attribute ((unused))) void OH_AbsoluteLongX (const OpcDesc* D attribute ((unused))) { /* Get the operand */ - unsigned Addr = GetCodeLongAddr (PC+1); + uint32_t Addr = GetCodeLongAddr (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -513,7 +514,7 @@ void OH_Relative (const OpcDesc* D) signed char Offs = GetCodeByte (PC+1); /* Calculate the target address */ - unsigned Addr = (((int) PC+2) + Offs) & 0xFFFF; + uint32_t Addr = (((int) PC+2) + Offs) & 0xFFFF; /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -535,7 +536,7 @@ void OH_RelativeLong (const OpcDesc* D attribute ((unused))) signed short Offs = GetCodeWord (PC+1); /* Calculate the target address */ - unsigned Addr = (((int) PC+3) + Offs) & 0xFFFF; + uint32_t Addr = (((int) PC+3) + Offs) & 0xFFFF; /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -552,7 +553,7 @@ void OH_RelativeLong4510 (const OpcDesc* D attribute ((unused))) signed short Offs = GetCodeWord (PC+1); /* Calculate the target address */ - unsigned Addr = (((int) PC+2) + Offs) & 0xFFFF; + uint32_t Addr = (((int) PC+2) + Offs) & 0xFFFF; /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -566,7 +567,7 @@ void OH_RelativeLong4510 (const OpcDesc* D attribute ((unused))) void OH_DirectIndirect (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -580,7 +581,7 @@ void OH_DirectIndirect (const OpcDesc* D) void OH_DirectIndirectY (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -594,7 +595,7 @@ void OH_DirectIndirectY (const OpcDesc* D) void OH_DirectIndirectZ (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -622,7 +623,7 @@ void OH_DirectIndirectZ_Q (const OpcDesc* D) void OH_DirectXIndirect (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -636,7 +637,7 @@ void OH_DirectXIndirect (const OpcDesc* D) void OH_AbsoluteIndirect (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+1); + uint32_t Addr = GetCodeWord (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -652,11 +653,11 @@ void OH_BitBranch (const OpcDesc* D) char* BranchLabel; /* Get the operands */ - unsigned char TestAddr = GetCodeByte (PC+1); - signed char BranchOffs = GetCodeByte (PC+2); + uint32_t TestAddr = GetCodeByte (PC+1); + int8_t BranchOffs = GetCodeByte (PC+2); /* Calculate the target address for the branch */ - unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; + uint32_t BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; /* Generate labels in pass 1. The bit branch codes are special in that ** they don't really match the remainder of the 6502 instruction set (they @@ -686,11 +687,11 @@ void OH_BitBranch_m740 (const OpcDesc* D) */ { /* unsigned Bit = GetCodeByte (PC) >> 5; */ - unsigned Addr = GetCodeByte (PC+1); - signed char BranchOffs = GetCodeByte (PC+2); + uint32_t Addr = GetCodeByte (PC+1); + int8_t BranchOffs = (int8_t) GetCodeByte (PC+2); /* Calculate the target address for the branch */ - unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; + uint32_t BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -700,10 +701,12 @@ void OH_BitBranch_m740 (const OpcDesc* D) OneLine (D, "%s, %s", GetAddrArg (D->Flags, Addr), GetAddrArg (flLabel, BranchAddr)); } + + void OH_ImmediateDirect (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+2); + uint32_t Addr = GetCodeByte (PC+2); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -717,7 +720,7 @@ void OH_ImmediateDirect (const OpcDesc* D) void OH_ImmediateDirectX (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+2); + uint32_t Addr = GetCodeByte (PC+2); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -731,7 +734,7 @@ void OH_ImmediateDirectX (const OpcDesc* D) void OH_ImmediateAbsolute (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+2); + uint32_t Addr = GetCodeWord (PC+2); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -745,7 +748,7 @@ void OH_ImmediateAbsolute (const OpcDesc* D) void OH_ImmediateAbsoluteX (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+2); + uint32_t Addr = GetCodeWord (PC+2); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -790,7 +793,7 @@ void OH_StackRelativeIndirectY4510 (const OpcDesc* D attribute ((unused))) void OH_DirectIndirectLong (const OpcDesc* D attribute ((unused))) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -804,7 +807,7 @@ void OH_DirectIndirectLong (const OpcDesc* D attribute ((unused))) void OH_DirectIndirectLongY (const OpcDesc* D attribute ((unused))) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -820,9 +823,9 @@ void OH_BlockMove (const OpcDesc* D) char* DstLabel; /* Get source operand */ - unsigned Src = GetCodeWord (PC+1); + uint32_t Src = GetCodeWord (PC+1); /* Get destination operand */ - unsigned Dst = GetCodeWord (PC+3); + uint32_t Dst = GetCodeWord (PC+3); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Src); @@ -835,7 +838,7 @@ void OH_BlockMove (const OpcDesc* D) DstLabel = xstrdup (GetAddrArg (D->Flags, Dst)); /* Output the line */ - OneLine (D, "%s%s,%s%s,$%04X", + OneLine (D, "%s%s,%s%s,$%04" PRIX16, GetAbsOverride (D->Flags, Src), GetAddrArg (D->Flags, Src), GetAbsOverride (D->Flags, Dst), DstLabel, GetCodeWord (PC+5)); @@ -848,12 +851,12 @@ void OH_BlockMove (const OpcDesc* D) void OH_BlockMove65816 (const OpcDesc* D) { /* Get source operand */ - unsigned Src = GetCodeByte (PC+2); + uint8_t Src = GetCodeByte (PC+2); /* Get destination operand */ - unsigned Dst = GetCodeByte (PC+1); + uint8_t Dst = GetCodeByte (PC+1); /* Output the line */ - OneLine (D, "#$%02X, #$%02X", Src, Dst); + OneLine (D, "#$%02" PRIX8 ", #$%02" PRIX8, Src, Dst); } @@ -861,7 +864,7 @@ void OH_BlockMove65816 (const OpcDesc* D) void OH_AbsoluteXIndirect (const OpcDesc* D attribute ((unused))) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+1); + uint32_t Addr = GetCodeWord (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -875,7 +878,7 @@ void OH_AbsoluteXIndirect (const OpcDesc* D attribute ((unused))) void OH_DirectImmediate (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -891,7 +894,7 @@ void OH_ZeroPageBit (const OpcDesc* D) ** NOTE: currently <bit> is part of the instruction */ { - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -917,10 +920,10 @@ void OH_AccumulatorBitBranch (const OpcDesc* D) ** NOTE: currently <bit> is part of the instruction */ { - signed char BranchOffs = GetCodeByte (PC+1); + int8_t BranchOffs = GetCodeByte (PC+1); /* Calculate the target address for the branch */ - unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; + uint32_t BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; /* Generate labels in pass 1 */ GenerateLabel (flLabel, BranchAddr); @@ -945,7 +948,7 @@ void OH_SpecialPage (const OpcDesc* D) /* m740 "special page" address mode */ { /* Get the operand */ - unsigned Addr = 0xFF00 + GetCodeByte (PC+1); + uint32_t Addr = 0xFF00 + GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -1004,16 +1007,13 @@ void OH_JsrAbsolute (const OpcDesc* D) unsigned ParamSize = SubroutineParamSize[GetCodeWord (PC+1)]; OH_Absolute (D); if (ParamSize > 0) { - unsigned RemainingBytes; - unsigned BytesLeft; + uint32_t RemainingBytes; + uint32_t BytesLeft; PC += D->Size; RemainingBytes = GetRemainingBytes (); - if (RemainingBytes < ParamSize) { - ParamSize = RemainingBytes; - } - BytesLeft = ParamSize; + BytesLeft = (RemainingBytes < ParamSize)? RemainingBytes : ParamSize; while (BytesLeft > 0) { - unsigned Chunk = (BytesLeft > BytesPerLine) ? BytesPerLine : BytesLeft; + uint32_t Chunk = (BytesLeft > BytesPerLine) ? BytesPerLine : BytesLeft; DataByteLine (Chunk); BytesLeft -= Chunk; PC += Chunk; @@ -1024,7 +1024,7 @@ void OH_JsrAbsolute (const OpcDesc* D) -void SetSubroutineParamSize (unsigned Addr, unsigned Size) +void SetSubroutineParamSize (uint32_t Addr, unsigned Size) { SubroutineParamSize[Addr] = Size; } diff --git a/src/da65/handler.h b/src/da65/handler.h index fc82595c6..91c1562cd 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -38,6 +38,8 @@ +#include <stdint.h> + /* common */ #include "attrib.h" @@ -119,7 +121,7 @@ void OH_JmpAbsoluteIndirect (const OpcDesc* D); void OH_JmpAbsoluteXIndirect (const OpcDesc* D); void OH_JsrAbsolute (const OpcDesc*); -void SetSubroutineParamSize (unsigned Addr, unsigned Size); +void SetSubroutineParamSize (uint32_t Addr, unsigned Size); /* End of handler.h */ diff --git a/src/da65/infofile.c b/src/da65/infofile.c index fbf367cc9..67e7df1d9 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -219,7 +219,7 @@ static void GlobalSection (void) case INFOTOK_ARGUMENT_COLUMN: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (MIN_ACOL, MAX_ACOL); + InfoRangeCheck ("ARGUMENTCOLUMN", MIN_ACOL, MAX_ACOL); ACol = InfoIVal; InfoNextTok (); break; @@ -227,7 +227,7 @@ static void GlobalSection (void) case INFOTOK_COMMENT_COLUMN: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (MIN_CCOL, MAX_CCOL); + InfoRangeCheck ("COMMENTCOLUMN", MIN_CCOL, MAX_CCOL); CCol = InfoIVal; InfoNextTok (); break; @@ -235,7 +235,7 @@ static void GlobalSection (void) case INFOTOK_COMMENTS: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (MIN_COMMENTS, MAX_COMMENTS); + InfoRangeCheck ("COMMENTS", MIN_COMMENTS, MAX_COMMENTS); Comments = InfoIVal; InfoNextTok (); break; @@ -281,7 +281,7 @@ static void GlobalSection (void) case INFOTOK_INPUTSIZE: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (1, 0x10000); + InfoRangeCheck ("INPUTSIZE", 1, 0x10000); InputSize = InfoIVal; InfoNextTok (); break; @@ -289,7 +289,7 @@ static void GlobalSection (void) case INFOTOK_LABELBREAK: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (0, UCHAR_MAX); + InfoRangeCheck ("LABELBREAK", 0, UCHAR_MAX); LBreak = (unsigned char) InfoIVal; InfoNextTok (); break; @@ -297,7 +297,7 @@ static void GlobalSection (void) case INFOTOK_MNEMONIC_COLUMN: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (MIN_MCOL, MAX_MCOL); + InfoRangeCheck ("MNEMONICCOLUMN", MIN_MCOL, MAX_MCOL); MCol = InfoIVal; InfoNextTok (); break; @@ -336,7 +336,7 @@ static void GlobalSection (void) InfoNextTok (); InfoAssureInt (); if (InfoIVal != 0) { - InfoRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN); + InfoRangeCheck ("PAGELENGTH", MIN_PAGE_LEN, MAX_PAGE_LEN); } PageLength = InfoIVal; InfoNextTok (); @@ -345,15 +345,16 @@ static void GlobalSection (void) case INFOTOK_STARTADDR: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (0x0000, 0xFFFF); + InfoRangeCheck ("STARTADDR", 0x0000, 0xFFFF); StartAddr = InfoIVal; + HaveStartAddr = 1; InfoNextTok (); break; case INFOTOK_TEXT_COLUMN: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (MIN_TCOL, MAX_TCOL); + InfoRangeCheck ("TEXTCOLUMN", MIN_TCOL, MAX_TCOL); TCol = InfoIVal; InfoNextTok (); break; @@ -413,7 +414,7 @@ static void LabelSection (void) InfoError ("Value already given"); } InfoAssureInt (); - InfoRangeCheck (0, 0xFFFF); + InfoRangeCheck ("ADDR", 0, 0xFFFF); Value = InfoIVal; InfoNextTok (); break; @@ -447,7 +448,7 @@ static void LabelSection (void) InfoError ("Size already given"); } InfoAssureInt (); - InfoRangeCheck (1, 0x10000); + InfoRangeCheck ("SIZE", 1, 0x10000); Size = InfoIVal; InfoNextTok (); break; @@ -458,7 +459,7 @@ static void LabelSection (void) InfoError ("ParamSize already given"); } InfoAssureInt (); - InfoRangeCheck (1, 0x10000); + InfoRangeCheck ("PARAMSIZE", 1, 0x10000); ParamSize = InfoIVal; InfoNextTok (); break; @@ -554,13 +555,13 @@ static void RangeSection (void) tComment = 0x10, tAddrMode = 0x20, tUnit = 0x40, - tNeeded = (tStart | tEnd | tType) + tNeeded = (tStart | tEnd | tType) }; unsigned Attributes = tNone; /* Locals - initialize to avoid gcc warnings */ - unsigned Start = 0; - unsigned End = 0; + uint32_t Start = 0; + uint32_t End = 0; unsigned char Type = 0; unsigned AddrMode = 0; char* Name = 0; @@ -599,17 +600,18 @@ static void RangeSection (void) case INFOTOK_END: AddAttr ("END", &Attributes, tEnd); InfoNextTok (); - if (InfoTok == INFOTOK_OFFSET_INTCON) { - InfoRangeCheck (0x0000, 0xFFFF); - if (!(Attributes & tStart)) + InfoRangeCheck ("END", 0x0000, 0xFFFF); + if ((Attributes & tStart) == 0) { InfoError ("When using End with an offset, Start must be specified before"); + } End = Start + InfoIVal - 1; - if (End > 0xFFFF) + if (End > 0xFFFF) { InfoError ("Range error"); + } } else { InfoAssureInt (); - InfoRangeCheck (0x0000, 0xFFFF); + InfoRangeCheck ("END", 0x0000, 0xFFFF); End = InfoIVal; } InfoNextTok (); @@ -631,7 +633,7 @@ static void RangeSection (void) AddAttr ("START", &Attributes, tStart); InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (0x0000, 0xFFFF); + InfoRangeCheck ("START", 0x0000, 0xFFFF); Start = InfoIVal; InfoNextTok (); break; @@ -689,7 +691,7 @@ static void RangeSection (void) AddAttr ("UNIT", &Attributes, tUnit); InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (0x0002, 0xFFFF); + InfoRangeCheck ("UNIT", 0x0002, 0xFFFF); Unit = InfoIVal; InfoNextTok (); break; @@ -807,7 +809,7 @@ static void SegmentSection (void) InfoError ("Value already given"); } InfoAssureInt (); - InfoRangeCheck (0, 0xFFFF); + InfoRangeCheck ("END", 0, 0xFFFF); End = InfoIVal; InfoNextTok (); break; @@ -828,7 +830,7 @@ static void SegmentSection (void) InfoError ("Value already given"); } InfoAssureInt (); - InfoRangeCheck (0, 0xFFFF); + InfoRangeCheck ("START", 0, 0xFFFF); Start = InfoIVal; InfoNextTok (); break; diff --git a/src/da65/labels.c b/src/da65/labels.c index 4cae0316a..3a4cdd2d7 100644 --- a/src/da65/labels.c +++ b/src/da65/labels.c @@ -33,15 +33,17 @@ +#include <inttypes.h> #include <stdio.h> #include <string.h> /* common */ +#include "coll.h" +#include "strbuf.h" #include "xmalloc.h" #include "xsprintf.h" /* da65 */ -#include "attrtab.h" #include "code.h" #include "comments.h" #include "error.h" @@ -57,14 +59,82 @@ -/* Symbol table */ -static const char* SymTab[0x10000]; +/* Label structure how it is found in the label table */ +typedef struct Label Label; +struct Label { + struct Label* Next; /* Next entry in linked list */ + uint32_t Addr; /* The full address */ + char Name[1]; /* Symbol name, dynamically allocated */ +}; -/* 65816 symbol table */ -#define MAX_LONG_LABELS 256 -static const char* LongSymVal[MAX_LONG_LABELS]; -static unsigned LongSymAddr[MAX_LONG_LABELS]; -static unsigned LongLabelsUsed; +/* Labels use a hash table and a linear list for collision resolution. The +** hash function is easy and effective. It evaluates just the lower bits of +** the address. +*/ +#define LABEL_HASH_SIZE 4096u /* Must be power of two */ +static Label* LabelTab[LABEL_HASH_SIZE]; + + + +/*****************************************************************************/ +/* struct Label */ +/*****************************************************************************/ + + + +static Label* NewLabel (uint32_t Addr, const char* Name) +/* Create a new label structure and return it */ +{ + /* Get the length of the name */ + unsigned Len = strlen (Name); + + /* Create a new label */ + Label* L = xmalloc (sizeof (Label) + Len); + + /* Fill in the data */ + L->Next = 0; + L->Addr = Addr; + memcpy (L->Name, Name, Len + 1); + + /* Return the label just created */ + return L; +} + + + +static uint32_t GetLabelHash (uint32_t Addr) +/* Get the hash for a label at the given address */ +{ + return (Addr & (LABEL_HASH_SIZE - 1)); +} + + + +static Label* FindLabel (uint32_t Addr) +/* Search for a label for the given address and return it. Returns NULL if +** no label exists for the address. +*/ +{ + Label* L = LabelTab[GetLabelHash (Addr)]; + while (L) { + if (L->Addr == Addr) { + break; + } + L = L->Next; + } + return L; +} + + + +static void InsertLabel (Label* L) +/* Insert a label into the tables */ +{ + /* Insert into hash table */ + uint32_t Hash = GetLabelHash (L->Addr); + L->Next = LabelTab[Hash]; + LabelTab[Hash] = L; +} @@ -74,34 +144,19 @@ static unsigned LongLabelsUsed; -static const char* MakeLabelName (unsigned Addr) +static const char* MakeLabelName (uint32_t Addr) /* Make the default label name from the given address and return it in a ** static buffer. */ { static char LabelBuf [32]; - xsprintf (LabelBuf, sizeof (LabelBuf), - IsLongAddr (Addr) ? "L%06X" : "L%04X", Addr); + xsprintf (LabelBuf, sizeof (LabelBuf), "L%04" PRIX32, Addr); return LabelBuf; } -static unsigned FindLongIndex (unsigned Addr) -{ - unsigned i; - for (i = 0; i < LongLabelsUsed; i++) { - if (LongSymAddr[i] == Addr) { - return i; - } - } - - return -1; -} - - - -static void AddLabel (unsigned Addr, attr_t Attr, const char* Name) +static void AddLabel (uint32_t Addr, attr_t Attr, const char* Name) /* Add a label */ { /* Get an existing label attribute */ @@ -109,43 +164,25 @@ static void AddLabel (unsigned Addr, attr_t Attr, const char* Name) /* Must not have two symbols for one address */ if (ExistingAttr != atNoLabel) { - /* Allow redefinition if identical. Beware: Unnamed labels don't - ** have a name (you guessed that, didn't you?). + /* Allow redefinition if identical. Beware: Unnamed labels do not + ** have an entry in the label table. */ - if (IsLongAddr (Addr)) { - const unsigned i = FindLongIndex (Addr); - if (ExistingAttr == Attr && - ((Name == 0 && LongSymVal[i] == 0) || - (Name != 0 && LongSymVal[i] != 0 && - strcmp (LongSymVal[i], Name) == 0))) { - return; - } - Error ("Duplicate label for address $%06X (%s): '%s'", Addr, - LongSymVal[i] == 0 ? "<unnamed label>" : LongSymVal[i], - Name == 0 ? "<unnamed label>" : Name); - } else { - if (ExistingAttr == Attr && - ((Name == 0 && SymTab[Addr] == 0) || - (Name != 0 && SymTab[Addr] != 0 && - strcmp (SymTab[Addr], Name) == 0))) { - return; - } - Error ("Duplicate label for address $%04X (%s): '%s'", Addr, - SymTab[Addr] == 0 ? "<unnamed label>" : SymTab[Addr], - Name == 0 ? "<unnamed label>" : Name); + Label* L = FindLabel (Addr); + if (ExistingAttr == Attr && + ((Name == 0 && L == 0) || + (Name != 0 && L != 0 && strcmp (Name, L->Name) == 0))) { + return; } + Error ("Duplicate label for address $%04X (%s): '%s'", Addr, + L? L->Name : "<unnamed label>", + Name? Name : "<unnamed label>"); } - /* Create a new label (xstrdup will return NULL if input NULL) */ - if (IsLongAddr (Addr)) { - if (LongLabelsUsed >= MAX_LONG_LABELS) { - Error ("Too many long labels"); - } - LongSymAddr[LongLabelsUsed] = Addr; - LongSymVal[LongLabelsUsed] = xstrdup (Name); - LongLabelsUsed++; - } else { - SymTab[Addr] = xstrdup (Name); + /* If this is not an unnamed label, create a new label entry and + ** insert it. + */ + if (Name != 0) { + InsertLabel (NewLabel (Addr, Name)); } /* Remember the attribute */ @@ -154,7 +191,7 @@ static void AddLabel (unsigned Addr, attr_t Attr, const char* Name) -void AddIntLabel (unsigned Addr) +void AddIntLabel (uint32_t Addr) /* Add an internal label using the address to generate the name. */ { AddLabel (Addr, atIntLabel, MakeLabelName (Addr)); @@ -162,7 +199,7 @@ void AddIntLabel (unsigned Addr) -void AddExtLabel (unsigned Addr, const char* Name) +void AddExtLabel (uint32_t Addr, const char* Name) /* Add an external label */ { AddLabel (Addr, atExtLabel, Name); @@ -170,7 +207,7 @@ void AddExtLabel (unsigned Addr, const char* Name) -void AddUnnamedLabel (unsigned Addr) +void AddUnnamedLabel (uint32_t Addr) /* Add an unnamed label */ { AddLabel (Addr, atUnnamedLabel, 0); @@ -178,11 +215,27 @@ void AddUnnamedLabel (unsigned Addr) -void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs) +void AddDepLabel (uint32_t Addr, attr_t Attr, const char* BaseName, unsigned Offs) /* Add a dependent label at the given address using "basename+Offs" as the new ** name. */ { + /* Create the new name in the buffer */ + StrBuf Name = AUTO_STRBUF_INITIALIZER; + if (UseHexOffs) { + SB_Printf (&Name, "%s+$%02X", BaseName, Offs); + } else { + SB_Printf (&Name, "%s+%u", BaseName, Offs); + } + + /* Define the labels */ + AddLabel (Addr, Attr | atDepLabel, SB_GetConstBuf (&Name)); + + /* Free the name buffer */ + SB_Done (&Name); + + + /* Allocate memory for the dependent label name */ unsigned NameLen = strlen (BaseName); char* DepName = xmalloc (NameLen + 7); /* "+$ABCD\0" */ @@ -203,7 +256,7 @@ void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Off -static void AddLabelRange (unsigned Addr, attr_t Attr, +static void AddLabelRange (uint32_t Addr, attr_t Attr, const char* Name, unsigned Count) /* Add a label for a range. The first entry gets the label "Name" while the ** others get "Name+offs". @@ -241,7 +294,7 @@ static void AddLabelRange (unsigned Addr, attr_t Attr, -void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count) +void AddIntLabelRange (uint32_t Addr, const char* Name, unsigned Count) /* Add an internal label for a range. The first entry gets the label "Name" ** while the others get "Name+offs". */ @@ -252,7 +305,7 @@ void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count) -void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count) +void AddExtLabelRange (uint32_t Addr, const char* Name, unsigned Count) /* Add an external label for a range. The first entry gets the label "Name" ** while the others get "Name+offs". */ @@ -263,7 +316,7 @@ void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count) -int HaveLabel (unsigned Addr) +int HaveLabel (uint32_t Addr) /* Check if there is a label for the given address */ { /* Check for a label */ @@ -272,7 +325,7 @@ int HaveLabel (unsigned Addr) -int MustDefLabel (unsigned Addr) +int MustDefLabel (uint32_t Addr) /* Return true if we must define a label for this address, that is, if there ** is a label at this address, and it is an external or internal label. */ @@ -286,7 +339,7 @@ int MustDefLabel (unsigned Addr) -const char* GetLabelName (unsigned Addr) +const char* GetLabelName (uint32_t Addr) /* Return the label name for an address */ { /* Get the label attribute */ @@ -297,19 +350,16 @@ const char* GetLabelName (unsigned Addr) */ if (A == atUnnamedLabel) { return ""; - } else if (IsLongAddr (Addr)) { - /* Return the label if any */ - const unsigned i = FindLongIndex (Addr); - return i < LongLabelsUsed ? LongSymVal[i] : NULL; } else { /* Return the label if any */ - return SymTab[Addr]; + const Label* L = FindLabel (Addr); + return L? L->Name : 0; } } -const char* GetLabel (unsigned Addr, unsigned RefFrom) +const char* GetLabel (uint32_t Addr, uint32_t RefFrom) /* Return the label name for an address, as it is used in a label reference. ** RefFrom is the address the label is referenced from. This is needed in case ** of unnamed labels, to determine the name. @@ -339,7 +389,7 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom) */ if (Addr <= RefFrom) { /* Search backwards */ - unsigned I = RefFrom; + uint32_t I = RefFrom; while (Addr < I) { --I; A = GetLabelAttr (I); @@ -357,7 +407,7 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom) } else { /* Search forwards */ - unsigned I = RefFrom; + uint32_t I = RefFrom; while (Addr > I) { ++I; A = GetLabelAttr (I); @@ -373,26 +423,22 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom) /* Return the label name */ return FwdLabels[Count-1]; } - - } else if (IsLongAddr (Addr)) { - /* Return the label if any */ - const unsigned i = FindLongIndex (Addr); - return i < LongLabelsUsed ? LongSymVal[i] : NULL; } else { /* Return the label if any */ - return SymTab[Addr]; + const Label* L = FindLabel (Addr); + return L? L->Name : 0; } } -void ForwardLabel (unsigned Offs) +void ForwardLabel (uint32_t Offs) /* If necessary, output a forward label, one that is within the next few ** bytes and is therefore output as "label = * + x". */ { /* Calculate the actual address */ - unsigned long Addr = PC + Offs; + uint32_t Addr = PC + Offs; /* Get the type of the label */ attr_t A = GetLabelAttr (Addr); @@ -406,7 +452,7 @@ void ForwardLabel (unsigned Offs) ** an error. */ if (A == atUnnamedLabel) { - Error ("Cannot define unnamed label at address $%04lX", Addr); + Error ("Cannot define unnamed label at address $%04" PRIX32, Addr); } /* Output the label */ @@ -415,24 +461,33 @@ void ForwardLabel (unsigned Offs) -static void DefOutOfRangeLabel (unsigned long Addr) +static int CompareLabels (void* Data attribute ((unused)), + const void* L1, const void* L2) +/* Compare functions for sorting the out-of-range labels */ +{ + if (((const Label*) L1)->Addr < ((const Label*) L2)->Addr) { + return -1; + } else if (((const Label*) L1)->Addr > ((const Label*) L2)->Addr) { + return 1; + } else { + return 0; + } +} + + + +static void DefOutOfRangeLabel (const Label* L) /* Define one label that is outside code range. */ { - switch (GetLabelAttr (Addr)) { + switch (GetLabelAttr (L->Addr)) { case atIntLabel: case atExtLabel: - if (IsLongAddr (Addr)) { - const unsigned i = FindLongIndex (Addr); - DefConst (i < LongLabelsUsed ? LongSymVal[i] : NULL, - GetComment (Addr), Addr); - } else { - DefConst (SymTab[Addr], GetComment (Addr), Addr); - } + DefConst (L->Name, GetComment (L->Addr), L->Addr); break; case atUnnamedLabel: - Error ("Cannot define unnamed label at address $%04lX", Addr); + Error ("Cannot define unnamed label at address $%04" PRIX32, L->Addr); break; default: @@ -446,34 +501,40 @@ static void DefOutOfRangeLabel (unsigned long Addr) void DefOutOfRangeLabels (void) /* Output any labels that are out of the loaded code range */ { - unsigned long Addr; - unsigned i; + unsigned I; - SeparatorLine (); + /* This requires somewhat more effort since the labels output should be + ** sorted by address for better readability. This is not directly + ** possible when using a hash table, so an intermediate data structure + ** is required. It is not possible to collect out-of-range labels while + ** generating them, since they may come from an info file and where added + ** while no input file was read. Which means it cannot be determined at + ** that point if they're out-of-range or not. + */ + Collection Labels = AUTO_COLLECTION_INITIALIZER; + CollGrow (&Labels, 128); - /* Low range */ - Addr = 0; - while (Addr < CodeStart) { - DefOutOfRangeLabel (Addr++); - } - - /* Skip areas in code range */ - while (Addr <= CodeEnd) { - if (GetStyleAttr (Addr) == atSkip) { - DefOutOfRangeLabel (Addr); + /* Walk over the hash and copy all out-of-range labels */ + for (I = 0; I < LABEL_HASH_SIZE; ++I) { + Label* L = LabelTab[I]; + while (L) { + if (L->Addr < CodeStart || L->Addr > CodeEnd) { + CollAppend (&Labels, L); + } + L = L->Next; } - ++Addr; } - /* High range */ - while (Addr < 0x10000) { - DefOutOfRangeLabel (Addr++); - } - - /* 65816 long range */ - for (i = 0; i < LongLabelsUsed; i++) { - DefOutOfRangeLabel (LongSymAddr[i]); - } + /* Sort the out-of-range labels by address */ + CollSort (&Labels, CompareLabels, 0); + /* Output the labels */ SeparatorLine (); + for (I = 0; I < CollCount (&Labels); ++I) { + DefOutOfRangeLabel (CollConstAt (&Labels, I)); + } + SeparatorLine (); + + /* Free allocated storage */ + DoneCollection (&Labels); } diff --git a/src/da65/labels.h b/src/da65/labels.h index c4b52774a..37f2daeab 100644 --- a/src/da65/labels.h +++ b/src/da65/labels.h @@ -38,6 +38,9 @@ +#include <stdint.h> + +/* da65 */ #include "attrtab.h" @@ -48,42 +51,42 @@ -void AddIntLabel (unsigned Addr); +void AddIntLabel (uint32_t Addr); /* Add an internal label using the address to generate the name. */ -void AddExtLabel (unsigned Addr, const char* Name); +void AddExtLabel (uint32_t Addr, const char* Name); /* Add an external label */ -void AddUnnamedLabel (unsigned Addr); +void AddUnnamedLabel (uint32_t Addr); /* Add an unnamed label */ -void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs); +void AddDepLabel (uint32_t Addr, attr_t Attr, const char* BaseName, unsigned Offs); /* Add a dependent label at the given address using "base name+Offs" as the new ** name. */ -void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count); +void AddIntLabelRange (uint32_t Addr, const char* Name, unsigned Count); /* Add an internal label for a range. The first entry gets the label "Name" ** while the others get "Name+offs". */ -void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count); +void AddExtLabelRange (uint32_t Addr, const char* Name, unsigned Count); /* Add an external label for a range. The first entry gets the label "Name" ** while the others get "Name+offs". */ -int HaveLabel (unsigned Addr); +int HaveLabel (uint32_t Addr); /* Check if there is a label for the given address */ -int MustDefLabel (unsigned Addr); +int MustDefLabel (uint32_t Addr); /* Return true if we must define a label for this address, that is, if there ** is a label at this address, and it is an external or internal label. */ -const char* GetLabelName (unsigned Addr); +const char* GetLabelName (uint32_t Addr); /* Return the label name for an address */ -const char* GetLabel (unsigned Addr, unsigned RefFrom); +const char* GetLabel (uint32_t Addr, uint32_t RefFrom); /* Return the label name for an address, as it is used in a label reference. ** RefFrom is the address the label is referenced from. This is needed in case ** of unnamed labels, to determine the name. diff --git a/src/da65/main.c b/src/da65/main.c index 545cc657b..91eecd94f 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -313,7 +313,8 @@ static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg static void OptStartAddr (const char* Opt, const char* Arg) /* Set the default start address */ { - StartAddr = CvtNumber (Opt, Arg); + StartAddr = (uint32_t) CvtNumber (Opt, Arg); + HaveStartAddr = 1; } @@ -409,11 +410,11 @@ static unsigned HandleChangedLength(const OpcDesc* D, unsigned PC) static void OneOpcode (unsigned RemainingBytes) /* Disassemble one opcode */ { - unsigned I; - unsigned OldPC = PC; + uint32_t I; + uint32_t OldPC = PC; /* Get the opcode from the current address */ - unsigned char OPC = GetCodeByte (PC); + uint8_t OPC = GetCodeByte (PC); /* Get the opcode description for the opcode byte */ const OpcDesc* D = &OpcTable[OPC]; @@ -574,7 +575,7 @@ static void OneOpcode (unsigned RemainingBytes) static void OnePass (void) /* Make one pass through the code */ { - unsigned Count; + uint32_t Count; PrevAddrMode = 0; diff --git a/src/da65/output.c b/src/da65/output.c index 8e786e130..bc5f7d5c2 100644 --- a/src/da65/output.c +++ b/src/da65/output.c @@ -33,6 +33,7 @@ +#include <inttypes.h> #include <stdio.h> #include <stdarg.h> #include <string.h> @@ -208,13 +209,13 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs) -void DefConst (const char* Name, const char* Comment, unsigned Addr) +void DefConst (const char* Name, const char* Comment, uint32_t Addr) /* Define an address constant */ { if (Pass == PassCount) { Output ("%s", Name); Indent (ACol); - Output (":= $%04X", Addr); + Output (":= $%04" PRIX32, Addr); if (Comment) { Indent (CCol); Output ("; %s", Comment); @@ -225,19 +226,19 @@ void DefConst (const char* Name, const char* Comment, unsigned Addr) -void DataByteLine (unsigned ByteCount) +void DataByteLine (uint32_t ByteCount) /* Output a line with bytes */ { - unsigned I; + uint32_t I; Indent (MCol); Output (".byte"); Indent (ACol); for (I = 0; I < ByteCount; ++I) { if (I > 0) { - Output (",$%02X", CodeBuf[PC+I]); + Output (",$%02" PRIX8, CodeBuf[PC+I]); } else { - Output ("$%02X", CodeBuf[PC+I]); + Output ("$%02" PRIX8, CodeBuf[PC+I]); } } LineComment (PC, ByteCount); @@ -246,19 +247,19 @@ void DataByteLine (unsigned ByteCount) -void DataDByteLine (unsigned ByteCount) +void DataDByteLine (uint32_t ByteCount) /* Output a line with dbytes */ { - unsigned I; + uint32_t I; Indent (MCol); Output (".dbyt"); Indent (ACol); for (I = 0; I < ByteCount; I += 2) { if (I > 0) { - Output (",$%04X", GetCodeDByte (PC+I)); + Output (",$%04" PRIX16, GetCodeDByte (PC+I)); } else { - Output ("$%04X", GetCodeDByte (PC+I)); + Output ("$%04" PRIX16, GetCodeDByte (PC+I)); } } LineComment (PC, ByteCount); @@ -267,19 +268,19 @@ void DataDByteLine (unsigned ByteCount) -void DataWordLine (unsigned ByteCount) +void DataWordLine (uint32_t ByteCount) /* Output a line with words */ { - unsigned I; + uint32_t I; Indent (MCol); Output (".word"); Indent (ACol); for (I = 0; I < ByteCount; I += 2) { if (I > 0) { - Output (",$%04X", GetCodeWord (PC+I)); + Output (",$%04" PRIX16, GetCodeWord (PC+I)); } else { - Output ("$%04X", GetCodeWord (PC+I)); + Output ("$%04" PRIX16, GetCodeWord (PC+I)); } } LineComment (PC, ByteCount); @@ -288,19 +289,19 @@ void DataWordLine (unsigned ByteCount) -void DataDWordLine (unsigned ByteCount) +void DataDWordLine (uint32_t ByteCount) /* Output a line with dwords */ { - unsigned I; + uint32_t I; Indent (MCol); Output (".dword"); Indent (ACol); for (I = 0; I < ByteCount; I += 4) { if (I > 0) { - Output (",$%08lX", GetCodeDWord (PC+I)); + Output (",$%08" PRIX32, GetCodeDWord (PC+I)); } else { - Output ("$%08lX", GetCodeDWord (PC+I)); + Output ("$%08" PRIX32, GetCodeDWord (PC+I)); } } LineComment (PC, ByteCount); @@ -372,12 +373,12 @@ void LineComment (unsigned PC, unsigned Count) Output ("; %04X", PC); if (Comments >= 3) { for (I = 0; I < Count; ++I) { - Output (" %02X", CodeBuf [PC+I]); + Output (" %02" PRIX8, CodeBuf [PC+I]); } if (Comments >= 4) { Indent (TCol); for (I = 0; I < Count; ++I) { - unsigned char C = CodeBuf [PC+I]; + uint8_t C = CodeBuf [PC+I]; if (!isprint (C)) { C = '.'; } diff --git a/src/da65/output.h b/src/da65/output.h index bc20aace0..7370e0786 100644 --- a/src/da65/output.h +++ b/src/da65/output.h @@ -72,22 +72,22 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs); ** current PC. */ -void DefConst (const char* Name, const char* Comment, unsigned Addr); +void DefConst (const char* Name, const char* Comment, uint32_t Addr); /* Define an address constant */ void OneDataByte (void); /* Output a .byte line with the current code byte */ -void DataByteLine (unsigned ByteCount); +void DataByteLine (uint32_t ByteCount); /* Output a line with bytes */ -void DataDByteLine (unsigned ByteCount); +void DataDByteLine (uint32_t ByteCount); /* Output a line with dbytes */ -void DataWordLine (unsigned ByteCount); +void DataWordLine (uint32_t ByteCount); /* Output a line with words */ -void DataDWordLine (unsigned ByteCount); +void DataDWordLine (uint32_t ByteCount); /* Output a line with dwords */ void SeparatorLine (void); diff --git a/src/da65/scanner.c b/src/da65/scanner.c index d0301c08a..66940dfb6 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -600,11 +600,11 @@ void InfoAssureIdent (void) -void InfoRangeCheck (long Lo, long Hi) +void InfoRangeCheck (const char* Attr, long Lo, long Hi) /* Check the range of InfoIVal */ { if (InfoIVal < Lo || InfoIVal > Hi) { - InfoError ("Range error"); + InfoError ("Range error for attribute %s", Attr); } } diff --git a/src/da65/scanner.h b/src/da65/scanner.h index ce76d4a98..e34aecb4f 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -191,7 +191,7 @@ void InfoAssureChar (void); void InfoAssureIdent (void); /* Make sure the next token is an identifier */ -void InfoRangeCheck (long Lo, long Hi); +void InfoRangeCheck (const char* Attr, long Lo, long Hi); /* Check the range of InfoIVal */ void InfoSpecialToken (const IdentTok* Table, unsigned Size, const char* Name); diff --git a/src/da65/segment.c b/src/da65/segment.c index 12d4cf656..1a0b3b062 100644 --- a/src/da65/segment.c +++ b/src/da65/segment.c @@ -58,7 +58,7 @@ typedef struct Segment Segment; struct Segment { Segment* NextStart; /* Pointer to next segment */ - unsigned long Start; + uint32_t Start; unsigned AddrSize; char Name[1]; /* Name, dynamically allocated */ }; @@ -76,7 +76,7 @@ static Segment* StartTab[HASH_SIZE]; /* Table containing segment starts */ -void AddAbsSegment (unsigned Start, unsigned End, const char* Name) +void AddAbsSegment (uint32_t Start, uint32_t End, const char* Name) /* Add an absolute segment to the segment table */ { /* Get the length of the name */ @@ -104,7 +104,7 @@ void AddAbsSegment (unsigned Start, unsigned End, const char* Name) -char* GetSegmentStartName (unsigned Addr) +char* GetSegmentStartName (uint32_t Addr) /* Return the name of the segment which starts at the given address */ { Segment* S = StartTab[Addr % HASH_SIZE]; @@ -122,7 +122,7 @@ char* GetSegmentStartName (unsigned Addr) -unsigned GetSegmentAddrSize (unsigned Addr) +unsigned GetSegmentAddrSize (uint32_t Addr) /* Return the address size of the segment which starts at the given address */ { Segment* S = StartTab[Addr % HASH_SIZE]; diff --git a/src/da65/segment.h b/src/da65/segment.h index b1423bb41..5da30fda3 100644 --- a/src/da65/segment.h +++ b/src/da65/segment.h @@ -44,13 +44,13 @@ -void AddAbsSegment (unsigned Start, unsigned End, const char* Name); +void AddAbsSegment (uint32_t Start, uint32_t End, const char* Name); /* Add an absolute segment to the segment table */ -char* GetSegmentStartName (unsigned Addr); +char* GetSegmentStartName (uint32_t Addr); /* Return the name of the segment which starts at the given address */ -unsigned GetSegmentAddrSize (unsigned Addr); +unsigned GetSegmentAddrSize (uint32_t Addr); /* Return the address size of the segment which starts at the given address */ From 7d231d60a6b969ffd7198ac90ff77f23f74d4281 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 22 Jun 2025 12:15:33 +0200 Subject: [PATCH 572/707] Minor corrections after looking at the diff. --- src/da65/handler.c | 4 +--- src/da65/labels.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index 836dc2884..db55b4058 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -125,10 +125,8 @@ static const char* GetAddrArg (unsigned Flags, uint32_t Addr) static char Buf [32]; if (Addr < 0x100) { xsprintf (Buf, sizeof (Buf), "$%02" PRIX32, Addr); - } else if (Addr < 0x10000) { - xsprintf (Buf, sizeof (Buf), "$%04" PRIX32, Addr); } else { - xsprintf (Buf, sizeof (Buf), "$%06" PRIX32, Addr); + xsprintf (Buf, sizeof (Buf), "$%04" PRIX32, Addr); } return Buf; } diff --git a/src/da65/labels.c b/src/da65/labels.c index 3a4cdd2d7..6f6bce3ed 100644 --- a/src/da65/labels.c +++ b/src/da65/labels.c @@ -507,7 +507,7 @@ void DefOutOfRangeLabels (void) ** sorted by address for better readability. This is not directly ** possible when using a hash table, so an intermediate data structure ** is required. It is not possible to collect out-of-range labels while - ** generating them, since they may come from an info file and where added + ** generating them, since they may come from an info file and are added ** while no input file was read. Which means it cannot be determined at ** that point if they're out-of-range or not. */ From e949fbdbbfb125769f5129f79a5033af051b2a54 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 22 Jun 2025 20:32:55 +0200 Subject: [PATCH 573/707] Unify CPU list in the docs. --- doc/da65.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index 7300d3d71..dd51a4764 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -248,8 +248,8 @@ With the command line option <tt><ref id="option--cpu" name="--cpu"></tt>, the disassembler may be told which CPU to support: <itemize> - <item><ref id="6502-mode" name="6502 mode"> - NMOS 6502 (all legal instructions) - <item><ref id="6502X-mode" name="6502X mode"> - NMOS 6502 with all undocumented instructions + <item><ref id="6502-mode" name="6502"> - NMOS 6502 (all legal instructions) + <item><ref id="6502X-mode" name="6502X"> - NMOS 6502 with all undocumented instructions <item><ref id="DTV-mode" name="6502DTV"> - the emulated CPU of the C64DTV device <item><ref id="65SC02-mode" name="65SC02"> - first CMOS instruction set (no bit manipulation, no wai/stp) <item><ref id="65C02-mode" name="65C02"> - full CMOS instruction set (has bit manipulation and wai/stp) From 8615c244d93660bd8448125b3730b24f8f29707e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 22 Jun 2025 21:07:38 +0200 Subject: [PATCH 574/707] add initial target for mega65, also added c65 where missing. reworked from #1792 --- src/ca65/main.c | 4 ++++ src/cc65/codegen.c | 2 ++ src/cc65/main.c | 8 ++++++++ src/common/target.c | 2 ++ src/common/target.h | 1 + 5 files changed, 17 insertions(+) diff --git a/src/ca65/main.c b/src/ca65/main.c index 682e9be7f..f113bc812 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -342,6 +342,10 @@ static void SetSys (const char* Sys) NewSymbol ("__SYM1__", 1); break; + case TGT_MEGA65: + CBMSystem ("__MEGA65__"); + break; + case TGT_KIM1: NewSymbol ("__KIM1__", 1); break; diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index e55a318d6..17618e5ff 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -202,6 +202,8 @@ void g_preamble (void) case CPU_65C02: AddTextLine ("\t.setcpu\t\t\"65C02\""); break; case CPU_65816: AddTextLine ("\t.setcpu\t\t\"65816\""); break; case CPU_HUC6280: AddTextLine ("\t.setcpu\t\t\"HUC6280\""); break; + case CPU_4510: AddTextLine ("\t.setcpu\t\t\"4510\""); break; + case CPU_45GS02: AddTextLine ("\t.setcpu\t\t\"45GS02\""); break; default: Internal ("Unknown CPU: %d", CPU); } diff --git a/src/cc65/main.c b/src/cc65/main.c index 5b951dc56..abed6acae 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -301,6 +301,14 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__SYM1__", 1); break; + case TGT_C65: + cbmsys ("__C65__"); + break; + + case TGT_MEGA65: + cbmsys ("__MEGA65__"); + break; + case TGT_KIM1: DefineNumericMacro ("__KIM1__", 1); break; diff --git a/src/common/target.c b/src/common/target.c index 1544c215b..51e015adc 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -187,6 +187,7 @@ static const TargetEntry TargetMap[] = { { "kim1", TGT_KIM1 }, { "lunix", TGT_LUNIX }, { "lynx", TGT_LYNX }, + { "mega65", TGT_MEGA65, }, { "module", TGT_MODULE }, { "nes", TGT_NES }, { "none", TGT_NONE }, @@ -243,6 +244,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "c65", CPU_4510, BINFMT_BINARY, CTPET }, { "cx16", CPU_65C02, BINFMT_BINARY, CTPET }, { "sym1", CPU_6502, BINFMT_BINARY, CTNone }, + { "mega65", CPU_45GS02, BINFMT_BINARY, CTPET }, { "kim1", CPU_6502, BINFMT_BINARY, CTNone }, { "rp6502", CPU_65C02, BINFMT_BINARY, CTNone }, { "agat", CPU_6502, BINFMT_BINARY, CTAgat }, diff --git a/src/common/target.h b/src/common/target.h index d6c9fc35b..c5c8455a0 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -87,6 +87,7 @@ typedef enum { TGT_C65, TGT_CX16, TGT_SYM1, + TGT_MEGA65, TGT_KIM1, TGT_RP6502, TGT_AGAT, From 6d7f37c4f2fb97277535f6955be82ebf2e88e133 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 22 Jun 2025 21:08:13 +0200 Subject: [PATCH 575/707] update list of targets in the docs --- doc/ca65.sgml | 2 +- doc/cc65.sgml | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 1503b2f39..d2506d958 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -313,7 +313,7 @@ Here is a description of all the command line options: character constants into the character set of the target platform. The default for the target system is "none", which means that no translation will take place. The assembler supports the same target systems as the - compiler, see there for a list. + compiler, see <htmlurl url="ca65.html#option-t" name="there for a list">. Depending on the target, the default CPU type is also set. This can be overridden by using the <tt/<ref id="option--cpu" name="--cpu">/ option. diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 383a6dd6a..166c0fad4 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -610,27 +610,42 @@ Here is a description of all the command line options: <itemize> <item>none + <item>agat (a russian apple2 like computer) <item>apple2 <item>apple2enh <item>atari + <item>atari2600 + <item>atari5200 + <item>atari7800 <item>atarixl <item>atmos + <item>bbc <item>c16 (works also for the c116 with memory up to 32K) <item>c64 + <item>c65 <item>c128 <item>cbm510 (CBM-II series with 40 column video) <item>cbm610 (all CBM-II II computers with 80 column video) + <item>creativision + <item>cx16 + <item>gamate <item>geos-apple <item>geos-cbm + <item>geos (alias for geos-cbm) + <item>kim1 <item>lunix <item>lynx + <item>mega65 <item>nes <item>osic1p + <item>pce (PC engine) <item>pet (all CBM PET systems except the 2001) <item>plus4 + <item>p6502 <item>sim6502 <item>sim65c02 <item>supervision + <item>sym1 <item>telestrat <item>vic20 </itemize> From 715d9c00a2c8f12ef5aa38dbc5cf25b925c63726 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 22 Jun 2025 21:09:40 +0200 Subject: [PATCH 576/707] initial (identical) minimal "library" for assembly support for c65 and mega65. taken from #1792 --- libsrc/c65/exehdr.s | 32 ++++++++++++++++++++++++++++++++ libsrc/c65/loadaddr.s | 16 ++++++++++++++++ libsrc/mega65/exehdr.s | 32 ++++++++++++++++++++++++++++++++ libsrc/mega65/loadaddr.s | 16 ++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 libsrc/c65/exehdr.s create mode 100644 libsrc/c65/loadaddr.s create mode 100644 libsrc/mega65/exehdr.s create mode 100644 libsrc/mega65/loadaddr.s diff --git a/libsrc/c65/exehdr.s b/libsrc/c65/exehdr.s new file mode 100644 index 000000000..645fc12e7 --- /dev/null +++ b/libsrc/c65/exehdr.s @@ -0,0 +1,32 @@ +; +; Ullrich von Bassewitz, 2010-11-14 +; +; This module supplies a small BASIC stub program that jumps to the machine +; language code that follows it using SYS. +; + + ; The following symbol is used by linker config to force the module + ; to get included into the output file + .export __EXEHDR__: absolute = 1 + +.segment "EXEHDR" + + .addr Next + .word .version ; Line number + .byte $fe, $02, "0:" ; BANK 0 + .byte $9e ; SYS +; .byte <(((Start / 10000) .mod 10) + '0') + .byte <(((Start / 1000) .mod 10) + '0') + .byte <(((Start / 100) .mod 10) + '0') + .byte <(((Start / 10) .mod 10) + '0') + .byte <(((Start / 1) .mod 10) + '0') + .byte $00 ; End of BASIC line +Next: .word 0 ; BASIC end marker +Start: + +; If the start address is larger than 4 digits, the header generated above +; will not contain the highest digit. Instead of wasting one more digit that +; is almost never used, check it at link time and generate an error so the +; user knows something is wrong. + +.assert (Start < 10000), error, "Start address too large for generated BASIC stub" diff --git a/libsrc/c65/loadaddr.s b/libsrc/c65/loadaddr.s new file mode 100644 index 000000000..0675dd67d --- /dev/null +++ b/libsrc/c65/loadaddr.s @@ -0,0 +1,16 @@ +; +; Ullrich von Bassewitz, 2010-11-13 +; +; This module supplies the load address that is expected by Commodore +; machines in the first two bytes of an excutable disk file. +; + + + ; The following symbol is used by linker config to force the module + ; to get included into the output file + .export __LOADADDR__: absolute = 1 + +.segment "LOADADDR" + + .addr *+2 + diff --git a/libsrc/mega65/exehdr.s b/libsrc/mega65/exehdr.s new file mode 100644 index 000000000..645fc12e7 --- /dev/null +++ b/libsrc/mega65/exehdr.s @@ -0,0 +1,32 @@ +; +; Ullrich von Bassewitz, 2010-11-14 +; +; This module supplies a small BASIC stub program that jumps to the machine +; language code that follows it using SYS. +; + + ; The following symbol is used by linker config to force the module + ; to get included into the output file + .export __EXEHDR__: absolute = 1 + +.segment "EXEHDR" + + .addr Next + .word .version ; Line number + .byte $fe, $02, "0:" ; BANK 0 + .byte $9e ; SYS +; .byte <(((Start / 10000) .mod 10) + '0') + .byte <(((Start / 1000) .mod 10) + '0') + .byte <(((Start / 100) .mod 10) + '0') + .byte <(((Start / 10) .mod 10) + '0') + .byte <(((Start / 1) .mod 10) + '0') + .byte $00 ; End of BASIC line +Next: .word 0 ; BASIC end marker +Start: + +; If the start address is larger than 4 digits, the header generated above +; will not contain the highest digit. Instead of wasting one more digit that +; is almost never used, check it at link time and generate an error so the +; user knows something is wrong. + +.assert (Start < 10000), error, "Start address too large for generated BASIC stub" diff --git a/libsrc/mega65/loadaddr.s b/libsrc/mega65/loadaddr.s new file mode 100644 index 000000000..0675dd67d --- /dev/null +++ b/libsrc/mega65/loadaddr.s @@ -0,0 +1,16 @@ +; +; Ullrich von Bassewitz, 2010-11-13 +; +; This module supplies the load address that is expected by Commodore +; machines in the first two bytes of an excutable disk file. +; + + + ; The following symbol is used by linker config to force the module + ; to get included into the output file + .export __LOADADDR__: absolute = 1 + +.segment "LOADADDR" + + .addr *+2 + From f6a3f66f0b0e99d262aa015df6220931f036f4b3 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 22 Jun 2025 21:42:36 +0200 Subject: [PATCH 577/707] asm configs --- cfg/c65-asm.cfg | 20 ++++++++++++++++++++ cfg/mega65-asm.cfg | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 cfg/c65-asm.cfg create mode 100644 cfg/mega65-asm.cfg diff --git a/cfg/c65-asm.cfg b/cfg/c65-asm.cfg new file mode 100644 index 000000000..40904ef70 --- /dev/null +++ b/cfg/c65-asm.cfg @@ -0,0 +1,20 @@ +FEATURES { + STARTADDRESS: default = $2001; +} +SYMBOLS { + __LOADADDR__: type = import; +} +MEMORY { + ZP: file = "", start = $0002, size = $00FE, define = yes; + LOADADDR: file = %O, start = %S - 2, size = $0002; + MAIN: file = %O, start = %S, size = $D000 - %S; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + LOADADDR: load = LOADADDR, type = ro; + EXEHDR: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = rw; + RODATA: load = MAIN, type = ro, optional = yes; + DATA: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, optional = yes, define = yes; +} diff --git a/cfg/mega65-asm.cfg b/cfg/mega65-asm.cfg new file mode 100644 index 000000000..40904ef70 --- /dev/null +++ b/cfg/mega65-asm.cfg @@ -0,0 +1,20 @@ +FEATURES { + STARTADDRESS: default = $2001; +} +SYMBOLS { + __LOADADDR__: type = import; +} +MEMORY { + ZP: file = "", start = $0002, size = $00FE, define = yes; + LOADADDR: file = %O, start = %S - 2, size = $0002; + MAIN: file = %O, start = %S, size = $D000 - %S; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + LOADADDR: load = LOADADDR, type = ro; + EXEHDR: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = rw; + RODATA: load = MAIN, type = ro, optional = yes; + DATA: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, optional = yes, define = yes; +} From 44672e628154841dd6a7de57459157b24bf803f6 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 22 Jun 2025 21:43:21 +0200 Subject: [PATCH 578/707] prepared lib makefile. skip building the library while compiler support is not there --- libsrc/Makefile | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index 1ec0bcfea..970ae6972 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -21,6 +21,7 @@ CBMS = c128 \ GEOS = geos-apple \ geos-cbm +# FIXME: c65 (and perhaps mega65?) should be moved up to CBMS maybe TARGETS = agat \ apple2 \ apple2enh \ @@ -30,6 +31,7 @@ TARGETS = agat \ atari5200 \ atari7800 \ atmos \ + c65 \ creativision \ $(CBMS) \ $(GEOS) \ @@ -45,7 +47,8 @@ TARGETS = agat \ sim65c02 \ supervision \ sym1 \ - telestrat + telestrat \ + mega65 TARGETTEST = none \ sim6502 \ @@ -193,6 +196,11 @@ ifeq ($(TARGET),$(filter $(TARGET),$(GEOS))) SRCDIRS += $(addprefix geos-common/,$(GEOSDIRS)) endif +ifeq ($(TARGET),c65) +# FIXME: the compiler does not work for 4510 yet +else ifeq ($(TARGET),mega65) +# FIXME: the compiler does not work for 45GS02 yet +else SRCDIRS += common \ conio \ dbg \ @@ -203,6 +211,7 @@ SRCDIRS += common \ serial \ tgi \ zlib +endif vpath %.s $(SRCDIRS) vpath %.c $(SRCDIRS) From 04890985175fe3f446928f1b66b8afd4714ab672 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Sun, 22 Jun 2025 21:34:41 +0000 Subject: [PATCH 579/707] restore comment alignment --- libsrc/atari/crt0.s | 4 ++-- libsrc/atari/fdtable.s | 2 +- libsrc/atari/ucase_fn.s | 4 ++-- libsrc/atari5200/crt0.s | 2 +- libsrc/atmos/crt0.s | 2 +- libsrc/c128/crt0.s | 2 +- libsrc/c16/crt0.s | 2 +- libsrc/c64/crt0.s | 2 +- libsrc/common/fread.s | 2 +- libsrc/common/memcpy.s | 2 +- libsrc/common/memset.s | 2 +- libsrc/common/vfprintf.s | 4 ++-- libsrc/common/vscanf.s | 2 +- libsrc/cx16/crt0.s | 2 +- libsrc/dbg/dbgdump.s | 6 +++--- libsrc/nes/crt0.s | 2 +- libsrc/pce/memcpy.s | 4 ++-- libsrc/pet/crt0.s | 2 +- libsrc/runtime/add.s | 22 +++++++++++----------- libsrc/runtime/addysp.s | 6 +++--- libsrc/runtime/and.s | 2 +- libsrc/runtime/enter.s | 2 +- libsrc/runtime/icmp.s | 12 ++++++------ libsrc/runtime/incsp2.s | 14 +++++++------- libsrc/runtime/ladd.s | 10 +++++----- libsrc/runtime/land.s | 10 +++++----- libsrc/runtime/ldaxsp.s | 4 ++-- libsrc/runtime/leave.s | 4 ++-- libsrc/runtime/lor.s | 8 ++++---- libsrc/runtime/lrsub.s | 8 ++++---- libsrc/runtime/lsub.s | 6 +++--- libsrc/runtime/lxor.s | 10 +++++----- libsrc/runtime/popa.s | 4 ++-- libsrc/runtime/popptr1.s | 6 +++--- libsrc/runtime/popsreg.s | 6 +++--- libsrc/runtime/pusha.s | 12 ++++++------ libsrc/runtime/pushax.s | 12 ++++++------ libsrc/runtime/pushbsp.s | 2 +- libsrc/runtime/pushwsp.s | 14 +++++++------- libsrc/runtime/regswap.s | 4 ++-- libsrc/runtime/regswap1.s | 4 ++-- libsrc/runtime/regswap2.s | 8 ++++---- libsrc/runtime/rsub.s | 4 ++-- libsrc/runtime/sub.s | 4 ++-- libsrc/runtime/tosint.s | 2 +- libsrc/runtime/toslong.s | 4 ++-- libsrc/runtime/zeropage.s | 2 +- libsrc/sim6502/exehdr.s | 2 +- libsrc/supervision/crt0.s | 2 +- libsrc/telestrat/crt0.s | 2 +- libsrc/vic20/crt0.s | 2 +- 51 files changed, 131 insertions(+), 131 deletions(-) diff --git a/libsrc/atari/crt0.s b/libsrc/atari/crt0.s index 2ccc7eeb9..23c1f580c 100644 --- a/libsrc/atari/crt0.s +++ b/libsrc/atari/crt0.s @@ -75,11 +75,11 @@ start: lda MEMTOP sbc #<__RESERVED_MEMORY__ sta APPMHI ; initialize our APPMHI value - sta c_sp ; set up runtime stack part 1 + sta c_sp ; set up runtime stack part 1 lda MEMTOP+1 sbc #>__RESERVED_MEMORY__ sta APPMHI+1 - sta c_sp+1 ; set up runtime stack part 2 + sta c_sp+1 ; set up runtime stack part 2 .endif diff --git a/libsrc/atari/fdtable.s b/libsrc/atari/fdtable.s index 9323af5d3..d1d869387 100644 --- a/libsrc/atari/fdtable.s +++ b/libsrc/atari/fdtable.s @@ -229,7 +229,7 @@ freefnd:txa beq l2 l1: ldy #0 - lda (c_sp),y ; get device + lda (c_sp),y ; get device l2: sta fd_table+ft_dev,x ; set device lda #1 sta fd_table+ft_usa,x ; set usage counter diff --git a/libsrc/atari/ucase_fn.s b/libsrc/atari/ucase_fn.s index d67fa36e5..534c6a21c 100644 --- a/libsrc/atari/ucase_fn.s +++ b/libsrc/atari/ucase_fn.s @@ -69,7 +69,7 @@ loop2: lda (ptr4),y cmp #'a' bcc L1 ; Not lowercase and #$DF ; make upper case char, assume ASCII chars - sta (c_sp),y ; store back + sta (c_sp),y ; store back L1: iny bpl loop2 ; bpl: this way we only support a max. length of 127 @@ -93,7 +93,7 @@ copy_end: jsr subysp ; adjust stack pointer dey cpdev: lda __defdev,y - sta (c_sp),y ; insert device name, number and ':' + sta (c_sp),y ; insert device name, number and ':' dey bpl cpdev hasdev2: diff --git a/libsrc/atari5200/crt0.s b/libsrc/atari5200/crt0.s index b0b0738a0..a72d7f9f6 100644 --- a/libsrc/atari5200/crt0.s +++ b/libsrc/atari5200/crt0.s @@ -28,7 +28,7 @@ start: lda #<(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__) ldx #>(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__) sta c_sp - stx c_sp+1 ; Set argument stack ptr + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/atmos/crt0.s b/libsrc/atmos/crt0.s index 05137193c..55c60dd30 100644 --- a/libsrc/atmos/crt0.s +++ b/libsrc/atmos/crt0.s @@ -86,7 +86,7 @@ L1: lda c_sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) sta c_sp - stx c_sp+1 ; Set argument stack ptr + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/c128/crt0.s b/libsrc/c128/crt0.s index b54533864..f6a55778c 100644 --- a/libsrc/c128/crt0.s +++ b/libsrc/c128/crt0.s @@ -59,7 +59,7 @@ L1: lda c_sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta c_sp - stx c_sp+1 ; Set argument stack ptr + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/c16/crt0.s b/libsrc/c16/crt0.s index 491000e52..c203fb20f 100644 --- a/libsrc/c16/crt0.s +++ b/libsrc/c16/crt0.s @@ -50,7 +50,7 @@ L1: lda c_sp,x ldy #$80 ldx #$00 MemOk: stx c_sp - sty c_sp+1 ; set argument stack ptr + sty c_sp+1 ; set argument stack ptr ; Call the module constructors. diff --git a/libsrc/c64/crt0.s b/libsrc/c64/crt0.s index 9e0162513..dea9226aa 100644 --- a/libsrc/c64/crt0.s +++ b/libsrc/c64/crt0.s @@ -95,7 +95,7 @@ L1: lda c_sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) sta c_sp - stx c_sp+1 ; Set argument stack ptr + stx c_sp+1 ; Set argument stack ptr ; Switch to the second charset. diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index 2dc9ad936..be06c2a62 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -152,7 +152,7 @@ lda (c_sp),y sta ptr1+1 adc #0 - sta (c_sp),y ; ptr1 = buf++; + sta (c_sp),y ; ptr1 = buf++; ; Get the buffered character and place it as first character into the read ; buffer. diff --git a/libsrc/common/memcpy.s b/libsrc/common/memcpy.s index e9c3f1968..8f6531956 100644 --- a/libsrc/common/memcpy.s +++ b/libsrc/common/memcpy.s @@ -74,6 +74,6 @@ memcpy_getparams: ; IMPORTANT! Function has to leave with Y=0! tax stx ptr2+1 ; save high byte of ptr2 dey ; Y = 0 - lda (c_sp),y ; Get ptr2 low + lda (c_sp),y ; Get ptr2 low sta ptr2 rts diff --git a/libsrc/common/memset.s b/libsrc/common/memset.s index 13e8ece9f..5d56507a5 100644 --- a/libsrc/common/memset.s +++ b/libsrc/common/memset.s @@ -39,7 +39,7 @@ common: ; Fill value is in X! lda (c_sp),y sta ptr1+1 ; save high byte of ptr dey ; Y = 0 - lda (c_sp),y ; Get ptr + lda (c_sp),y ; Get ptr sta ptr1 lsr ptr3+1 ; divide number of diff --git a/libsrc/common/vfprintf.s b/libsrc/common/vfprintf.s index 65bf62a22..3dc1e6729 100644 --- a/libsrc/common/vfprintf.s +++ b/libsrc/common/vfprintf.s @@ -121,12 +121,12 @@ _vfprintf: ; exactly as _printf expects it. Parameters will get dropped by _printf. ldy #2 - lda (c_sp),y ; Low byte of f + lda (c_sp),y ; Low byte of f sta ptr lda #<outdesc sta (c_sp),y iny - lda (c_sp),y ; High byte of f + lda (c_sp),y ; High byte of f sta ptr+1 lda #>outdesc sta (c_sp),y diff --git a/libsrc/common/vscanf.s b/libsrc/common/vscanf.s index 1681acd97..a97bd163a 100644 --- a/libsrc/common/vscanf.s +++ b/libsrc/common/vscanf.s @@ -31,7 +31,7 @@ _vscanf: ; Move the format down ldy #2 - lda (c_sp),y ; Load byte of format + lda (c_sp),y ; Load byte of format ldy #0 sta (c_sp),y ldy #3 diff --git a/libsrc/cx16/crt0.s b/libsrc/cx16/crt0.s index 0f8452a32..5ee81b184 100644 --- a/libsrc/cx16/crt0.s +++ b/libsrc/cx16/crt0.s @@ -81,7 +81,7 @@ init: lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) sta c_sp - stx c_sp+1 ; Set argument stack ptr + stx c_sp+1 ; Set argument stack ptr ; Switch to the lower/UPPER PetSCII charset. diff --git a/libsrc/dbg/dbgdump.s b/libsrc/dbg/dbgdump.s index 2a4aea3f7..335175840 100644 --- a/libsrc/dbg/dbgdump.s +++ b/libsrc/dbg/dbgdump.s @@ -11,16 +11,16 @@ _DbgMemDump: ldy #0 - lda (c_sp),y ; Get length + lda (c_sp),y ; Get length sta tmp4 iny - lda (c_sp),y ; Get the string buffer + lda (c_sp),y ; Get the string buffer sta ptr3 iny lda (c_sp),y sta ptr3+1 iny - lda (c_sp),y ; Get the address + lda (c_sp),y ; Get the address sta ptr4 iny lda (c_sp),y diff --git a/libsrc/nes/crt0.s b/libsrc/nes/crt0.s index 9b5ceb337..dfc26dcde 100644 --- a/libsrc/nes/crt0.s +++ b/libsrc/nes/crt0.s @@ -108,7 +108,7 @@ start: lda #<(__SRAM_START__ + __SRAM_SIZE__) ldx #>(__SRAM_START__ + __SRAM_SIZE__) sta c_sp - stx c_sp+1 ; Set argument stack ptr + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/pce/memcpy.s b/libsrc/pce/memcpy.s index 5a0822ec1..7ee33477b 100644 --- a/libsrc/pce/memcpy.s +++ b/libsrc/pce/memcpy.s @@ -86,9 +86,9 @@ memcpy_getparams: ; (Direct stack access is six cycles faster [total cycle count].) iny ; (Y=0 by popptr1, need '1' here) save dest - lda (c_sp),y ; get high byte + lda (c_sp),y ; get high byte tax - lda (c_sp) ; get low byte + lda (c_sp) ; get low byte sta ptr2 stx ptr2+1 rts ; return dest address (for memmove) diff --git a/libsrc/pet/crt0.s b/libsrc/pet/crt0.s index ff57d7bac..e3c6ed4b4 100644 --- a/libsrc/pet/crt0.s +++ b/libsrc/pet/crt0.s @@ -54,7 +54,7 @@ L1: lda c_sp,x lda MEMSIZE sta c_sp lda MEMSIZE+1 - sta c_sp+1 ; Set argument stack ptr + sta c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/runtime/add.s b/libsrc/runtime/add.s index b308614a1..85ddd0f25 100644 --- a/libsrc/runtime/add.s +++ b/libsrc/runtime/add.s @@ -20,34 +20,34 @@ tosaddax: .if (.cpu .bitand ::CPU_ISET_65SC02) - adc (c_sp) ; (7) + adc (c_sp) ; (7) tay ; (9) - inc c_sp ; (14) + inc c_sp ; (14) bne hiadd ; (17) - inc c_sp+1 ; (-1+5) + inc c_sp+1 ; (-1+5) hiadd: txa ; (19) - adc (c_sp) ; (24) + adc (c_sp) ; (24) tax ; (26) - inc c_sp ; (31) + inc c_sp ; (31) bne done ; (34) - inc c_sp+1 ; (-1+5) + inc c_sp+1 ; (-1+5) done: tya ; (36) .else ldy #0 ; (4) - adc (c_sp),y ; (9) lo byte + adc (c_sp),y ; (9) lo byte iny ; (11) sta tmp1 ; (14) save it txa ; (16) - adc (c_sp),y ; (21) hi byte + adc (c_sp),y ; (21) hi byte tax ; (23) clc ; (25) - lda c_sp ; (28) + lda c_sp ; (28) adc #2 ; (30) - sta c_sp ; (33) + sta c_sp ; (33) bcc L1 ; (36) - inc c_sp+1 ; (-1+5) + inc c_sp+1 ; (-1+5) L1: lda tmp1 ; (39) restore low byte .endif diff --git a/libsrc/runtime/addysp.s b/libsrc/runtime/addysp.s index 553ed98c7..d48e048bb 100644 --- a/libsrc/runtime/addysp.s +++ b/libsrc/runtime/addysp.s @@ -12,10 +12,10 @@ addysp1: addysp: pha ; Save A clc tya ; Get the value - adc c_sp ; Add low byte - sta c_sp ; Put it back + adc c_sp ; Add low byte + sta c_sp ; Put it back bcc @L1 ; If no carry, we're done - inc c_sp+1 ; Inc high byte + inc c_sp+1 ; Inc high byte @L1: pla ; Restore A rts diff --git a/libsrc/runtime/and.s b/libsrc/runtime/and.s index 21acebb66..8411660ab 100644 --- a/libsrc/runtime/and.s +++ b/libsrc/runtime/and.s @@ -14,7 +14,7 @@ tosanda0: ldx #$00 tosandax: .if (.cpu .bitand CPU_ISET_65SC02) - and (c_sp) ; 65SC02 version, saves 2 cycles and 1 byte + and (c_sp) ; 65SC02 version, saves 2 cycles and 1 byte ldy #1 .else ldy #0 diff --git a/libsrc/runtime/enter.s b/libsrc/runtime/enter.s index 5915f579a..454c2a6f9 100644 --- a/libsrc/runtime/enter.s +++ b/libsrc/runtime/enter.s @@ -13,6 +13,6 @@ enter: tya ; get arg size dec c_sp+1 L1: dec c_sp ldy #0 - sta (c_sp),y ; Store the arg count + sta (c_sp),y ; Store the arg count rts diff --git a/libsrc/runtime/icmp.s b/libsrc/runtime/icmp.s index 0d3bb6140..eba8ce561 100644 --- a/libsrc/runtime/icmp.s +++ b/libsrc/runtime/icmp.s @@ -17,16 +17,16 @@ tosicmp: stx sreg+1 ; Save ax ldy #$00 - lda (c_sp),y ; Get low byte + lda (c_sp),y ; Get low byte tax - inc c_sp ; 5 + inc c_sp ; 5 bne @L1 ; 3 - inc c_sp+1 ; (5) + inc c_sp+1 ; (5) @L1: - lda (c_sp),y ; Get high byte - inc c_sp ; 5 + lda (c_sp),y ; Get high byte + inc c_sp ; 5 bne @L2 ; 3 - inc c_sp+1 ; (5) + inc c_sp+1 ; (5) ; Do the compare. diff --git a/libsrc/runtime/incsp2.s b/libsrc/runtime/incsp2.s index 0d84dc7bb..c3260c19d 100644 --- a/libsrc/runtime/incsp2.s +++ b/libsrc/runtime/incsp2.s @@ -14,13 +14,13 @@ .proc popax ldy #1 - lda (c_sp),y ; get hi byte + lda (c_sp),y ; get hi byte tax ; into x .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (c_sp) ; get lo byte + lda (c_sp) ; get lo byte .else dey - lda (c_sp),y ; get lo byte + lda (c_sp),y ; get lo byte .endif .endproc @@ -29,14 +29,14 @@ .proc incsp2 - inc c_sp ; 5 + inc c_sp ; 5 beq @L1 ; 2 - inc c_sp ; 5 + inc c_sp ; 5 beq @L2 ; 2 rts -@L1: inc c_sp ; 5 -@L2: inc c_sp+1 ; 5 +@L1: inc c_sp ; 5 +@L2: inc c_sp+1 ; 5 rts .endproc diff --git a/libsrc/runtime/ladd.s b/libsrc/runtime/ladd.s index 6658d7ec6..6c187f32d 100644 --- a/libsrc/runtime/ladd.s +++ b/libsrc/runtime/ladd.s @@ -20,24 +20,24 @@ tosadd0ax: tosaddeax: clc .if (.cpu .bitand CPU_ISET_65SC02) - adc (c_sp) ; 65SC02 version - saves 2 cycles + adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else ldy #0 - adc (c_sp),y ; lo byte + adc (c_sp),y ; lo byte iny .endif sta tmp1 ; use as temp storage txa - adc (c_sp),y ; byte 1 + adc (c_sp),y ; byte 1 tax iny lda sreg - adc (c_sp),y ; byte 2 + adc (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - adc (c_sp),y ; byte 3 + adc (c_sp),y ; byte 3 sta sreg+1 lda tmp1 ; load byte 0 jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/land.s b/libsrc/runtime/land.s index 9dd3cad6a..400fede3b 100644 --- a/libsrc/runtime/land.s +++ b/libsrc/runtime/land.s @@ -23,24 +23,24 @@ tosand0ax: tosandeax: .if (.cpu .bitand ::CPU_ISET_65SC02) - and (c_sp) ; byte 0 + and (c_sp) ; byte 0 ldy #1 .else ldy #0 - and (c_sp),y ; byte 0 + and (c_sp),y ; byte 0 iny .endif sta tmp1 txa - and (c_sp),y ; byte 1 + and (c_sp),y ; byte 1 tax iny lda sreg - and (c_sp),y ; byte 2 + and (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - and (c_sp),y ; byte 3 + and (c_sp),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/ldaxsp.s b/libsrc/runtime/ldaxsp.s index 88a3043a0..b744ce242 100644 --- a/libsrc/runtime/ldaxsp.s +++ b/libsrc/runtime/ldaxsp.s @@ -12,9 +12,9 @@ ldax0sp: ldy #1 ldaxysp: - lda (c_sp),y ; get high byte + lda (c_sp),y ; get high byte tax ; and save it dey ; point to lo byte - lda (c_sp),y ; load low byte + lda (c_sp),y ; load low byte rts diff --git a/libsrc/runtime/leave.s b/libsrc/runtime/leave.s index a917ab955..408fdd159 100644 --- a/libsrc/runtime/leave.s +++ b/libsrc/runtime/leave.s @@ -31,7 +31,7 @@ leavey: .if (.cpu .bitand ::CPU_ISET_65SC02) leave: tay ; save A a sec - lda (c_sp) ; that's the pushed arg size + lda (c_sp) ; that's the pushed arg size sec ; Count the byte, the count's stored in adc c_sp sta c_sp @@ -43,7 +43,7 @@ L1: tya ; Get return value back leave: pha ; save A a sec ldy #0 - lda (c_sp),y ; that's the pushed arg size + lda (c_sp),y ; that's the pushed arg size sec ; Count the byte, the count's stored in adc c_sp sta c_sp diff --git a/libsrc/runtime/lor.s b/libsrc/runtime/lor.s index 94731adac..888a0c611 100644 --- a/libsrc/runtime/lor.s +++ b/libsrc/runtime/lor.s @@ -27,20 +27,20 @@ tosoreax: ldy #1 .else ldy #0 - ora (c_sp),y ; byte 0 + ora (c_sp),y ; byte 0 iny .endif sta tmp1 txa - ora (c_sp),y ; byte 1 + ora (c_sp),y ; byte 1 tax iny lda sreg - ora (c_sp),y ; byte 2 + ora (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - ora (c_sp),y ; byte 3 + ora (c_sp),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/lrsub.s b/libsrc/runtime/lrsub.s index 3bf941951..456d8d8d5 100644 --- a/libsrc/runtime/lrsub.s +++ b/libsrc/runtime/lrsub.s @@ -31,20 +31,20 @@ tosrsubeax: ldy #1 .else ldy #0 - sbc (c_sp),y ; byte 0 + sbc (c_sp),y ; byte 0 iny .endif sta tmp1 ; use as temp storage txa - sbc (c_sp),y ; byte 1 + sbc (c_sp),y ; byte 1 tax iny lda sreg - sbc (c_sp),y ; byte 2 + sbc (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - sbc (c_sp),y ; byte 3 + sbc (c_sp),y ; byte 3 sta sreg+1 lda tmp1 jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/lsub.s b/libsrc/runtime/lsub.s index 2c0082deb..17b225404 100644 --- a/libsrc/runtime/lsub.s +++ b/libsrc/runtime/lsub.s @@ -27,17 +27,17 @@ tossubeax: sec eor #$FF .if (.cpu .bitand ::CPU_ISET_65SC02) - adc (c_sp) ; 65SC02 version - saves 2 cycles + adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else ldy #0 - adc (c_sp),y ; lo byte + adc (c_sp),y ; lo byte iny .endif pha ; Save low byte txa eor #$FF - adc (c_sp),y ; byte 1 + adc (c_sp),y ; byte 1 tax iny lda (c_sp),y diff --git a/libsrc/runtime/lxor.s b/libsrc/runtime/lxor.s index 8b17d8df6..6d9f7db3a 100644 --- a/libsrc/runtime/lxor.s +++ b/libsrc/runtime/lxor.s @@ -23,24 +23,24 @@ tosxor0ax: tosxoreax: .if (.cpu .bitand ::CPU_ISET_65SC02) - eor (c_sp) ; byte 0 + eor (c_sp) ; byte 0 ldy #1 .else ldy #0 - eor (c_sp),y ; byte 0 + eor (c_sp),y ; byte 0 iny .endif sta tmp1 txa - eor (c_sp),y ; byte 1 + eor (c_sp),y ; byte 1 tax iny lda sreg - eor (c_sp),y ; byte 2 + eor (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - eor (c_sp),y ; byte 3 + eor (c_sp),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/popa.s b/libsrc/runtime/popa.s index c90f2be59..c1700071d 100644 --- a/libsrc/runtime/popa.s +++ b/libsrc/runtime/popa.s @@ -15,9 +15,9 @@ lda (c_sp) .else ldy #0 ; (2) - lda (c_sp),y ; (7) Read byte + lda (c_sp),y ; (7) Read byte .endif - inc c_sp ; (12) + inc c_sp ; (12) beq @L1 ; (14) rts ; (20) diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index caa43f3e0..45043dd27 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -12,13 +12,13 @@ .proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) ldy #1 - lda (c_sp),y ; get hi byte + lda (c_sp),y ; get hi byte sta ptr1+1 ; into ptr hi dey ; dey even for for 65C02 here to have Y=0 at exit! .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (c_sp) ; get lo byte + lda (c_sp) ; get lo byte .else - lda (c_sp),y ; get lo byte + lda (c_sp),y ; get lo byte .endif sta ptr1 ; to ptr lo jmp incsp2 diff --git a/libsrc/runtime/popsreg.s b/libsrc/runtime/popsreg.s index 6c1a61a32..c7f667246 100644 --- a/libsrc/runtime/popsreg.s +++ b/libsrc/runtime/popsreg.s @@ -13,13 +13,13 @@ popsreg: pha ; save A ldy #1 - lda (c_sp),y ; get hi byte + lda (c_sp),y ; get hi byte sta sreg+1 ; store it .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (c_sp) ; get lo byte + lda (c_sp) ; get lo byte .else dey - lda (c_sp),y ; get lo byte + lda (c_sp),y ; get lo byte .endif sta sreg ; store it pla ; get A back diff --git a/libsrc/runtime/pusha.s b/libsrc/runtime/pusha.s index 253612172..399423077 100644 --- a/libsrc/runtime/pusha.s +++ b/libsrc/runtime/pusha.s @@ -15,15 +15,15 @@ pusha0sp: ldy #$00 pushaysp: lda (c_sp),y -pusha: ldy c_sp ; (3) +pusha: ldy c_sp ; (3) beq @L1 ; (6) - dec c_sp ; (11) + dec c_sp ; (11) ldy #0 ; (13) - sta (c_sp),y ; (19) + sta (c_sp),y ; (19) rts ; (25) -@L1: dec c_sp+1 ; (11) - dec c_sp ; (16) - sta (c_sp),y ; (22) +@L1: dec c_sp+1 ; (11) + dec c_sp ; (16) + sta (c_sp),y ; (22) rts ; (28) diff --git a/libsrc/runtime/pushax.s b/libsrc/runtime/pushax.s index 247a38630..f77a9bcc3 100644 --- a/libsrc/runtime/pushax.s +++ b/libsrc/runtime/pushax.s @@ -20,21 +20,21 @@ pusha0: ldx #0 .proc pushax pha ; (3) - lda c_sp ; (6) + lda c_sp ; (6) sec ; (8) sbc #2 ; (10) - sta c_sp ; (13) + sta c_sp ; (13) bcs @L1 ; (17) - dec c_sp+1 ; (+5) + dec c_sp+1 ; (+5) @L1: ldy #1 ; (19) txa ; (21) - sta (c_sp),y ; (27) + sta (c_sp),y ; (27) pla ; (31) dey ; (33) .if (.cpu .bitand ::CPU_ISET_65SC02) - sta (c_sp) ; (37) + sta (c_sp) ; (37) .else - sta (c_sp),y ; (38) + sta (c_sp),y ; (38) .endif rts ; (44/43) diff --git a/libsrc/runtime/pushbsp.s b/libsrc/runtime/pushbsp.s index 64da06723..45ad93b12 100644 --- a/libsrc/runtime/pushbsp.s +++ b/libsrc/runtime/pushbsp.s @@ -11,7 +11,7 @@ pushbsp: ldy #0 pushbysp: - lda (c_sp),y ; get lo byte + lda (c_sp),y ; get lo byte jmp pusha0 ; promote to unsigned and push diff --git a/libsrc/runtime/pushwsp.s b/libsrc/runtime/pushwsp.s index 3bd164230..31c08d624 100644 --- a/libsrc/runtime/pushwsp.s +++ b/libsrc/runtime/pushwsp.s @@ -12,20 +12,20 @@ pushw0sp: ldy #3 pushwysp: - lda c_sp ; 3 + lda c_sp ; 3 sub #2 ; 4 - sta c_sp ; 3 + sta c_sp ; 3 bcs @L1 ; 3(+1) - dec c_sp+1 ; (5) -@L1: lda (c_sp),y ; 5 =16 + dec c_sp+1 ; (5) +@L1: lda (c_sp),y ; 5 =16 tax ; 2 dey ; 2 - lda (c_sp),y ; 5 + lda (c_sp),y ; 5 ldy #$00 ; 2 - sta (c_sp),y ; 5 + sta (c_sp),y ; 5 iny ; 2 txa ; 2 - sta (c_sp),y ; 5 + sta (c_sp),y ; 5 rts diff --git a/libsrc/runtime/regswap.s b/libsrc/runtime/regswap.s index 96080c823..17db9ee27 100644 --- a/libsrc/runtime/regswap.s +++ b/libsrc/runtime/regswap.s @@ -12,10 +12,10 @@ sta tmp1 ; Store count @L1: lda regbank,x ; Get old value pha ; Save it - lda (c_sp),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank,x ; Store new value pla - sta (c_sp),y ; Store old value + sta (c_sp),y ; Store old value inx iny dec tmp1 diff --git a/libsrc/runtime/regswap1.s b/libsrc/runtime/regswap1.s index 34cfd50eb..22cf170dc 100644 --- a/libsrc/runtime/regswap1.s +++ b/libsrc/runtime/regswap1.s @@ -11,10 +11,10 @@ lda regbank,x ; Get old value pha ; Save it - lda (c_sp),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank,x ; Store new value pla - sta (c_sp),y ; Store old value + sta (c_sp),y ; Store old value rts .endproc diff --git a/libsrc/runtime/regswap2.s b/libsrc/runtime/regswap2.s index 4f55fad40..07bc7c196 100644 --- a/libsrc/runtime/regswap2.s +++ b/libsrc/runtime/regswap2.s @@ -13,20 +13,20 @@ lda regbank,x ; Get old value pha ; Save it - lda (c_sp),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank,x ; Store new value pla - sta (c_sp),y ; Store old value + sta (c_sp),y ; Store old value ; Second byte iny lda regbank+1,x ; Get old value pha ; Save it - lda (c_sp),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank+1,x ; Store new value pla - sta (c_sp),y ; Store old value + sta (c_sp),y ; Store old value rts diff --git a/libsrc/runtime/rsub.s b/libsrc/runtime/rsub.s index c91b983dd..bacb3c7fc 100644 --- a/libsrc/runtime/rsub.s +++ b/libsrc/runtime/rsub.s @@ -24,12 +24,12 @@ tosrsubax: ldy #1 .else ldy #0 - sbc (c_sp),y ; lo byte + sbc (c_sp),y ; lo byte iny .endif sta tmp1 ; save lo byte txa - sbc (c_sp),y ; hi byte + sbc (c_sp),y ; hi byte tax lda tmp1 jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/sub.s b/libsrc/runtime/sub.s index 07e7dc5e3..58ffb4c91 100644 --- a/libsrc/runtime/sub.s +++ b/libsrc/runtime/sub.s @@ -22,13 +22,13 @@ tossubax: ldy #1 .else ldy #0 - adc (c_sp),y ; Subtract low byte + adc (c_sp),y ; Subtract low byte iny .endif pha ; Save high byte txa eor #$FF - adc (c_sp),y ; Subtract high byte + adc (c_sp),y ; Subtract high byte tax ; High byte into X pla ; Restore low byte jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/tosint.s b/libsrc/runtime/tosint.s index b924a53e3..2aaa19ccc 100644 --- a/libsrc/runtime/tosint.s +++ b/libsrc/runtime/tosint.s @@ -19,7 +19,7 @@ lda (c_sp) .else ldy #0 - lda (c_sp),y ; c_sp+1 + lda (c_sp),y ; c_sp+1 .endif ldy #2 sta (c_sp),y diff --git a/libsrc/runtime/toslong.s b/libsrc/runtime/toslong.s index 8e417367f..cf8eff031 100644 --- a/libsrc/runtime/toslong.s +++ b/libsrc/runtime/toslong.s @@ -18,7 +18,7 @@ tosulong: ldy #2 lda (c_sp),y .if (.cpu .bitand CPU_ISET_65SC02) - sta (c_sp) ; 65C02 version + sta (c_sp) ; 65C02 version iny ; Y = 3 .else ldy #0 @@ -44,7 +44,7 @@ toslong: ldy #2 lda (c_sp),y .if (.cpu .bitand CPU_ISET_65SC02) - sta (c_sp) ; 65C02 version + sta (c_sp) ; 65C02 version iny ; Y = 3 .else ldy #0 diff --git a/libsrc/runtime/zeropage.s b/libsrc/runtime/zeropage.s index 73b25bf0a..75856f751 100644 --- a/libsrc/runtime/zeropage.s +++ b/libsrc/runtime/zeropage.s @@ -10,7 +10,7 @@ .zeropage -c_sp: .res 2 ; Stack pointer +c_sp: .res 2 ; Stack pointer sreg: .res 2 ; Secondary register/high 16 bit for longs regsave: .res 4 ; Slot to save/restore (E)AX into ptr1: .res 2 diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s index 0a0e4bb26..224b2af2d 100644 --- a/libsrc/sim6502/exehdr.s +++ b/libsrc/sim6502/exehdr.s @@ -24,6 +24,6 @@ .else .error Unknown CPU type. .endif - .byte c_sp ; c_sp address + .byte c_sp ; c_sp address .addr __MAIN_START__ ; load address .addr startup ; reset address diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index 931ec8be8..1cfba1845 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -34,7 +34,7 @@ reset: lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) ldx #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) sta c_sp - stx c_sp+1 ; Set argument stack ptr + stx c_sp+1 ; Set argument stack ptr jsr initlib jsr _main _exit: jsr donelib diff --git a/libsrc/telestrat/crt0.s b/libsrc/telestrat/crt0.s index 430c4f8c8..aa32ed0d0 100644 --- a/libsrc/telestrat/crt0.s +++ b/libsrc/telestrat/crt0.s @@ -75,7 +75,7 @@ L1: lda c_sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) sta c_sp - stx c_sp+1 ; Set argument stack ptr + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/vic20/crt0.s b/libsrc/vic20/crt0.s index 64ccf6085..189114f5d 100644 --- a/libsrc/vic20/crt0.s +++ b/libsrc/vic20/crt0.s @@ -46,7 +46,7 @@ L1: lda c_sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) sta c_sp - stx c_sp+1 ; Set argument stack ptr + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. From 034fc93c75ec0f721293a8cb3231c9ddda287537 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 23 Jun 2025 13:23:23 +0200 Subject: [PATCH 580/707] enable 4510/45GS02 in the compiler - however, the resulting asm files cant be assembled because of sp vs c_sp clash --- libsrc/Makefile | 4 ++-- src/cc65/main.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index 970ae6972..9bbb0aadb 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -197,9 +197,9 @@ ifeq ($(TARGET),$(filter $(TARGET),$(GEOS))) endif ifeq ($(TARGET),c65) -# FIXME: the compiler does not work for 4510 yet +# FIXME: this does not work because of the SP vs C_SP clash else ifeq ($(TARGET),mega65) -# FIXME: the compiler does not work for 45GS02 yet +# FIXME: this does not work because of the SP vs C_SP clash else SRCDIRS += common \ conio \ diff --git a/src/cc65/main.c b/src/cc65/main.c index abed6acae..648c603cd 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -348,7 +348,6 @@ static void DefineCpuMacros (void) 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); @@ -382,6 +381,14 @@ static void DefineCpuMacros (void) DefineNumericMacro ("__CPU_HUC6280__", 1); break; + case CPU_4510: + DefineNumericMacro ("__CPU_4510__", 1); + break; + + case CPU_45GS02: + DefineNumericMacro ("__CPU_45GS02__", 1); + break; + default: FAIL ("Unexpected value in switch"); break; @@ -397,6 +404,8 @@ static void DefineCpuMacros (void) DefineNumericMacro ("__CPU_ISET_65C02__", CPU_ISET_65C02); DefineNumericMacro ("__CPU_ISET_65816__", CPU_ISET_65816); DefineNumericMacro ("__CPU_ISET_HUC6280__", CPU_ISET_HUC6280); + DefineNumericMacro ("__CPU_ISET_4510__", CPU_ISET_4510); + DefineNumericMacro ("__CPU_ISET_45GS02__", CPU_ISET_45GS02); /* Now define the macro that contains the bit set with the available ** cpu instructions. From 49713f73e0ea0498840bc18aa06acd41bf06bdb5 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Fri, 20 Jun 2025 08:13:12 +0200 Subject: [PATCH 581/707] Output relative branch targets as "*-30" instead of "* + (-30)". --- src/da65/handler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index db55b4058..c119206ad 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -518,11 +518,11 @@ void OH_Relative (const OpcDesc* D) GenerateLabel (D->Flags, Addr); /* Output the line */ - if (HaveLabel(Addr)) { + if (HaveLabel (Addr)) { OneLine (D, "%s", GetAddrArg (D->Flags, Addr)); } else { /* No label -- make a relative address expression */ - OneLine (D, "* + (%d)", (int) Offs + 2); + OneLine (D, "*%+d", (int) Offs + 2); } } From 96bb1e43367e49311b3df86f4b8c144b84924271 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:55:31 +0200 Subject: [PATCH 582/707] Fix coding style. --- src/da65/data.c | 10 +++++----- src/da65/handler.c | 2 +- src/da65/infofile.c | 8 ++++---- src/da65/main.c | 8 ++++---- src/da65/scanner.c | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/da65/data.c b/src/da65/data.c index a7389ca5a..c359e5684 100644 --- a/src/da65/data.c +++ b/src/da65/data.c @@ -63,7 +63,7 @@ static uint32_t GetSpan (attr_t Style) uint32_t Count = 1; while (Count < RemainingBytes) { attr_t Attr; - if (MustDefLabel(PC+Count)) { + if (MustDefLabel (PC+Count)) { break; } Attr = GetAttr (PC+Count); @@ -119,7 +119,7 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u } /* If the next line is not the same style, add a separator */ - if (CodeLeft() && GetStyleAttr (PC) != Style) { + if (CodeLeft () && GetStyleAttr (PC) != Style) { SeparatorLine (); } @@ -221,7 +221,7 @@ uint32_t AddrTable (void) } /* If the next line is not an address table line, add a separator */ - if (CodeLeft() && GetStyleAttr (PC) != atAddrTab) { + if (CodeLeft () && GetStyleAttr (PC) != atAddrTab) { SeparatorLine (); } @@ -287,7 +287,7 @@ uint32_t RtsTable (void) } /* If the next line is not a return address table line, add a separator */ - if (CodeLeft() && GetStyleAttr (PC) != atRtsTab) { + if (CodeLeft () && GetStyleAttr (PC) != atRtsTab) { SeparatorLine (); } @@ -366,7 +366,7 @@ uint32_t TextTable (void) } /* If the next line is not a byte table line, add a separator */ - if (CodeLeft() && GetStyleAttr (PC) != atTextTab) { + if (CodeLeft () && GetStyleAttr (PC) != atTextTab) { SeparatorLine (); } diff --git a/src/da65/handler.c b/src/da65/handler.c index c119206ad..1624e6fd4 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -962,7 +962,7 @@ void OH_Rts (const OpcDesc* D) if (NewlineAfterRTS) { LineFeed (); } - SeparatorLine(); + SeparatorLine (); } diff --git a/src/da65/infofile.c b/src/da65/infofile.c index 67e7df1d9..bfbd3eb66 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -666,7 +666,7 @@ static void RangeSection (void) if (InfoSVal[1] == '\0') { InfoError ("AddrMode must be two characters long"); } - if (tolower(InfoSVal[0]) == 'm') { + if (tolower (InfoSVal[0]) == 'm') { if (InfoSVal[0] == 'm') { AddrMode = atMem16; } else { @@ -675,7 +675,7 @@ static void RangeSection (void) } else { InfoError ("AddrMode syntax: mx"); } - if (tolower(InfoSVal[1]) == 'x') { + if (tolower (InfoSVal[1]) == 'x') { if (InfoSVal[1] == 'x') { AddrMode |= atIdx16; } else { @@ -735,7 +735,7 @@ static void RangeSection (void) if (Attributes & tUnit) { unsigned i; for (i = Start; i < End; i += Unit) { - MarkAddr(i, atTableUnit); + MarkAddr (i, atTableUnit); } } @@ -928,7 +928,7 @@ void ReadInfoFile (void) /* Read the info file */ { /* Check if we have a info file given */ - if (InfoAvail()) { + if (InfoAvail ()) { /* Open the config file */ InfoOpenInput (); diff --git a/src/da65/main.c b/src/da65/main.c index 91eecd94f..a00bf588a 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -357,7 +357,7 @@ static void OptVersion (const char* Opt attribute ((unused)), /* Print the disassembler version */ { fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); - exit(EXIT_SUCCESS); + exit (EXIT_SUCCESS); } @@ -497,11 +497,11 @@ static void OneOpcode (unsigned RemainingBytes) if (PrevAddrMode != AddrMode) { if ((PrevAddrMode & atMem8) != (AddrMode & atMem8) || (PrevAddrMode & atMem16) != (AddrMode & atMem16)) { - OutputMFlag(!!(AddrMode & atMem8)); + OutputMFlag (!!(AddrMode & atMem8)); } if ((PrevAddrMode & atIdx8) != (AddrMode & atIdx8) || (PrevAddrMode & atIdx16) != (AddrMode & atIdx16)) { - OutputXFlag(!!(AddrMode & atIdx8)); + OutputXFlag (!!(AddrMode & atIdx8)); } PrevAddrMode = AddrMode; @@ -580,7 +580,7 @@ static void OnePass (void) PrevAddrMode = 0; /* Disassemble until nothing left */ - while ((Count = GetRemainingBytes()) > 0) { + while ((Count = GetRemainingBytes ()) > 0) { OneOpcode (Count); } } diff --git a/src/da65/scanner.c b/src/da65/scanner.c index 66940dfb6..22319aba3 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -671,8 +671,8 @@ void InfoSetName (const char* Name) /* Set a name for a config file */ { InfoFile = Name; - xfree(InputSrcName); - InputSrcName = xstrdup(Name); + xfree (InputSrcName); + InputSrcName = xstrdup (Name); } From 4c81eacefebc6e53903abc80d211b1c1b0f18c7a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:00:12 +0200 Subject: [PATCH 583/707] Added -d/--debug and -m/--multi-pass switches to the disassembler. The latter will make the disassembler run multiple preparation passes to find all addresses where labels must be placed. Without -m some label addresses are found in the final pass, where the disassembler cannot make use of them. --- doc/da65.sgml | 21 ++++++++++++++- src/da65/global.c | 2 +- src/da65/global.h | 4 ++- src/da65/labels.c | 14 ++++++++++ src/da65/labels.h | 3 +++ src/da65/main.c | 68 ++++++++++++++++++++++++++++++++++++++++++++--- src/da65/output.c | 16 +++++------ 7 files changed, 113 insertions(+), 15 deletions(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index dd51a4764..314e552a9 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -46,14 +46,16 @@ The assembler accepts the following options: --------------------------------------------------------------------------- Usage: da65 [options] [inputfile] Short options: + -d Debug mode -g Add debug info to object file -h Help (this text) -i name Specify an info file + -m Run multiple passes to resolve labels -o name Name the output file -v Increase verbosity -F Add formfeeds to the output - -s Accept line markers in the info file -S addr Set the start/load address + -s Accept line markers in the info file -V Print the disassembler version Long options: @@ -61,6 +63,7 @@ Long options: --comment-column n Specify comment start column --comments n Set the comment level for the output --cpu type Set cpu type + --debug Debug mode --debug-info Add debug info to object file --formfeeds Add formfeeds to the output --help Help (this text) @@ -68,6 +71,7 @@ Long options: --info name Specify an info file --label-break n Add newline if label exceeds length n --mnemonic-column n Specify mnemonic start column + --multi-pass Run multiple passes to resolve labels --pagelength n Set the page length for the listing --start-addr addr Set the start/load address --sync-lines Accept line markers in the info file @@ -123,6 +127,12 @@ Here is a description of all the command line options: </itemize> + <tag><tt>-d, --debug</tt></tag> + + Enables debug mode, something that should not be needed for mere + mortals:-) + + <label id="option--formfeeds"> <tag><tt>-F, --formfeeds</tt></tag> @@ -179,6 +189,15 @@ Here is a description of all the command line options: <tt><ref id="LABELBREAK" name="LABELBREAK"></tt>. + <tag><tt>-m, --multi-pass</tt></tag> + + This option causes the disassembler to run multiple passes over the input + binary to find and create all necessary labels. Without this option the + disassembler may detect the necessity for a label in the final pass, when + output was already partially generated. It will output numerical addresses + or program counter relative expressions in this case. + + <label id="option--mnemonic-column"> <tag><tt>--mnemonic-column n</tt></tag> diff --git a/src/da65/global.c b/src/da65/global.c index 7e5cabf54..74f70b6fd 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -54,8 +54,8 @@ const char CfgExt[] = ".cfg"; /* Config file extension */ /* Flags and other command line stuff */ unsigned char DebugInfo = 0; /* Add debug info to the object file */ unsigned char FormFeeds = 0; /* Add form feeds to the output? */ +unsigned char MultiPass = 0; /* Run several passes to resolve labels */ unsigned char UseHexOffs = 0; /* Use hexadecimal label offsets */ -unsigned char PassCount = 2; /* How many passed do we do? */ signed char NewlineAfterJMP = -1; /* Add a newline after a JMP insn? */ signed char NewlineAfterRTS = -1; /* Add a newline after a RTS insn? */ unsigned char HaveStartAddr = 0; /* Flag for start address given */ diff --git a/src/da65/global.h b/src/da65/global.h index 2e558d6a9..8e3fe90ee 100644 --- a/src/da65/global.h +++ b/src/da65/global.h @@ -59,8 +59,8 @@ extern const char CfgExt[]; /* Config file extension */ /* Flags and other command line stuff */ extern unsigned char DebugInfo; /* Add debug info to the object file */ extern unsigned char FormFeeds; /* Add form feeds to the output? */ +extern unsigned char MultiPass; /* Run several passes to resolve labels */ extern unsigned char UseHexOffs; /* Use hexadecimal label offsets */ -extern unsigned char PassCount; /* How many passed do we do? */ extern signed char NewlineAfterJMP;/* Add a newline after a JMP insn? */ extern signed char NewlineAfterRTS;/* Add a newline after a RTS insn? */ extern unsigned char HaveStartAddr; /* Flag for start address given */ @@ -70,6 +70,8 @@ extern long InputOffs; /* Offset into input file */ extern long InputSize; /* Number of bytes to read from input */ /* Stuff needed by many routines */ +#define PASS_PREP 1 /* Preparation pass */ +#define PASS_FINAL 2 /* Final pass generating output */ extern unsigned Pass; /* Disassembler pass */ extern char Now[128]; /* Current time as string */ diff --git a/src/da65/labels.c b/src/da65/labels.c index 6f6bce3ed..a2c027705 100644 --- a/src/da65/labels.c +++ b/src/da65/labels.c @@ -74,6 +74,9 @@ struct Label { #define LABEL_HASH_SIZE 4096u /* Must be power of two */ static Label* LabelTab[LABEL_HASH_SIZE]; +/* Total number of labels */ +static unsigned long LabelCount = 0; + /*****************************************************************************/ @@ -187,6 +190,9 @@ static void AddLabel (uint32_t Addr, attr_t Attr, const char* Name) /* Remember the attribute */ MarkAddr (Addr, Attr); + + /* Count labels */ + ++LabelCount; } @@ -538,3 +544,11 @@ void DefOutOfRangeLabels (void) /* Free allocated storage */ DoneCollection (&Labels); } + + + +unsigned long GetLabelCount (void) +/* Return the total number of labels defined so far */ +{ + return LabelCount; +} diff --git a/src/da65/labels.h b/src/da65/labels.h index 37f2daeab..923a4bd43 100644 --- a/src/da65/labels.h +++ b/src/da65/labels.h @@ -100,6 +100,9 @@ void ForwardLabel (unsigned Offs); void DefOutOfRangeLabels (void); /* Output any labels that are out of the loaded code range */ +unsigned long GetLabelCount (void); +/* Return the total number of labels defined so far */ + /* End of labels.h */ diff --git a/src/da65/main.c b/src/da65/main.c index a00bf588a..03dbcaccf 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -42,8 +42,10 @@ /* common */ #include "abend.h" +#include "check.h" #include "cmdline.h" #include "cpu.h" +#include "debugflag.h" #include "fname.h" #include "print.h" #include "version.h" @@ -79,9 +81,11 @@ static void Usage (void) { printf ("Usage: %s [options] [inputfile]\n" "Short options:\n" + " -d\t\t\tDebug mode\n" " -g\t\t\tAdd debug info to object file\n" " -h\t\t\tHelp (this text)\n" " -i name\t\tSpecify an info file\n" + " -m\t\t\tRun multiple passes to resolve labels\n" " -o name\t\tName the output file\n" " -v\t\t\tIncrease verbosity\n" " -F\t\t\tAdd formfeeds to the output\n" @@ -94,6 +98,7 @@ static void Usage (void) " --comment-column n\tSpecify comment start column\n" " --comments n\t\tSet the comment level for the output\n" " --cpu type\t\tSet cpu type\n" + " --debug\t\tDebug mode\n" " --debug-info\t\tAdd debug info to object file\n" " --formfeeds\t\tAdd formfeeds to the output\n" " --help\t\tHelp (this text)\n" @@ -101,6 +106,7 @@ static void Usage (void) " --info name\t\tSpecify an info file\n" " --label-break n\tAdd newline if label exceeds length n\n" " --mnemonic-column n\tSpecify mnemonic start column\n" + " --multi-pass\t\tRun multiple passes to resolve labels\n" " --pagelength n\tSet the page length for the listing\n" " --start-addr addr\tSet the start/load address\n" " --sync-lines\t\tAccept line markers in the info file\n" @@ -223,6 +229,15 @@ static void OptCPU (const char* Opt attribute ((unused)), const char* Arg) +static void OptDebug (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Disassembler debug mode */ +{ + ++Debug; +} + + + static void OptDebugInfo (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Add debug info to the object file */ @@ -298,6 +313,15 @@ static void OptMnemonicColumn (const char* Opt, const char* Arg) +static void OptMultiPass (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Handle the --multi-pass option */ +{ + MultiPass = 1; +} + + + static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg) /* Handle the --pagelength option */ { @@ -590,15 +614,37 @@ static void OnePass (void) static void Disassemble (void) /* Disassemble the code */ { - /* Pass 1 */ - Pass = 1; + /* Preparation pass */ + Pass = PASS_PREP; OnePass (); + /* If the --multi-pass option is given, repeat this pass until we have no + ** new labels. + */ + if (MultiPass) { + unsigned long LabelCount = GetLabelCount (); + unsigned Passes = 1; + while (1) { + unsigned long NewLabelCount; + ResetCode (); + OnePass (); + CHECK(++Passes <= 4096); /* Safety measure */ + NewLabelCount = GetLabelCount (); + if (NewLabelCount <= LabelCount) { + break; + } + LabelCount = NewLabelCount; + } + if (Debug) { + printf ("Run %u preparation passes to resolve labels\n", Passes); + } + } + Output ("---------------------------"); LineFeed (); - /* Pass 2 */ - Pass = 2; + /* Final pass */ + Pass = PASS_FINAL; ResetCode (); OutputSettings (); DefOutOfRangeLabels (); @@ -617,6 +663,7 @@ int main (int argc, char* argv []) { "--comment-column", 1, OptCommentColumn }, { "--comments", 1, OptComments }, { "--cpu", 1, OptCPU }, + { "--debug", 0, OptDebug }, { "--debug-info", 0, OptDebugInfo }, { "--formfeeds", 0, OptFormFeeds }, { "--help", 0, OptHelp }, @@ -624,6 +671,7 @@ int main (int argc, char* argv []) { "--info", 1, OptInfo }, { "--label-break", 1, OptLabelBreak }, { "--mnemonic-column", 1, OptMnemonicColumn }, + { "--multi-pass", 0, OptMultiPass }, { "--pagelength", 1, OptPageLength }, { "--start-addr", 1, OptStartAddr }, { "--sync-lines", 0, OptSyncLines }, @@ -653,6 +701,14 @@ int main (int argc, char* argv []) LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0])); break; + case 'd': + if (Arg[2] == '\0') { + OptDebug (Arg, 0); + } else { + UnknownOption (Arg); + } + break; + case 'g': OptDebugInfo (Arg, 0); break; @@ -665,6 +721,10 @@ int main (int argc, char* argv []) OptInfo (Arg, GetArg (&I, 2)); break; + case 'm': + OptMultiPass (Arg, 0); + break; + case 'o': OutFile = GetArg (&I, 2); break; diff --git a/src/da65/output.c b/src/da65/output.c index bc5f7d5c2..13cb3e127 100644 --- a/src/da65/output.c +++ b/src/da65/output.c @@ -124,7 +124,7 @@ void CloseOutput (void) void Output (const char* Format, ...) /* Write to the output file */ { - if (Pass == PassCount) { + if (Pass == PASS_FINAL) { va_list ap; va_start (ap, Format); Col += vfprintf (F, Format, ap); @@ -137,7 +137,7 @@ void Output (const char* Format, ...) void Indent (unsigned N) /* Make sure the current line column is at position N (zero based) */ { - if (Pass == PassCount) { + if (Pass == PASS_FINAL) { while (Col < N) { fputc (' ', F); ++Col; @@ -150,7 +150,7 @@ void Indent (unsigned N) void LineFeed (void) /* Add a linefeed to the output file */ { - if (Pass == PassCount) { + if (Pass == PASS_FINAL) { fputc ('\n', F); if (PageLength > 0 && ++Line >= PageLength) { if (FormFeeds) { @@ -185,7 +185,7 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs) ** current PC. */ { - if (Pass == PassCount) { + if (Pass == PASS_FINAL) { /* Flush existing output if necessary */ if (Col > 1) { LineFeed (); @@ -212,7 +212,7 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs) void DefConst (const char* Name, const char* Comment, uint32_t Addr) /* Define an address constant */ { - if (Pass == PassCount) { + if (Pass == PASS_FINAL) { Output ("%s", Name); Indent (ACol); Output (":= $%04" PRIX32, Addr); @@ -313,7 +313,7 @@ void DataDWordLine (uint32_t ByteCount) void SeparatorLine (void) /* Print a separator line */ { - if (Pass == PassCount && Comments >= 1) { + if (Pass == PASS_FINAL && Comments >= 1) { Output ("; ----------------------------------------------------------------------------"); LineFeed (); } @@ -324,7 +324,7 @@ void SeparatorLine (void) void StartSegment (const char* Name, unsigned AddrSize) /* Start a segment */ { - if (Pass == PassCount) { + if (Pass == PASS_FINAL) { LineFeed (); Output (".segment"); Indent (ACol); @@ -368,7 +368,7 @@ void LineComment (unsigned PC, unsigned Count) { unsigned I; - if (Pass == PassCount && Comments >= 2) { + if (Pass == PASS_FINAL && Comments >= 2) { Indent (CCol); Output ("; %04X", PC); if (Comments >= 3) { From 5fc15a7a60f16c239c01663be52c48fb20ad1e4f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 23 Jun 2025 17:09:06 +0200 Subject: [PATCH 584/707] test #2674 --- asminc/zeropage.inc | 2 +- doc/atari.sgml | 2 +- doc/ca65.sgml | 6 +- doc/cc65-intern.sgml | 12 +- doc/customizing.sgml | 4 +- doc/sim65.sgml | 2 +- libsrc/agat/crt0.s | 8 +- libsrc/apple2/callmain.s | 2 +- libsrc/apple2/crt0.s | 6 +- libsrc/apple2/exec.s | 4 +- libsrc/apple2/filename.s | 14 +- libsrc/apple2/mli_file_info_direct.s | 4 +- libsrc/apple2/mou/a2.stdmou.s | 4 +- libsrc/apple2/open.s | 4 +- libsrc/apple2/syschdir.s | 4 +- libsrc/apple2/sysmkdir.s | 4 +- libsrc/apple2/sysremove.s | 4 +- libsrc/apple2/sysrename.s | 8 +- libsrc/atari/crt0.s | 8 +- libsrc/atari/diopncls.s | 8 +- libsrc/atari/fdtable.s | 4 +- libsrc/atari/mcbpm.s | 14 +- libsrc/atari/mou/atrjoy.s | 4 +- libsrc/atari/mou/atrst.s | 4 +- libsrc/atari/mou/atrtt.s | 4 +- libsrc/atari/sysrename.s | 22 ++-- libsrc/atari/ucase_fn.s | 12 +- libsrc/atari2600/crt0.s | 4 +- libsrc/atari5200/crt0.s | 4 +- libsrc/atari7800/crt0.s | 4 +- libsrc/atari7800/mono_setcursor.s | 2 +- libsrc/atari7800/setcursor.s | 2 +- libsrc/atmos/crt0.s | 8 +- libsrc/c128/crt0.s | 8 +- libsrc/c128/mou/c128-1351.s | 4 +- libsrc/c128/mou/c128-inkwell.s | 4 +- libsrc/c128/mou/c128-joy.s | 4 +- libsrc/c128/mou/c128-pot.s | 4 +- libsrc/c16/crt0.s | 8 +- libsrc/c64/crt0.s | 8 +- libsrc/c64/mou/c64-1351.s | 4 +- libsrc/c64/mou/c64-inkwell.s | 4 +- libsrc/c64/mou/c64-joy.s | 4 +- libsrc/c64/mou/c64-pot.s | 4 +- libsrc/cbm/dir.s | 8 +- libsrc/cbm/open.s | 2 +- libsrc/cbm/write.s | 2 +- libsrc/cbm510/crt0.s | 12 +- libsrc/cbm510/mou/cbm510-inkwl.s | 4 +- libsrc/cbm510/mou/cbm510-joy.s | 4 +- libsrc/cbm610/crt0.s | 12 +- libsrc/common/_fopen.s | 10 +- libsrc/common/_heap.s | 6 +- libsrc/common/_idiv32by16r16.s | 8 +- libsrc/common/_printf.s | 14 +- libsrc/common/_udiv32by16r16.s | 8 +- libsrc/common/fprintf.s | 8 +- libsrc/common/fread.s | 14 +- libsrc/common/fscanf.s | 8 +- libsrc/common/interrupt.s | 4 +- libsrc/common/itoa.s | 10 +- libsrc/common/longjmp.s | 6 +- libsrc/common/lz4.s | 2 +- libsrc/common/memcpy.s | 6 +- libsrc/common/memset.s | 6 +- libsrc/common/printf.s | 6 +- libsrc/common/realloc.s | 2 +- libsrc/common/scanf.s | 6 +- libsrc/common/setjmp.s | 6 +- libsrc/common/snprintf.s | 8 +- libsrc/common/sprintf.s | 8 +- libsrc/common/sscanf.s | 8 +- libsrc/common/vfprintf.s | 10 +- libsrc/common/vfscanf.s | 8 +- libsrc/common/vprintf.s | 14 +- libsrc/common/vscanf.s | 12 +- libsrc/common/vsnprintf.s | 14 +- libsrc/common/vsscanf.s | 10 +- libsrc/conio/cprintf.s | 6 +- libsrc/conio/cscanf.s | 4 +- libsrc/conio/vcprintf.s | 10 +- libsrc/creativision/crt0.s | 4 +- libsrc/cx16/crt0.s | 4 +- libsrc/cx16/mou/cx16-std.s | 4 +- libsrc/dbg/dbgdump.s | 12 +- libsrc/dbg/dbgsupp.s | 8 +- libsrc/gamate/crt0.s | 4 +- libsrc/geos-common/drivers/geos-stdmou.s | 12 +- libsrc/geos-common/system/crt0.s | 6 +- libsrc/kim1/crt0.s | 4 +- libsrc/lynx/crt0.s | 4 +- libsrc/lynx/lseek.s | 2 +- libsrc/nes/crt0.s | 4 +- libsrc/none/crt0.s | 4 +- libsrc/osic1p/crt0.s | 4 +- libsrc/pce/_printf.s | 12 +- libsrc/pce/crt0.s | 6 +- libsrc/pce/memcpy.s | 6 +- libsrc/pet/crt0.s | 8 +- libsrc/plus4/crt0.s | 8 +- libsrc/rp6502/crt0.s | 4 +- libsrc/rp6502/ria.s | 2 +- libsrc/rp6502/xreg.s | 6 +- libsrc/runtime/add.s | 24 ++-- libsrc/runtime/addeqsp.s | 10 +- libsrc/runtime/addysp.s | 8 +- libsrc/runtime/and.s | 8 +- libsrc/runtime/bpushbsp.s | 4 +- libsrc/runtime/decsp1.s | 8 +- libsrc/runtime/decsp2.s | 8 +- libsrc/runtime/decsp3.s | 8 +- libsrc/runtime/decsp4.s | 8 +- libsrc/runtime/decsp5.s | 8 +- libsrc/runtime/decsp6.s | 8 +- libsrc/runtime/decsp7.s | 8 +- libsrc/runtime/decsp8.s | 8 +- libsrc/runtime/enter.s | 10 +- libsrc/runtime/eq.s | 2 +- libsrc/runtime/icmp.s | 14 +- libsrc/runtime/incsp1.s | 6 +- libsrc/runtime/incsp2.s | 16 +-- libsrc/runtime/ladd.s | 12 +- libsrc/runtime/laddeqsp.s | 18 +-- libsrc/runtime/land.s | 12 +- libsrc/runtime/lcmp.s | 10 +- libsrc/runtime/ldau0sp.s | 6 +- libsrc/runtime/ldauisp.s | 6 +- libsrc/runtime/ldaxsp.s | 6 +- libsrc/runtime/ldeaxysp.s | 10 +- libsrc/runtime/leaaxsp.s | 6 +- libsrc/runtime/leave.s | 18 +-- libsrc/runtime/lmul.s | 12 +- libsrc/runtime/lor.s | 12 +- libsrc/runtime/lpop.s | 12 +- libsrc/runtime/lpush.s | 12 +- libsrc/runtime/lrsub.s | 12 +- libsrc/runtime/lsub.s | 12 +- libsrc/runtime/lsubeqsp.s | 18 +-- libsrc/runtime/ludiv.s | 12 +- libsrc/runtime/lxor.s | 12 +- libsrc/runtime/or.s | 8 +- libsrc/runtime/popa.s | 10 +- libsrc/runtime/popptr1.s | 8 +- libsrc/runtime/popsreg.s | 8 +- libsrc/runtime/pusha.s | 16 +-- libsrc/runtime/pushax.s | 14 +- libsrc/runtime/pushbsp.s | 4 +- libsrc/runtime/pushlysp.s | 10 +- libsrc/runtime/pushwsp.s | 16 +-- libsrc/runtime/regswap.s | 6 +- libsrc/runtime/regswap1.s | 6 +- libsrc/runtime/regswap2.s | 10 +- libsrc/runtime/rsub.s | 8 +- libsrc/runtime/staspidx.s | 6 +- libsrc/runtime/staxsp.s | 8 +- libsrc/runtime/staxspi.s | 8 +- libsrc/runtime/steaxsp.s | 12 +- libsrc/runtime/stkchk.s | 14 +- libsrc/runtime/sub.s | 8 +- libsrc/runtime/subeqsp.s | 10 +- libsrc/runtime/subysp.s | 8 +- libsrc/runtime/swap.s | 14 +- libsrc/runtime/tosint.s | 12 +- libsrc/runtime/toslong.s | 26 ++-- libsrc/runtime/xor.s | 8 +- libsrc/runtime/zeropage.s | 2 +- libsrc/sim6502/crt0.s | 4 +- libsrc/sim6502/exehdr.s | 4 +- libsrc/supervision/crt0.s | 4 +- libsrc/sym1/crt0.s | 4 +- libsrc/telestrat/crt0.s | 8 +- libsrc/telestrat/open.s | 2 +- libsrc/telestrat/wherex.s | 2 +- libsrc/tgi/tgi_outtextxy.s | 10 +- libsrc/vic20/crt0.s | 8 +- libsrc/zlib/inflatemem.s | 10 +- samples/getsp.s | 6 +- samples/tinyshell.c | 12 +- src/cc65/codegen.c | 155 ++++++++++++----------- src/cc65/codeinfo.c | 4 +- src/cc65/codeinfo.h | 6 +- src/cc65/codeopt.c | 2 +- src/cc65/codeoptutil.c | 22 ++-- src/cc65/coptadd.c | 60 ++++----- src/cc65/coptadd.h | 20 +-- src/cc65/coptbool.c | 12 +- src/cc65/coptcmp.c | 16 +-- src/cc65/coptcmp.h | 4 +- src/cc65/coptmisc.c | 22 ++-- src/cc65/coptptrload.c | 10 +- src/cc65/coptptrload.h | 8 +- src/cc65/coptptrstore.c | 12 +- src/cc65/coptptrstore.h | 10 +- src/cc65/coptstop.c | 6 +- src/cc65/coptstore.c | 2 +- src/cc65/locals.c | 2 +- src/cc65/stdfunc.c | 34 ++--- src/dbginfo/dbgsh.c | 2 +- src/sim65/main.c | 2 +- targettest/atari/mem.c | 2 +- targettest/ft.c | 12 +- targettest/getsp.s | 6 +- test/val/bug1652-optimizer.c | 8 +- test/val/cq85.c | 2 +- 204 files changed, 915 insertions(+), 912 deletions(-) diff --git a/asminc/zeropage.inc b/asminc/zeropage.inc index 6627d86b6..5285779ba 100644 --- a/asminc/zeropage.inc +++ b/asminc/zeropage.inc @@ -8,7 +8,7 @@ ; by the compiler, ready for usage in asm code. - .globalzp sp, sreg, regsave + .globalzp c_sp, sreg, regsave .globalzp ptr1, ptr2, ptr3, ptr4 .globalzp tmp1, tmp2, tmp3, tmp4 .globalzp regbank diff --git a/doc/atari.sgml b/doc/atari.sgml index 060bc8ad4..1a83d74fb 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -1121,7 +1121,7 @@ If BSS and/or the stack shouldn't stay at the end of the program, some parts of the cc65 runtime lib need to be replaced/modified. common/_heap.s defines the location of the heap and atari/crt0.s -defines the location of the stack by initializing sp. +defines the location of the stack by initializing c_sp. <sect1>Upgrading from an older cc65 version<p> diff --git a/doc/ca65.sgml b/doc/ca65.sgml index d2506d958..7b36abec5 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -5016,17 +5016,17 @@ bit. Using <tscreen><verb> .if (.cpu .bitand CPU_ISET_65SC02) - lda (sp) + lda (c_sp) .else ldy #$00 - lda (sp),y + lda (c_sp),y .endif </verb></tscreen> it is possible to determine if the <tscreen><verb> - lda (sp) + lda (c_sp) </verb></tscreen> instruction is supported, which is the case for the 65SC02, 65C02 and 65816 diff --git a/doc/cc65-intern.sgml b/doc/cc65-intern.sgml index 904cee070..9c59cd79a 100644 --- a/doc/cc65-intern.sgml +++ b/doc/cc65-intern.sgml @@ -131,7 +131,7 @@ All other parameters will be pushed to the C-stack from left to right. The rightmost parameter will have the lowest address on the stack, and multi-byte parameters will have their least significant byte at the lower address. -The <tt/sp/ pseudo-register is a zeropage pointer to the base of the C-stack. +The <tt/c_sp/ pseudo-register is a zeropage pointer to the base of the C-stack. If the function is variadic, the <tt/Y/ register will contain the number of bytes pushed to the stack for this function. @@ -153,10 +153,10 @@ void cdecl foo(unsigned bar, unsigned char baz); ; Example code for accessing bar. The variable is in A/X after this code snippet: ; ldy #2 ; Offset of high byte of bar - lda (sp),y ; High byte now in A + lda (c_sp),y ; High byte now in A tax ; High byte now in X dey ; Offset of low byte of bar - lda (sp),y ; Low byte now in A + lda (c_sp),y ; Low byte now in A </verb></tscreen> <sect1>Epilogue, after the function call<p> @@ -175,12 +175,12 @@ used if the return type is 32-bit. If the function has a void return type, the compiler will not depend on the result of <tt>A/X/sreg</tt>, so these may be clobbered by the function. -The C-stack pointer <tt/sp/ must be restored by the function to its value before the +The C-stack pointer <tt/c_sp/ must be restored by the function to its value before the function call prologue. It may pop all of its parameters from the C-stack (e.g. using the <tt/runtime/ function <tt/popa/), -or it could adjust <tt/sp/ directly. +or it could adjust <tt/c_sp/ directly. If the function is variadic, the <tt/Y/ register contains the number of bytes -pushed to the stack on entry, which may be added to <tt/sp/ to restore its +pushed to the stack on entry, which may be added to <tt/c_sp/ to restore its original state. The internal pseudo-register <tt/regbank/ must not be changed by the function. diff --git a/doc/customizing.sgml b/doc/customizing.sgml index 58631eb3c..ffca0ce58 100644 --- a/doc/customizing.sgml +++ b/doc/customizing.sgml @@ -193,9 +193,9 @@ _init: LDX #$FF ; Initialize stack pointer to $01FF ; Set cc65 argument stack pointer LDA #<(__RAM_START__ + __RAM_SIZE__) - STA sp + STA c_sp LDA #>(__RAM_START__ + __RAM_SIZE__) - STA sp+1 + STA c_sp+1 ; --------------------------------------------------------------------------- ; Initialize memory storage diff --git a/doc/sim65.sgml b/doc/sim65.sgml index 9c3764e1d..46ef961cb 100644 --- a/doc/sim65.sgml +++ b/doc/sim65.sgml @@ -209,7 +209,7 @@ Internally, the binary program file has a 12 byte header provided by the library <item>1 byte <bf/CPU type/: <tt/0/ = 6502, <tt/1/ = 65C02 -<item>1 byte <bf/sp address/: the zero page address of the C parameter stack pointer <tt/sp/ used by the paravirtualization functions +<item>1 byte <bf/c_sp address/: the zero page address of the C parameter stack pointer <tt/c_sp/ used by the paravirtualization functions <item>1 word <bf/load address/: where to load the data from the file into memory (default: <tt/$0200/) diff --git a/libsrc/agat/crt0.s b/libsrc/agat/crt0.s index 41f03b24d..eaca89308 100644 --- a/libsrc/agat/crt0.s +++ b/libsrc/agat/crt0.s @@ -31,7 +31,7 @@ exit: bpl :- ldx #zpspace-1 : lda zpsave,x - sta sp,x + sta c_sp,x dex bpl :- ldx #$FF @@ -44,7 +44,7 @@ exit: init: ldx #zpspace-1 -: lda sp,x +: lda c_sp,x sta zpsave,x dex bpl :- @@ -57,8 +57,8 @@ init: lda HIMEM ldx HIMEM+1 - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 ldx #<_exit lda #>_exit jsr reset diff --git a/libsrc/apple2/callmain.s b/libsrc/apple2/callmain.s index 71a8b5611..c43e339aa 100644 --- a/libsrc/apple2/callmain.s +++ b/libsrc/apple2/callmain.s @@ -54,7 +54,7 @@ exit: ldx #$02 ; Copy back the zero-page stuff. ldx #zpspace-1 : lda zpsave,x - sta sp,x + sta c_sp,x dex bpl :- diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index ce14cc1e3..47ac70a7e 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -43,7 +43,7 @@ ; Save the zero-page locations that we need. init: ldx #zpspace-1 -: lda sp,x +: lda c_sp,x sta zpsave,x dex bpl :- @@ -82,8 +82,8 @@ basic: lda HIMEM ldx HIMEM+1 ; Set up the C stack. -: sta sp - stx sp+1 +: sta c_sp + stx c_sp+1 ; ProDOS TechRefMan, chapter 5.3.5: ; "Your system program should place in the RESET vector the diff --git a/libsrc/apple2/exec.s b/libsrc/apple2/exec.s index 4e5e77a6e..38f31ee37 100644 --- a/libsrc/apple2/exec.s +++ b/libsrc/apple2/exec.s @@ -42,9 +42,9 @@ _exec: ; binary programs so we should do the same too in any case ; especially as _we_ rely on it in mainargs.s for argv[0] ldy #$00 - lda (sp),y + lda (c_sp),y tay -: lda (sp),y +: lda (c_sp),y sta $0280,y dey bpl :- diff --git a/libsrc/apple2/filename.s b/libsrc/apple2/filename.s index 0d4b6bedd..f4723ee1f 100644 --- a/libsrc/apple2/filename.s +++ b/libsrc/apple2/filename.s @@ -34,8 +34,8 @@ pushname: sta mliparam + MLI::ON_LINE::UNIT_NUM ; Use allocated pathname buffer - lda sp - ldx sp+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::ON_LINE::DATA_BUFFER stx mliparam + MLI::ON_LINE::DATA_BUFFER+1 @@ -46,16 +46,16 @@ pushname: bcs addsp65 ; Get volume name length - lda (sp),y + lda (c_sp),y and #15 ; Max volume name length ; Bracket volume name with slashes to form prefix sta tmp1 lda #'/' - sta (sp),y + sta (c_sp),y ldy tmp1 iny ; Leading slash - sta (sp),y + sta (c_sp),y iny ; Trailing slash ; Adjust source pointer for copy @@ -69,7 +69,7 @@ pushname: ; Copy source to allocated pathname buffer copy: lda (ptr1),y - sta (sp),y + sta (c_sp),y beq setlen iny cpy #FILENAME_MAX @@ -86,7 +86,7 @@ addsp65:ldy #FILENAME_MAX setlen: tya jsr decsp1 ; Preserves A ldy #$00 - sta (sp),y + sta (c_sp),y ; Return success tya diff --git a/libsrc/apple2/mli_file_info_direct.s b/libsrc/apple2/mli_file_info_direct.s index c15ebc28f..7fdaa9edf 100644 --- a/libsrc/apple2/mli_file_info_direct.s +++ b/libsrc/apple2/mli_file_info_direct.s @@ -11,8 +11,8 @@ ; Returns with carry set on error, and sets errno mli_file_info_direct: ; Set pushed name - lda sp - ldx sp+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::INFO::PATHNAME stx mliparam + MLI::INFO::PATHNAME+1 diff --git a/libsrc/apple2/mou/a2.stdmou.s b/libsrc/apple2/mou/a2.stdmou.s index 9c2f96200..38cd7c957 100644 --- a/libsrc/apple2/mou/a2.stdmou.s +++ b/libsrc/apple2/mou/a2.stdmou.s @@ -341,10 +341,10 @@ MOVE: ldy #$00 ; Start at top of stack ; Set x - lda (sp),y + lda (c_sp),y iny sta pos1_lo,x - lda (sp),y + lda (c_sp),y sta pos1_hi,x ; Update cursor diff --git a/libsrc/apple2/open.s b/libsrc/apple2/open.s index 7ece7f18d..8f1df26df 100644 --- a/libsrc/apple2/open.s +++ b/libsrc/apple2/open.s @@ -101,8 +101,8 @@ found: tya bne oserr1 ; Set pushed name - lda sp - ldx sp+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::OPEN::PATHNAME stx mliparam + MLI::OPEN::PATHNAME+1 diff --git a/libsrc/apple2/syschdir.s b/libsrc/apple2/syschdir.s index b3f81e2a5..be78a91b9 100644 --- a/libsrc/apple2/syschdir.s +++ b/libsrc/apple2/syschdir.s @@ -17,8 +17,8 @@ __syschdir: bne oserr ; Set pushed name - lda sp - ldx sp+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::PREFIX::PATHNAME stx mliparam + MLI::PREFIX::PATHNAME+1 diff --git a/libsrc/apple2/sysmkdir.s b/libsrc/apple2/sysmkdir.s index 7759da260..e59421319 100644 --- a/libsrc/apple2/sysmkdir.s +++ b/libsrc/apple2/sysmkdir.s @@ -23,8 +23,8 @@ __sysmkdir: bne oserr ; Set pushed name - lda sp - ldx sp+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::CREATE::PATHNAME stx mliparam + MLI::CREATE::PATHNAME+1 diff --git a/libsrc/apple2/sysremove.s b/libsrc/apple2/sysremove.s index 08c4dff68..088407024 100644 --- a/libsrc/apple2/sysremove.s +++ b/libsrc/apple2/sysremove.s @@ -16,8 +16,8 @@ __sysremove: bne oserr ; Set pushed name - lda sp - ldx sp+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::DESTROY::PATHNAME stx mliparam + MLI::DESTROY::PATHNAME+1 diff --git a/libsrc/apple2/sysrename.s b/libsrc/apple2/sysrename.s index 0fe8dd7b1..3e380548f 100644 --- a/libsrc/apple2/sysrename.s +++ b/libsrc/apple2/sysrename.s @@ -22,8 +22,8 @@ __sysrename: bne oserr1 ; Save pushed oldname - lda sp - ldx sp+1 + lda c_sp + ldx c_sp+1 sta ptr3 stx ptr3+1 @@ -40,8 +40,8 @@ __sysrename: stx mliparam + MLI::RENAME::PATHNAME+1 ; Set pushed newname - lda sp - ldx sp+1 + lda c_sp + ldx c_sp+1 sta mliparam + MLI::RENAME::NEW_PATHNAME stx mliparam + MLI::RENAME::NEW_PATHNAME+1 diff --git a/libsrc/atari/crt0.s b/libsrc/atari/crt0.s index 50e3ca7b6..23c1f580c 100644 --- a/libsrc/atari/crt0.s +++ b/libsrc/atari/crt0.s @@ -59,8 +59,8 @@ start: lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 .else @@ -75,11 +75,11 @@ start: lda MEMTOP sbc #<__RESERVED_MEMORY__ sta APPMHI ; initialize our APPMHI value - sta sp ; set up runtime stack part 1 + sta c_sp ; set up runtime stack part 1 lda MEMTOP+1 sbc #>__RESERVED_MEMORY__ sta APPMHI+1 - sta sp+1 ; set up runtime stack part 2 + sta c_sp+1 ; set up runtime stack part 2 .endif diff --git a/libsrc/atari/diopncls.s b/libsrc/atari/diopncls.s index f40d6bba4..a5c145081 100644 --- a/libsrc/atari/diopncls.s +++ b/libsrc/atari/diopncls.s @@ -16,7 +16,7 @@ .export sectsizetab .import ___oserror, __sio_call, _dio_read .import pushax, addysp, subysp - .importzp ptr2, sp + .importzp ptr2, c_sp .include "atari.inc" @@ -78,10 +78,10 @@ _dio_open: ldy #128 jsr subysp ; allocate buffer on the stack - lda sp + lda c_sp pha - lda sp+1 - pha ; save sp (buffer address) on processor stack + lda c_sp+1 + pha ; save c_sp (buffer address) on processor stack lda ptr2 ldx ptr2+1 diff --git a/libsrc/atari/fdtable.s b/libsrc/atari/fdtable.s index fd9f5021b..d1d869387 100644 --- a/libsrc/atari/fdtable.s +++ b/libsrc/atari/fdtable.s @@ -6,7 +6,7 @@ .include "atari.inc" .include "fd.inc" - .importzp tmp1,tmp2,tmp3,ptr4,sp + .importzp tmp1,tmp2,tmp3,ptr4,c_sp .import fd_table,fd_index .import fdt_to_fdi .export clriocb @@ -229,7 +229,7 @@ freefnd:txa beq l2 l1: ldy #0 - lda (sp),y ; get device + lda (c_sp),y ; get device l2: sta fd_table+ft_dev,x ; set device lda #1 sta fd_table+ft_usa,x ; set usage counter diff --git a/libsrc/atari/mcbpm.s b/libsrc/atari/mcbpm.s index 9e6ccc2c5..bc36b6f99 100644 --- a/libsrc/atari/mcbpm.s +++ b/libsrc/atari/mcbpm.s @@ -8,7 +8,7 @@ ; .include "atari.inc" - .importzp sp + .importzp c_sp .export _mouse_pm_callbacks .constructor pm_init, 27 .destructor pm_down @@ -193,22 +193,22 @@ pm_init: .else -; use top of memory and lower sp accordingly - sta sp +; use top of memory and lower c_sp accordingly + sta c_sp sta MOUSE_PM_BASE - lda sp+1 + lda c_sp+1 and #7 ; offset within 2K cmp #3 + MOUSE_PM_RAW + 1 ; can we use it? bcc @decr ; no - lda sp+1 + lda c_sp+1 and #$F8 @set: adc #3 + MOUSE_PM_RAW - 1 ; CF is set, so adding MOUSE_PM_RAW + 3 sta MOUSE_PM_BASE+1 - sta sp+1 + sta c_sp+1 bne @cont ; jump always -@decr: lda sp+1 +@decr: lda c_sp+1 and #$F8 sbc #8 - 1 ; CF is clear, subtracts 8 bcs @set ; jump always diff --git a/libsrc/atari/mou/atrjoy.s b/libsrc/atari/mou/atrjoy.s index a93c7de13..f30d72050 100644 --- a/libsrc/atari/mou/atrjoy.s +++ b/libsrc/atari/mou/atrjoy.s @@ -241,11 +241,11 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (c_sp),y sta XPos+1 tax dey - lda (sp),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/atari/mou/atrst.s b/libsrc/atari/mou/atrst.s index 626b7a8f7..7f915cc36 100644 --- a/libsrc/atari/mou/atrst.s +++ b/libsrc/atari/mou/atrst.s @@ -399,12 +399,12 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (c_sp),y sta XPos+1 sta XPosWrk+1 tax dey - lda (sp),y + lda (c_sp),y sta XPos ; New X position sta XPosWrk jsr CMOVEX ; Move the cursor diff --git a/libsrc/atari/mou/atrtt.s b/libsrc/atari/mou/atrtt.s index f7c56e9f2..516565844 100644 --- a/libsrc/atari/mou/atrtt.s +++ b/libsrc/atari/mou/atrtt.s @@ -236,11 +236,11 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (c_sp),y sta XPos+1 tax dey - lda (sp),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/atari/sysrename.s b/libsrc/atari/sysrename.s index e526af5c8..b410ebcfd 100644 --- a/libsrc/atari/sysrename.s +++ b/libsrc/atari/sysrename.s @@ -6,7 +6,7 @@ .include "atari.inc" .import findfreeiocb - .importzp tmp4, sp, ptr2, ptr3 + .importzp tmp4, c_sp, ptr2, ptr3 .import incsp2, subysp, addysp, popax .ifdef UCASE_FILENAME .importzp tmp3 @@ -118,19 +118,19 @@ L1: jsr subysp ; make room on the stack ; copy old name ldy #0 con: lda (ptr3),y - sta (sp),y + sta (c_sp),y beq copyend iny bne con copyend:lda #$20 ; space - sta (sp),y + sta (c_sp),y iny tya ; get current offset (beyond old name) clc - adc sp + adc c_sp sta ptr3 - lda sp+1 + lda c_sp+1 adc #0 sta ptr3+1 ; ptr3 now contains pointer to space for new filename @@ -143,9 +143,9 @@ cnn: lda (ptr2),y bne cnn copend2:ldx tmp4 - lda sp + lda c_sp sta ICBAL,x - lda sp+1 + lda c_sp+1 sta ICBAH,x lda #RENAME sta ICCOM,x @@ -160,13 +160,13 @@ copend2:ldx tmp4 ; clean up stack - lda sp + lda c_sp clc adc sspc - sta sp - lda sp+1 + sta c_sp + lda c_sp+1 adc sspc+1 - sta sp+1 + sta c_sp+1 ; handle status diff --git a/libsrc/atari/ucase_fn.s b/libsrc/atari/ucase_fn.s index f7f03915d..534c6a21c 100644 --- a/libsrc/atari/ucase_fn.s +++ b/libsrc/atari/ucase_fn.s @@ -24,7 +24,7 @@ .importzp tmp2 .import __defdev .endif - .importzp tmp3,ptr4,sp + .importzp tmp3,ptr4,c_sp .import subysp,addysp .export ucase_fn @@ -63,13 +63,13 @@ hasdev: ldy #0 loop2: lda (ptr4),y - sta (sp),y + sta (c_sp),y beq copy_end bmi L1 ; Not lowercase (also, invalid, should reject) cmp #'a' bcc L1 ; Not lowercase and #$DF ; make upper case char, assume ASCII chars - sta (sp),y ; store back + sta (c_sp),y ; store back L1: iny bpl loop2 ; bpl: this way we only support a max. length of 127 @@ -93,15 +93,15 @@ copy_end: jsr subysp ; adjust stack pointer dey cpdev: lda __defdev,y - sta (sp),y ; insert device name, number and ':' + sta (c_sp),y ; insert device name, number and ':' dey bpl cpdev hasdev2: .endif ; leave A and X pointing to the modified filename - lda sp - ldx sp+1 + lda c_sp + ldx c_sp+1 clc ; indicate success rts diff --git a/libsrc/atari2600/crt0.s b/libsrc/atari2600/crt0.s index 4f09a0a5a..7b5b679b0 100644 --- a/libsrc/atari2600/crt0.s +++ b/libsrc/atari2600/crt0.s @@ -35,8 +35,8 @@ clearLoop: ; Initialize C stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) ldx #>(__RAM_START__ + __RAM_SIZE__) - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 ; Call main jsr _main diff --git a/libsrc/atari5200/crt0.s b/libsrc/atari5200/crt0.s index 8f6e02273..a72d7f9f6 100644 --- a/libsrc/atari5200/crt0.s +++ b/libsrc/atari5200/crt0.s @@ -27,8 +27,8 @@ start: lda #<(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__) ldx #>(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__) - sta sp - stx sp+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/atari7800/crt0.s b/libsrc/atari7800/crt0.s index e791179f3..dea351473 100644 --- a/libsrc/atari7800/crt0.s +++ b/libsrc/atari7800/crt0.s @@ -30,9 +30,9 @@ start: ; Set up parameter stack lda #<(__RAM3_START__ + __RAM3_SIZE__) - sta sp + sta c_sp lda #>(__RAM3_START__ + __RAM3_SIZE__) - sta sp+1 + sta c_sp+1 jsr copydata jsr zerobss diff --git a/libsrc/atari7800/mono_setcursor.s b/libsrc/atari7800/mono_setcursor.s index 02e0308f6..995f0d661 100644 --- a/libsrc/atari7800/mono_setcursor.s +++ b/libsrc/atari7800/mono_setcursor.s @@ -27,7 +27,7 @@ .constructor mono_init_cursor .interruptor mono_blink_cursor - .importzp sp + .importzp c_sp .import _zonecounter .import _mono_zones .import cursor diff --git a/libsrc/atari7800/setcursor.s b/libsrc/atari7800/setcursor.s index f438de24f..040732cff 100644 --- a/libsrc/atari7800/setcursor.s +++ b/libsrc/atari7800/setcursor.s @@ -27,7 +27,7 @@ .constructor init_cursor .interruptor blink_cursor - .importzp sp + .importzp c_sp .import _zonecounter .import _zones .import cursor diff --git a/libsrc/atmos/crt0.s b/libsrc/atmos/crt0.s index 8c2be656c..55c60dd30 100644 --- a/libsrc/atmos/crt0.s +++ b/libsrc/atmos/crt0.s @@ -51,7 +51,7 @@ _exit: jsr donelib ldx #zpspace - 1 L2: lda zpsave,x - sta sp,x + sta c_sp,x dex bpl L2 @@ -68,7 +68,7 @@ L2: lda zpsave,x ; Save the zero-page area that we're about to use. init: ldx #zpspace - 1 -L1: lda sp,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -85,8 +85,8 @@ L1: lda sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/c128/crt0.s b/libsrc/c128/crt0.s index ba6a78ac5..f6a55778c 100644 --- a/libsrc/c128/crt0.s +++ b/libsrc/c128/crt0.s @@ -39,7 +39,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda sp,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -58,8 +58,8 @@ L1: lda sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. @@ -85,7 +85,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta c_sp,x dex bpl L2 diff --git a/libsrc/c128/mou/c128-1351.s b/libsrc/c128/mou/c128-1351.s index 76e28d9f7..f6954c823 100644 --- a/libsrc/c128/mou/c128-1351.s +++ b/libsrc/c128/mou/c128-1351.s @@ -296,11 +296,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (c_sp),y sta XPos+1 tax dey - lda (sp),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c128/mou/c128-inkwell.s b/libsrc/c128/mou/c128-inkwell.s index 2aac7d32d..b86959788 100644 --- a/libsrc/c128/mou/c128-inkwell.s +++ b/libsrc/c128/mou/c128-inkwell.s @@ -323,10 +323,10 @@ MOVE: sei ; No interrupts jsr MoveY ldy #$01 - lda (sp),y + lda (c_sp),y tax dey - lda (sp),y + lda (c_sp),y jsr MoveX ; Move the cursor cli ; Allow interrupts diff --git a/libsrc/c128/mou/c128-joy.s b/libsrc/c128/mou/c128-joy.s index d809db526..26367f8df 100644 --- a/libsrc/c128/mou/c128-joy.s +++ b/libsrc/c128/mou/c128-joy.s @@ -297,11 +297,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (c_sp),y sta XPos+1 tax dey - lda (sp),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c128/mou/c128-pot.s b/libsrc/c128/mou/c128-pot.s index 1cbe4aa18..55de4ac12 100644 --- a/libsrc/c128/mou/c128-pot.s +++ b/libsrc/c128/mou/c128-pot.s @@ -297,11 +297,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (c_sp),y sta XPos+1 tax dey - lda (sp),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c16/crt0.s b/libsrc/c16/crt0.s index 1df1e5c62..c203fb20f 100644 --- a/libsrc/c16/crt0.s +++ b/libsrc/c16/crt0.s @@ -24,7 +24,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda sp,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -49,8 +49,8 @@ L1: lda sp,x bcc MemOk ldy #$80 ldx #$00 -MemOk: stx sp - sty sp+1 ; set argument stack ptr +MemOk: stx c_sp + sty c_sp+1 ; set argument stack ptr ; Call the module constructors. @@ -69,7 +69,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta c_sp,x dex bpl L2 diff --git a/libsrc/c64/crt0.s b/libsrc/c64/crt0.s index 4e5c7c9d4..dea9226aa 100644 --- a/libsrc/c64/crt0.s +++ b/libsrc/c64/crt0.s @@ -55,7 +55,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta c_sp,x dex bpl L2 @@ -85,7 +85,7 @@ init: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda sp,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -94,8 +94,8 @@ L1: lda sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Switch to the second charset. diff --git a/libsrc/c64/mou/c64-1351.s b/libsrc/c64/mou/c64-1351.s index ce0f18803..dcf949730 100644 --- a/libsrc/c64/mou/c64-1351.s +++ b/libsrc/c64/mou/c64-1351.s @@ -239,11 +239,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (c_sp),y sta XPos+1 tax dey - lda (sp),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c64/mou/c64-inkwell.s b/libsrc/c64/mou/c64-inkwell.s index d2f14a6f0..68941260c 100644 --- a/libsrc/c64/mou/c64-inkwell.s +++ b/libsrc/c64/mou/c64-inkwell.s @@ -249,10 +249,10 @@ MOVE: sei ; No interrupts jsr MoveY ldy #$01 - lda (sp),y + lda (c_sp),y tax dey - lda (sp),y + lda (c_sp),y jsr MoveX ; Move the cursor cli ; Allow interrupts diff --git a/libsrc/c64/mou/c64-joy.s b/libsrc/c64/mou/c64-joy.s index 5ee1b4f84..901b9c42d 100644 --- a/libsrc/c64/mou/c64-joy.s +++ b/libsrc/c64/mou/c64-joy.s @@ -245,11 +245,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (c_sp),y sta XPos+1 tax dey - lda (sp),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/c64/mou/c64-pot.s b/libsrc/c64/mou/c64-pot.s index 9bdf24f62..1728913e1 100644 --- a/libsrc/c64/mou/c64-pot.s +++ b/libsrc/c64/mou/c64-pot.s @@ -230,11 +230,11 @@ MOVE: sei ; No interrupts jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (c_sp),y sta XPos+1 tax dey - lda (sp),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/cbm/dir.s b/libsrc/cbm/dir.s index 734485aaf..a78fc94a5 100644 --- a/libsrc/cbm/dir.s +++ b/libsrc/cbm/dir.s @@ -44,10 +44,10 @@ __dirread: ; Replace dir by dir->fd ldy #2 - lda (sp),y + lda (c_sp),y sta ptr1 iny - lda (sp),y + lda (c_sp),y sta ptr1+1 ldy #DIR::fd+1 lda (ptr1),y @@ -55,10 +55,10 @@ __dirread: dey lda (ptr1),y ldy #2 - sta (sp),y + sta (c_sp),y pla iny - sta (sp),y + sta (c_sp),y ; Get count, save it again, clear the high byte and call read(). By the ; previous actions, the stack frame is as read() needs it, and read() will diff --git a/libsrc/cbm/open.s b/libsrc/cbm/open.s index 47224925d..bf937ee0f 100644 --- a/libsrc/cbm/open.s +++ b/libsrc/cbm/open.s @@ -12,7 +12,7 @@ .import opencmdchannel, closecmdchannel, readdiskerror .import fnunit, fnisfile .import _close - .importzp sp, tmp2, tmp3 + .importzp c_sp, tmp2, tmp3 .include "errno.inc" .include "fcntl.inc" diff --git a/libsrc/cbm/write.s b/libsrc/cbm/write.s index 172e45382..43c7582f0 100644 --- a/libsrc/cbm/write.s +++ b/libsrc/cbm/write.s @@ -8,7 +8,7 @@ .constructor initstdout .import rwcommon - .importzp sp, ptr1, ptr2, ptr3 + .importzp c_sp, ptr1, ptr2, ptr3 .include "cbm.inc" .include "errno.inc" diff --git a/libsrc/cbm510/crt0.s b/libsrc/cbm510/crt0.s index 86137b1ca..80d587ff5 100644 --- a/libsrc/cbm510/crt0.s +++ b/libsrc/cbm510/crt0.s @@ -117,7 +117,7 @@ entry: php tya sec sbc #7 - sta $1FF ; Save new sp + sta $1FF ; Save new c_sp tay tsx @@ -145,7 +145,7 @@ entry: php iny sta (sysp1),y - ldy $1FF ; Restore sp in bank 15 + ldy $1FF ; Restore c_sp in bank 15 lda #.hibyte(expull-1) sta (sysp1),y @@ -245,7 +245,7 @@ L1: lda extzp,x dex bpl L1 -; Save the old stack pointer from the system bank; and, set up our hw sp. +; Save the old stack pointer from the system bank; and, set up our hw c_sp. tsx txa @@ -279,9 +279,9 @@ L3: lda vectors,x ; Set up the C stack. lda #.lobyte(callbank15::entry) - sta sp + sta c_sp lda #.hibyte(callbank15::entry) - sta sp+1 + sta c_sp+1 ; Set up the subroutine and jump vector table that redirects Kernal calls to ; the system bank. @@ -495,7 +495,7 @@ _exit: pha ; Save the return code on stack ; Set up the welcome code at the stack bottom in the system bank. ldy #$FF - lda (sysp1),y ; Load system bank sp + lda (sysp1),y ; Load system bank c_sp tax iny ; Y = 0 lda #$58 ; CLI opcode diff --git a/libsrc/cbm510/mou/cbm510-inkwl.s b/libsrc/cbm510/mou/cbm510-inkwl.s index ea6d95934..e5328cf75 100644 --- a/libsrc/cbm510/mou/cbm510-inkwl.s +++ b/libsrc/cbm510/mou/cbm510-inkwl.s @@ -256,10 +256,10 @@ MOVE: sei ; No interrupts jsr MoveY ldy #$01 - lda (sp),y + lda (c_sp),y tax dey - lda (sp),y + lda (c_sp),y jsr MoveX ; Move the cursor cli ; Allow interrupts diff --git a/libsrc/cbm510/mou/cbm510-joy.s b/libsrc/cbm510/mou/cbm510-joy.s index 4daa49272..912842be7 100644 --- a/libsrc/cbm510/mou/cbm510-joy.s +++ b/libsrc/cbm510/mou/cbm510-joy.s @@ -225,11 +225,11 @@ MOVE: sei ; No interrupts jsr MoveY ; Set new y position ldy #1 - lda (sp),y + lda (c_sp),y sta XPos+1 tax dey - lda (sp),y + lda (c_sp),y jsr MoveX ; Move the pointer cli ; Allow interrupts diff --git a/libsrc/cbm610/crt0.s b/libsrc/cbm610/crt0.s index 0ad343d7f..dc56fa2de 100644 --- a/libsrc/cbm610/crt0.s +++ b/libsrc/cbm610/crt0.s @@ -115,7 +115,7 @@ entry: php tya sec sbc #7 - sta $1FF ; Save new sp + sta $1FF ; Save new c_sp tay tsx @@ -143,7 +143,7 @@ entry: php iny sta (sysp1),y - ldy $1FF ; Restore sp in bank 15 + ldy $1FF ; Restore c_sp in bank 15 lda #.hibyte(expull-1) sta (sysp1),y @@ -243,7 +243,7 @@ L1: lda extzp,x dex bpl L1 -; Save the old stack pointer from the system bank; and, set up our hw sp. +; Save the old stack pointer from the system bank; and, set up our hw c_sp. tsx txa @@ -277,9 +277,9 @@ L3: lda vectors,x ; Set up the C stack. lda #.lobyte(callbank15::entry) - sta sp + sta c_sp lda #.hibyte(callbank15::entry) - sta sp+1 + sta c_sp+1 ; Set up the subroutine and jump vector table that redirects Kernal calls to ; the system bank. @@ -400,7 +400,7 @@ _exit: pha ; Save the return code ; Set up the welcome code at the stack bottom in the system bank. ldy #$FF - lda (sysp1),y ; Load system bank sp + lda (sysp1),y ; Load system bank c_sp tax iny ; Y = 0 lda #$58 ; CLI opcode diff --git a/libsrc/common/_fopen.s b/libsrc/common/_fopen.s index 17a1ec19b..0c234097e 100644 --- a/libsrc/common/_fopen.s +++ b/libsrc/common/_fopen.s @@ -9,7 +9,7 @@ .import _open .import pushax, incsp4, return0 - .importzp sp, ptr1 + .importzp c_sp, ptr1 .include "errno.inc" @@ -28,10 +28,10 @@ ; Get a pointer to the mode string ldy #1 - lda (sp),y + lda (c_sp),y sta ptr1+1 dey - lda (sp),y + lda (c_sp),y sta ptr1 ; Look at the first character in mode @@ -78,10 +78,10 @@ invmode: modeok: ldy #$00 txa ; Mode -> A - sta (sp),y + sta (c_sp),y tya iny - sta (sp),y + sta (c_sp),y ldy #4 ; Size of arguments in bytes jsr _open ; Will cleanup the stack diff --git a/libsrc/common/_heap.s b/libsrc/common/_heap.s index eb680fa20..e5d71d1be 100644 --- a/libsrc/common/_heap.s +++ b/libsrc/common/_heap.s @@ -6,7 +6,7 @@ .constructor initheap, 24 .import __BSS_RUN__, __BSS_SIZE__, __STACKSIZE__ - .importzp sp + .importzp c_sp .include "_heap.inc" @@ -31,10 +31,10 @@ ___heaplast: initheap: sec - lda sp + lda c_sp sbc #<__STACKSIZE__ sta ___heapend - lda sp+1 + lda c_sp+1 sbc #>__STACKSIZE__ sta ___heapend+1 rts diff --git a/libsrc/common/_idiv32by16r16.s b/libsrc/common/_idiv32by16r16.s index 7df78f4dd..9534f751f 100644 --- a/libsrc/common/_idiv32by16r16.s +++ b/libsrc/common/_idiv32by16r16.s @@ -20,17 +20,17 @@ ; Copy from stack to zeropage. This assumes ptr1 and ptr2 are adjacent. ldy #3 -@L1: lda (sp),y +@L1: lda (c_sp),y sta ptr1,y dey bpl @L1 lda #4 clc - adc sp - sta sp + adc c_sp + sta c_sp bcc @L2 - inc sp+1 + inc c_sp+1 @L2: pla ; Old rhs jmp idiv32by16r16 diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index d7eeb072d..40ab0bc64 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -338,25 +338,25 @@ MainLoop: jsr decsp6 ; 3 args ldy #5 lda OutData+1 - sta (sp),y + sta (c_sp),y dey lda OutData - sta (sp),y + sta (c_sp),y dey lda FSave+1 - sta (sp),y + sta (c_sp),y dey lda FSave - sta (sp),y + sta (c_sp),y dey lda FCount+1 - sta (sp),y + sta (c_sp),y dey lda FCount .if (.cpu .bitand ::CPU_ISET_65SC02) - sta (sp) + sta (c_sp) .else - sta (sp),y + sta (c_sp),y .endif jsr CallOutFunc ; Call the output function diff --git a/libsrc/common/_udiv32by16r16.s b/libsrc/common/_udiv32by16r16.s index a1d5f4e66..987390c04 100644 --- a/libsrc/common/_udiv32by16r16.s +++ b/libsrc/common/_udiv32by16r16.s @@ -21,17 +21,17 @@ ; Copy from stack to zeropage. This assumes ptr1 and ptr2 are adjacent. ldy #3 -@L1: lda (sp),y +@L1: lda (c_sp),y sta ptr1,y dey bpl @L1 lda #4 clc - adc sp - sta sp + adc c_sp + sta c_sp bcc @L2 - inc sp+1 + inc c_sp+1 @L2: jmp udiv32by16r16m diff --git a/libsrc/common/fprintf.s b/libsrc/common/fprintf.s index 1582e6521..af9a58ebc 100644 --- a/libsrc/common/fprintf.s +++ b/libsrc/common/fprintf.s @@ -6,7 +6,7 @@ .export _fprintf .import addysp, decsp4, _vfprintf - .importzp sp, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -38,9 +38,9 @@ _fprintf: ; Calculate a pointer to the Format argument lda ParamSize - add sp + add c_sp sta ptr1 - ldx sp+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 @@ -49,7 +49,7 @@ _fprintf: ldy #4-1 @L2: lda (ptr1),y - sta (sp),y + sta (c_sp),y dey bpl @L2 diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index b39b9d748..be06c2a62 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -14,7 +14,7 @@ .import pushwysp .import tosumulax, tosudivax - .importzp ptr1, sp + .importzp ptr1, c_sp .include "errno.inc" .include "_file.inc" @@ -136,23 +136,23 @@ ; to read() by one, so read() starts to store data at buf+1. .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (c_sp) sta ptr1 add #1 - sta (sp) + sta (c_sp) ldy #1 .else ldy #0 - lda (sp),y + lda (c_sp),y sta ptr1 add #1 - sta (sp),y + sta (c_sp),y iny .endif - lda (sp),y + lda (c_sp),y sta ptr1+1 adc #0 - sta (sp),y ; ptr1 = buf++; + sta (c_sp),y ; ptr1 = buf++; ; Get the buffered character and place it as first character into the read ; buffer. diff --git a/libsrc/common/fscanf.s b/libsrc/common/fscanf.s index a3d1ec0a1..c687a0624 100644 --- a/libsrc/common/fscanf.s +++ b/libsrc/common/fscanf.s @@ -6,7 +6,7 @@ .export _fscanf .import addysp, decsp4, _vfscanf - .importzp sp, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -50,9 +50,9 @@ _fscanf: ; Calculate a pointer to the Format argument lda ParamSize - add sp + add c_sp sta ptr1 - ldx sp+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 @@ -61,7 +61,7 @@ _fscanf: ldy #4-1 @L2: lda (ptr1),y - sta (sp),y + sta (c_sp),y dey bpl @L2 diff --git a/libsrc/common/interrupt.s b/libsrc/common/interrupt.s index 6bdbb5fe4..a67d51fda 100644 --- a/libsrc/common/interrupt.s +++ b/libsrc/common/interrupt.s @@ -93,8 +93,8 @@ zpsave: .res zpsavespace ; Set C level interrupt stack lda irqsp ldx irqsp+1 - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 ; Call C level interrupt request handler jsr irqvec diff --git a/libsrc/common/itoa.s b/libsrc/common/itoa.s index 808f9bc33..a1cd53c8b 100644 --- a/libsrc/common/itoa.s +++ b/libsrc/common/itoa.s @@ -8,7 +8,7 @@ .export _itoa, _utoa .import addysp1 .import __hextab - .importzp sp, sreg, ptr2, ptr3, tmp1 + .importzp c_sp, sreg, ptr2, ptr3, tmp1 .rodata specval: @@ -21,18 +21,18 @@ specval: dopop: sta tmp1 ; will lose high byte ldy #0 - lda (sp),y + lda (c_sp),y sta ptr2 sta ptr3 iny - lda (sp),y + lda (c_sp),y sta ptr2+1 sta ptr3+1 iny - lda (sp),y + lda (c_sp),y sta sreg iny - lda (sp),y + lda (c_sp),y sta sreg+1 jmp addysp1 ; Bump stack pointer diff --git a/libsrc/common/longjmp.s b/libsrc/common/longjmp.s index 91606a442..8855286a9 100644 --- a/libsrc/common/longjmp.s +++ b/libsrc/common/longjmp.s @@ -7,7 +7,7 @@ .export _longjmp .import popptr1 - .importzp sp, ptr1, ptr2 + .importzp c_sp, ptr1, ptr2 _longjmp: sta ptr2 ; Save retval @@ -23,10 +23,10 @@ _longjmp: lda (ptr1),y iny - sta sp + sta c_sp lda (ptr1),y iny - sta sp+1 + sta c_sp+1 ; Get the old stack pointer diff --git a/libsrc/common/lz4.s b/libsrc/common/lz4.s index c53841897..5d26cb56a 100644 --- a/libsrc/common/lz4.s +++ b/libsrc/common/lz4.s @@ -61,7 +61,7 @@ ; } ; } - .importzp sp, sreg, regsave, regbank + .importzp c_sp, sreg, regsave, regbank .importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 .macpack longbranch .import memcpy_upwards,pushax,popax diff --git a/libsrc/common/memcpy.s b/libsrc/common/memcpy.s index fd090c788..8f6531956 100644 --- a/libsrc/common/memcpy.s +++ b/libsrc/common/memcpy.s @@ -12,7 +12,7 @@ .export _memcpy, memcpy_upwards, memcpy_getparams .import popax, popptr1 - .importzp sp, ptr1, ptr2, ptr3 + .importzp c_sp, ptr1, ptr2, ptr3 ; ---------------------------------------------------------------------- _memcpy: @@ -70,10 +70,10 @@ memcpy_getparams: ; IMPORTANT! Function has to leave with Y=0! iny ; Y=0 guaranteed by popptr1, we need '1' here... ; (direct stack access is three cycles faster ; (total cycle count with return)) - lda (sp),y + lda (c_sp),y tax stx ptr2+1 ; save high byte of ptr2 dey ; Y = 0 - lda (sp),y ; Get ptr2 low + lda (c_sp),y ; Get ptr2 low sta ptr2 rts diff --git a/libsrc/common/memset.s b/libsrc/common/memset.s index be78fc30d..5d56507a5 100644 --- a/libsrc/common/memset.s +++ b/libsrc/common/memset.s @@ -17,7 +17,7 @@ .export _memset, _bzero, ___bzero .import popax - .importzp sp, ptr1, ptr2, ptr3 + .importzp c_sp, ptr1, ptr2, ptr3 _bzero: ___bzero: @@ -36,10 +36,10 @@ _memset: common: ; Fill value is in X! ldy #1 - lda (sp),y + lda (c_sp),y sta ptr1+1 ; save high byte of ptr dey ; Y = 0 - lda (sp),y ; Get ptr + lda (c_sp),y ; Get ptr sta ptr1 lsr ptr3+1 ; divide number of diff --git a/libsrc/common/printf.s b/libsrc/common/printf.s index 8d645dfa2..76e08e584 100644 --- a/libsrc/common/printf.s +++ b/libsrc/common/printf.s @@ -6,7 +6,7 @@ .export _printf .import _stdout, pushax, addysp, _vfprintf - .importzp sp, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -43,8 +43,8 @@ _printf: ; Now calculate the va_list pointer, which does points to Format - lda sp - ldx sp+1 + lda c_sp + ldx c_sp+1 add ParamSize bcc @L1 inx diff --git a/libsrc/common/realloc.s b/libsrc/common/realloc.s index 176871dd5..16d5eea41 100644 --- a/libsrc/common/realloc.s +++ b/libsrc/common/realloc.s @@ -4,7 +4,7 @@ ; void* __fastcall__ realloc (void* block, register size_t size) ; - .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4, sp + .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4, c_sp .import _malloc, _memcpy, _free .import pushax, popptr1, return0 .import incsp2, decsp2 diff --git a/libsrc/common/scanf.s b/libsrc/common/scanf.s index dd6c16ad1..92460b629 100644 --- a/libsrc/common/scanf.s +++ b/libsrc/common/scanf.s @@ -8,7 +8,7 @@ .export _scanf .import _stdin, pushax, addysp, _vfscanf - .import sp:zp, ptr1:zp + .import c_sp:zp, ptr1:zp .macpack generic @@ -34,8 +34,8 @@ _scanf: ; Now, calculate the va_list pointer, which does point to Format. - lda sp - ldx sp+1 + lda c_sp + ldx c_sp+1 add ArgSize bcc @L1 inx diff --git a/libsrc/common/setjmp.s b/libsrc/common/setjmp.s index 886853368..3c0b8aa17 100644 --- a/libsrc/common/setjmp.s +++ b/libsrc/common/setjmp.s @@ -8,7 +8,7 @@ .export ___setjmp .import return0 - .importzp sp, ptr1 + .importzp c_sp, ptr1 ___setjmp: sta ptr1 ; Save buf @@ -17,10 +17,10 @@ ___setjmp: ; The parameter stack is now empty, put it into buf - lda sp + lda c_sp sta (ptr1),y iny - lda sp+1 + lda c_sp+1 sta (ptr1),y iny diff --git a/libsrc/common/snprintf.s b/libsrc/common/snprintf.s index 33afb434d..c922a55bc 100644 --- a/libsrc/common/snprintf.s +++ b/libsrc/common/snprintf.s @@ -6,7 +6,7 @@ .export _snprintf .import pushax, addysp, decsp6, _vsnprintf - .importzp sp, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -38,9 +38,9 @@ _snprintf: ; Calculate a pointer to the Format argument lda ParamSize - add sp + add c_sp sta ptr1 - ldx sp+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 @@ -49,7 +49,7 @@ _snprintf: ldy #6-1 @L2: lda (ptr1),y - sta (sp),y + sta (c_sp),y dey bpl @L2 diff --git a/libsrc/common/sprintf.s b/libsrc/common/sprintf.s index d502d8638..d2ce6602e 100644 --- a/libsrc/common/sprintf.s +++ b/libsrc/common/sprintf.s @@ -6,7 +6,7 @@ .export _sprintf .import pushax, addysp, decsp4, _vsprintf - .importzp sp, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -38,9 +38,9 @@ _sprintf: ; Calculate a pointer to the Format argument lda ParamSize - add sp + add c_sp sta ptr1 - ldx sp+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 @@ -49,7 +49,7 @@ _sprintf: ldy #4-1 @L2: lda (ptr1),y - sta (sp),y + sta (c_sp),y dey bpl @L2 diff --git a/libsrc/common/sscanf.s b/libsrc/common/sscanf.s index 941f54e92..d393087d8 100644 --- a/libsrc/common/sscanf.s +++ b/libsrc/common/sscanf.s @@ -6,7 +6,7 @@ .export _sscanf .import addysp, decsp4, _vsscanf - .importzp sp, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -51,9 +51,9 @@ _sscanf: ; Calculate a pointer to the fixed parameters lda ParamSize - add sp + add c_sp sta ptr1 - ldx sp+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 @@ -62,7 +62,7 @@ _sscanf: ldy #4-1 @L2: lda (ptr1),y - sta (sp),y + sta (c_sp),y dey bpl @L2 diff --git a/libsrc/common/vfprintf.s b/libsrc/common/vfprintf.s index 1225bcc47..3dc1e6729 100644 --- a/libsrc/common/vfprintf.s +++ b/libsrc/common/vfprintf.s @@ -8,7 +8,7 @@ .export _vfprintf .import push1, pushwysp, incsp6 .import _fwrite, __printf - .importzp sp, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -121,15 +121,15 @@ _vfprintf: ; exactly as _printf expects it. Parameters will get dropped by _printf. ldy #2 - lda (sp),y ; Low byte of f + lda (c_sp),y ; Low byte of f sta ptr lda #<outdesc - sta (sp),y + sta (c_sp),y iny - lda (sp),y ; High byte of f + lda (c_sp),y ; High byte of f sta ptr+1 lda #>outdesc - sta (sp),y + sta (c_sp),y ; Restore low byte of ap and call _printf diff --git a/libsrc/common/vfscanf.s b/libsrc/common/vfscanf.s index c7d6e5564..71d7c634c 100644 --- a/libsrc/common/vfscanf.s +++ b/libsrc/common/vfscanf.s @@ -61,16 +61,16 @@ _vfscanf: ; Swap f against &d on the stack, placing f into d.data ldy #2 ; Offset of f on the stack - lda (sp),y + lda (c_sp),y sta d + SCANFDATA::DATA lda #<d - sta (sp),y + sta (c_sp),y iny ; High byte - lda (sp),y + lda (c_sp),y sta d + SCANFDATA::DATA + 1 lda #>d - sta (sp),y + sta (c_sp),y ; Restore the low byte of ap, and call the _scanf function diff --git a/libsrc/common/vprintf.s b/libsrc/common/vprintf.s index 0958b1038..1c44b61ef 100644 --- a/libsrc/common/vprintf.s +++ b/libsrc/common/vprintf.s @@ -7,7 +7,7 @@ .export _vprintf .import _vfprintf, _stdout .import decsp2 - .importzp sp + .importzp c_sp .proc _vprintf @@ -23,20 +23,20 @@ ; Move the format parameter down and store stdout in it's place ldy #2 - lda (sp),y + lda (c_sp),y ldy #0 - sta (sp),y + sta (c_sp),y ldy #3 - lda (sp),y + lda (c_sp),y ldy #1 - sta (sp),y + sta (c_sp),y iny lda _stdout - sta (sp),y + sta (c_sp),y iny lda _stdout+1 - sta (sp),y + sta (c_sp),y ; Restore A diff --git a/libsrc/common/vscanf.s b/libsrc/common/vscanf.s index 94afe527f..a97bd163a 100644 --- a/libsrc/common/vscanf.s +++ b/libsrc/common/vscanf.s @@ -31,22 +31,22 @@ _vscanf: ; Move the format down ldy #2 - lda (sp),y ; Load byte of format + lda (c_sp),y ; Load byte of format ldy #0 - sta (sp),y + sta (c_sp),y ldy #3 - lda (sp),y + lda (c_sp),y ldy #1 - sta (sp),y + sta (c_sp),y ; Store stdin into the stack frame iny lda _stdin - sta (sp),y + sta (c_sp),y iny lda _stdin+1 - sta (sp),y + sta (c_sp),y ; Restore the low byte of ap and jump to vfscanf, which will cleanup the stack diff --git a/libsrc/common/vsnprintf.s b/libsrc/common/vsnprintf.s index 048a756c3..780ab10ee 100644 --- a/libsrc/common/vsnprintf.s +++ b/libsrc/common/vsnprintf.s @@ -8,7 +8,7 @@ .export _vsnprintf, vsnprintf .import ldaxysp, popax, incsp2, incsp6 .import _memcpy, __printf - .importzp sp, ptr1 + .importzp c_sp, ptr1 .include "errno.inc" @@ -55,19 +55,19 @@ vsnprintf: ; be formatted and counted. ldy #2 - lda (sp),y + lda (c_sp),y sta ptr1 lda #<outdesc - sta (sp),y + sta (c_sp),y iny - lda (sp),y + lda (c_sp),y bmi L9 ; More than $7FFF sta ptr1+1 lda #>outdesc - sta (sp),y + sta (c_sp),y ; Write size-1 to outdesc.uns. It will be -1 if there is no buffer. @@ -178,12 +178,12 @@ out: clc adc ccount+0 ldy #4 - sta (sp),y + sta (c_sp),y lda bufptr+1 adc ccount+1 iny - sta (sp),y + sta (c_sp),y ; Get Count from stack diff --git a/libsrc/common/vsscanf.s b/libsrc/common/vsscanf.s index 335712b20..2061861dc 100644 --- a/libsrc/common/vsscanf.s +++ b/libsrc/common/vsscanf.s @@ -9,7 +9,7 @@ .export _vsscanf .import popax, __scanf - .importzp sp, ptr1, ptr2 + .importzp c_sp, ptr1, ptr2 .macpack generic @@ -165,15 +165,15 @@ d: .addr get ; to d ldy #2 ; Stack offset of str - lda (sp),y + lda (c_sp),y sta sd + SSCANFDATA::STR lda #<d - sta (sp),y + sta (c_sp),y iny - lda (sp),y + lda (c_sp),y sta sd + SSCANFDATA::STR+1 lda #>d - sta (sp),y + sta (c_sp),y lda #$00 sta sd + SSCANFDATA::INDEX diff --git a/libsrc/conio/cprintf.s b/libsrc/conio/cprintf.s index 01bd0bbc6..80bca2308 100644 --- a/libsrc/conio/cprintf.s +++ b/libsrc/conio/cprintf.s @@ -6,7 +6,7 @@ .export _cprintf .import pushax, addysp, _vcprintf - .importzp sp, ptr1 + .importzp c_sp, ptr1 .macpack generic @@ -31,9 +31,9 @@ _cprintf: dey dey ; Sub size of Format tya - add sp + add c_sp sta ptr1 - ldx sp+1 + ldx c_sp+1 bcc @L1 inx @L1: stx ptr1+1 diff --git a/libsrc/conio/cscanf.s b/libsrc/conio/cscanf.s index 7e54a844f..7ee532626 100644 --- a/libsrc/conio/cscanf.s +++ b/libsrc/conio/cscanf.s @@ -23,8 +23,8 @@ _cscanf: ; Now, calculate the va_list pointer -- which points to format. - ldx sp+1 - add sp + ldx c_sp+1 + add c_sp bcc @L1 inx @L1: sta ptr1 diff --git a/libsrc/conio/vcprintf.s b/libsrc/conio/vcprintf.s index 595a2d2c5..c6371f00e 100644 --- a/libsrc/conio/vcprintf.s +++ b/libsrc/conio/vcprintf.s @@ -7,7 +7,7 @@ .export _vcprintf .import pushax, popax, popptr1 .import __printf, _cputc - .importzp sp, ptr1, ptr2, ptr3, tmp1 + .importzp c_sp, ptr1, ptr2, ptr3, tmp1 .macpack generic .macpack cpu @@ -138,10 +138,10 @@ _vcprintf: ; Get the format parameter and push it again ldy #1 - lda (sp),y + lda (c_sp),y tax dey - lda (sp),y + lda (c_sp),y jsr pushax ; Replace the passed format parameter on the stack by &d - this creates @@ -150,10 +150,10 @@ _vcprintf: ldy #2 ; Low byte of d lda #<outdesc - sta (sp),y + sta (c_sp),y iny lda #>outdesc - sta (sp),y + sta (c_sp),y ; Restore ap and call _printf diff --git a/libsrc/creativision/crt0.s b/libsrc/creativision/crt0.s index 5185ff237..70009e2ba 100644 --- a/libsrc/creativision/crt0.s +++ b/libsrc/creativision/crt0.s @@ -40,8 +40,8 @@ entry: ; Setup the argument stack ptr lda #<(__ZP_LAST__ + __STACKSIZE__) ldx #>(__ZP_LAST__ + __STACKSIZE__) - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 ; Call module constructors jsr initlib diff --git a/libsrc/cx16/crt0.s b/libsrc/cx16/crt0.s index e37a64a7c..5ee81b184 100644 --- a/libsrc/cx16/crt0.s +++ b/libsrc/cx16/crt0.s @@ -80,8 +80,8 @@ init: lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Switch to the lower/UPPER PetSCII charset. diff --git a/libsrc/cx16/mou/cx16-std.s b/libsrc/cx16/mou/cx16-std.s index f211815de..5bfe27a7d 100644 --- a/libsrc/cx16/mou/cx16-std.s +++ b/libsrc/cx16/mou/cx16-std.s @@ -238,11 +238,11 @@ MOVE: php jsr CMOVEY ; Set it ldy #$01 - lda (sp),y + lda (c_sp),y sta XPos+1 tax dey - lda (sp),y + lda (c_sp),y sta XPos ; New X position jsr CMOVEX ; Move the cursor diff --git a/libsrc/dbg/dbgdump.s b/libsrc/dbg/dbgdump.s index bc6a4bd40..335175840 100644 --- a/libsrc/dbg/dbgdump.s +++ b/libsrc/dbg/dbgdump.s @@ -7,23 +7,23 @@ .export _DbgMemDump .import addysp1 .import __hextab - .importzp sp, tmp2, tmp3, tmp4, ptr3, ptr4 + .importzp c_sp, tmp2, tmp3, tmp4, ptr3, ptr4 _DbgMemDump: ldy #0 - lda (sp),y ; Get length + lda (c_sp),y ; Get length sta tmp4 iny - lda (sp),y ; Get the string buffer + lda (c_sp),y ; Get the string buffer sta ptr3 iny - lda (sp),y + lda (c_sp),y sta ptr3+1 iny - lda (sp),y ; Get the address + lda (c_sp),y ; Get the address sta ptr4 iny - lda (sp),y + lda (c_sp),y sta ptr4+1 jsr addysp1 ; Drop the parameters diff --git a/libsrc/dbg/dbgsupp.s b/libsrc/dbg/dbgsupp.s index b1f122013..ce503bcab 100644 --- a/libsrc/dbg/dbgsupp.s +++ b/libsrc/dbg/dbgsupp.s @@ -36,9 +36,9 @@ DbgBreak: jsr DbgSwapZP ; Swap stuff lda #<DbgStack ; Set new stack - sta sp + sta c_sp lda #>DbgStack - sta sp+1 + sta c_sp+1 jsr ResetDbgBreaks ; Reset temporary breakpoints jsr _DbgEntry ; Call C code jsr SetDbgBreaks ; Set temporary breakpoints @@ -61,7 +61,7 @@ DbgStack: ; Swap space for the C temporaries CTemp: -_DbgCS: .res 2 ; sp +_DbgCS: .res 2 ; c_sp _DbgHI: .res 2 ; sreg .res (zpsavespace-4) ; Other stuff @@ -78,7 +78,7 @@ Swap1: ldx CTemp,y lda <__ZP_START__,y sta CTemp,y txa - sta sp,y + sta c_sp,y dey bpl Swap1 rts diff --git a/libsrc/gamate/crt0.s b/libsrc/gamate/crt0.s index 5a5bb3aa0..67fa8813f 100644 --- a/libsrc/gamate/crt0.s +++ b/libsrc/gamate/crt0.s @@ -34,8 +34,8 @@ Start: ; Set up the stack lda #<(__RAM_START__+__RAM_SIZE__) ldx #>(__RAM_START__+__RAM_SIZE__) - sta sp - stx sp + 1 + sta c_sp + stx c_sp + 1 ; Call module constructors jsr initlib diff --git a/libsrc/geos-common/drivers/geos-stdmou.s b/libsrc/geos-common/drivers/geos-stdmou.s index 88bbc7df9..aacb2590e 100644 --- a/libsrc/geos-common/drivers/geos-stdmou.s +++ b/libsrc/geos-common/drivers/geos-stdmou.s @@ -13,7 +13,7 @@ .export _mouse_move, _mouse_buttons .import popsreg, addysp1 - .importzp sp, sreg, ptr1 + .importzp c_sp, sreg, ptr1 .include "const.inc" .include "jumptab.inc" @@ -87,22 +87,22 @@ _mouse_box: sta mouseBottom - lda (sp),y + lda (c_sp),y sta mouseRight iny - lda (sp),y + lda (c_sp),y sta mouseRight+1 ; maxx iny - lda (sp),y + lda (c_sp),y sta mouseTop iny ; Skip high byte iny - lda (sp),y + lda (c_sp),y sta mouseLeft iny - lda (sp),y + lda (c_sp),y sta mouseLeft+1 ; minx jmp addysp1 ; Drop params, return diff --git a/libsrc/geos-common/system/crt0.s b/libsrc/geos-common/system/crt0.s index 47cec74f2..e1751baef 100644 --- a/libsrc/geos-common/system/crt0.s +++ b/libsrc/geos-common/system/crt0.s @@ -11,7 +11,7 @@ .import initlib, donelib .import callmain .import zerobss - .importzp sp + .importzp c_sp .include "jumptab.inc" .include "geossym.inc" @@ -48,8 +48,8 @@ lda #<(__STACKADDR__ + __STACKSIZE__) ldx #>(__STACKADDR__ + __STACKSIZE__) - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 ; Call the module constructors. diff --git a/libsrc/kim1/crt0.s b/libsrc/kim1/crt0.s index 906b3b980..adc934a78 100644 --- a/libsrc/kim1/crt0.s +++ b/libsrc/kim1/crt0.s @@ -26,9 +26,9 @@ _init: cld ; Clear decimal mode ; Set cc65 argument stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) - sta sp + sta c_sp lda #>(__RAM_START__ + __RAM_SIZE__) - sta sp+1 + sta c_sp+1 ; Initialize memory storage diff --git a/libsrc/lynx/crt0.s b/libsrc/lynx/crt0.s index 030f523e9..e1f1c078e 100644 --- a/libsrc/lynx/crt0.s +++ b/libsrc/lynx/crt0.s @@ -80,8 +80,8 @@ MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$2 lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 ; Init Mickey. diff --git a/libsrc/lynx/lseek.s b/libsrc/lynx/lseek.s index 04d816945..da0a1922b 100644 --- a/libsrc/lynx/lseek.s +++ b/libsrc/lynx/lseek.s @@ -11,7 +11,7 @@ ; ; off_t __fastcall__ lseek(int fd, off_t offset, int whence); - .importzp sp, sreg, regsave, regbank, tmp1, ptr1, ptr2 + .importzp c_sp, sreg, regsave, regbank, tmp1, ptr1, ptr2 .macpack longbranch .export _lseek .import addysp, stax0sp, tosand0ax, pusheax, asreax2 diff --git a/libsrc/nes/crt0.s b/libsrc/nes/crt0.s index 19e97bb12..dfc26dcde 100644 --- a/libsrc/nes/crt0.s +++ b/libsrc/nes/crt0.s @@ -107,8 +107,8 @@ start: lda #<(__SRAM_START__ + __SRAM_SIZE__) ldx #>(__SRAM_START__ + __SRAM_SIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/none/crt0.s b/libsrc/none/crt0.s index 596fbcd46..443f453b9 100644 --- a/libsrc/none/crt0.s +++ b/libsrc/none/crt0.s @@ -10,8 +10,8 @@ lda #<__STACKSTART__ ldx #>__STACKSTART__ - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 jsr zerobss jsr initlib jsr _main diff --git a/libsrc/osic1p/crt0.s b/libsrc/osic1p/crt0.s index 56abb7cdb..46d29ed66 100644 --- a/libsrc/osic1p/crt0.s +++ b/libsrc/osic1p/crt0.s @@ -34,8 +34,8 @@ _init: ldx #$FF ; Initialize stack pointer to $01FF lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 ; --------------------------------------------------------------------------- ; Initialize memory storage diff --git a/libsrc/pce/_printf.s b/libsrc/pce/_printf.s index e1d2a1cf4..675076ec6 100644 --- a/libsrc/pce/_printf.s +++ b/libsrc/pce/_printf.s @@ -329,22 +329,22 @@ MainLoop: jsr decsp6 ; 3 args ldy #5 lda OutData+1 - sta (sp),y + sta (c_sp),y dey lda OutData - sta (sp),y + sta (c_sp),y dey lda FSave+1 - sta (sp),y + sta (c_sp),y dey lda FSave - sta (sp),y + sta (c_sp),y dey lda FCount+1 - sta (sp),y + sta (c_sp),y dey lda FCount - sta (sp),y + sta (c_sp),y jsr CallOutFunc ; Call the output function ; We're back from out(), or we didn't call it. Check for end of string. diff --git a/libsrc/pce/crt0.s b/libsrc/pce/crt0.s index d6dee3ef4..660faae7f 100644 --- a/libsrc/pce/crt0.s +++ b/libsrc/pce/crt0.s @@ -13,7 +13,7 @@ .import initlib, donelib .import push0, _main .import IRQStub, __nmi - .importzp sp + .importzp c_sp ; Linker-generated .import __CARTSIZE__ @@ -86,8 +86,8 @@ start: sei ; Set up the stack lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 ; Call the module constructors. jsr initlib diff --git a/libsrc/pce/memcpy.s b/libsrc/pce/memcpy.s index 98db6a964..7ee33477b 100644 --- a/libsrc/pce/memcpy.s +++ b/libsrc/pce/memcpy.s @@ -18,7 +18,7 @@ .export memcpy_increment, memcpy_transfer, memcpy_getparams .import incsp2, popax, popptr1 - .importzp sp, ptr1, ptr2, ptr3 + .importzp c_sp, ptr1, ptr2, ptr3 ; The structure of the transfer instructions @@ -86,9 +86,9 @@ memcpy_getparams: ; (Direct stack access is six cycles faster [total cycle count].) iny ; (Y=0 by popptr1, need '1' here) save dest - lda (sp),y ; get high byte + lda (c_sp),y ; get high byte tax - lda (sp) ; get low byte + lda (c_sp) ; get low byte sta ptr2 stx ptr2+1 rts ; return dest address (for memmove) diff --git a/libsrc/pet/crt0.s b/libsrc/pet/crt0.s index e56a7eca4..e3c6ed4b4 100644 --- a/libsrc/pet/crt0.s +++ b/libsrc/pet/crt0.s @@ -23,7 +23,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda sp,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -52,9 +52,9 @@ L1: lda sp,x stx spsave ; Save the system stack ptr lda MEMSIZE - sta sp + sta c_sp lda MEMSIZE+1 - sta sp+1 ; Set argument stack ptr + sta c_sp+1 ; Set argument stack ptr ; Call the module constructors. @@ -73,7 +73,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta c_sp,x dex bpl L2 diff --git a/libsrc/plus4/crt0.s b/libsrc/plus4/crt0.s index d1eea9472..a8a5b8e63 100644 --- a/libsrc/plus4/crt0.s +++ b/libsrc/plus4/crt0.s @@ -33,7 +33,7 @@ Start: sei ; No interrupts since we're banking out the ROM sta ENABLE_RAM ldx #zpspace-1 -L1: lda sp,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -53,8 +53,8 @@ L1: lda sp,x lda #<__HIMEM__ ldx #>__HIMEM__ - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 ; Set up the IRQ vector in the banked RAM; and, switch off the ROM. @@ -114,7 +114,7 @@ _exit: pha ; Save the return code ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta c_sp,x dex bpl L2 diff --git a/libsrc/rp6502/crt0.s b/libsrc/rp6502/crt0.s index 165ecf0a2..32d565fda 100644 --- a/libsrc/rp6502/crt0.s +++ b/libsrc/rp6502/crt0.s @@ -24,9 +24,9 @@ _init: ; Set cc65 argument stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) - sta sp + sta c_sp lda #>(__RAM_START__ + __RAM_SIZE__) - sta sp+1 + sta c_sp+1 ; Initialize memory storage jsr zerobss ; Clear BSS segment diff --git a/libsrc/rp6502/ria.s b/libsrc/rp6502/ria.s index a1b53efb1..78da4daba 100644 --- a/libsrc/rp6502/ria.s +++ b/libsrc/rp6502/ria.s @@ -11,7 +11,7 @@ .export _ria_call_int, _ria_call_long .export _ria_call_int_errno, _ria_call_long_errno -.importzp sp, sreg +.importzp c_sp, sreg .import ___mappederrno, incsp1 .code diff --git a/libsrc/rp6502/xreg.s b/libsrc/rp6502/xreg.s index 40d4a6705..a882ab10f 100644 --- a/libsrc/rp6502/xreg.s +++ b/libsrc/rp6502/xreg.s @@ -5,7 +5,7 @@ ; int __cdecl__ xreg(char device, char channel, unsigned char address, ...); .export _xreg -.importzp sp +.importzp c_sp .import addysp, _ria_call_int_errno .include "rp6502.inc" @@ -20,12 +20,12 @@ @copy: ; copy stack dey - lda (sp),y + lda (c_sp),y sta RIA_XSTACK tya bne @copy - ; recover variadic size and move sp + ; recover variadic size and move c_sp txa tay jsr addysp diff --git a/libsrc/runtime/add.s b/libsrc/runtime/add.s index a4658cc13..85ddd0f25 100644 --- a/libsrc/runtime/add.s +++ b/libsrc/runtime/add.s @@ -9,7 +9,7 @@ ; called a lot! .export tosadda0, tosaddax - .importzp sp, tmp1 + .importzp c_sp, tmp1 .macpack cpu @@ -20,34 +20,34 @@ tosaddax: .if (.cpu .bitand ::CPU_ISET_65SC02) - adc (sp) ; (7) + adc (c_sp) ; (7) tay ; (9) - inc sp ; (14) + inc c_sp ; (14) bne hiadd ; (17) - inc sp+1 ; (-1+5) + inc c_sp+1 ; (-1+5) hiadd: txa ; (19) - adc (sp) ; (24) + adc (c_sp) ; (24) tax ; (26) - inc sp ; (31) + inc c_sp ; (31) bne done ; (34) - inc sp+1 ; (-1+5) + inc c_sp+1 ; (-1+5) done: tya ; (36) .else ldy #0 ; (4) - adc (sp),y ; (9) lo byte + adc (c_sp),y ; (9) lo byte iny ; (11) sta tmp1 ; (14) save it txa ; (16) - adc (sp),y ; (21) hi byte + adc (c_sp),y ; (21) hi byte tax ; (23) clc ; (25) - lda sp ; (28) + lda c_sp ; (28) adc #2 ; (30) - sta sp ; (33) + sta c_sp ; (33) bcc L1 ; (36) - inc sp+1 ; (-1+5) + inc c_sp+1 ; (-1+5) L1: lda tmp1 ; (39) restore low byte .endif diff --git a/libsrc/runtime/addeqsp.s b/libsrc/runtime/addeqsp.s index 5112d2790..3c098ea5f 100644 --- a/libsrc/runtime/addeqsp.s +++ b/libsrc/runtime/addeqsp.s @@ -5,19 +5,19 @@ ; .export addeq0sp, addeqysp - .importzp sp + .importzp c_sp addeq0sp: ldy #0 addeqysp: clc - adc (sp),y - sta (sp),y + adc (c_sp),y + sta (c_sp),y pha iny txa - adc (sp),y - sta (sp),y + adc (c_sp),y + sta (c_sp),y tax pla rts diff --git a/libsrc/runtime/addysp.s b/libsrc/runtime/addysp.s index e0e7db1ce..d48e048bb 100644 --- a/libsrc/runtime/addysp.s +++ b/libsrc/runtime/addysp.s @@ -5,17 +5,17 @@ ; .export addysp1, addysp - .importzp sp + .importzp c_sp addysp1: iny addysp: pha ; Save A clc tya ; Get the value - adc sp ; Add low byte - sta sp ; Put it back + adc c_sp ; Add low byte + sta c_sp ; Put it back bcc @L1 ; If no carry, we're done - inc sp+1 ; Inc high byte + inc c_sp+1 ; Inc high byte @L1: pla ; Restore A rts diff --git a/libsrc/runtime/and.s b/libsrc/runtime/and.s index 8c180b580..8411660ab 100644 --- a/libsrc/runtime/and.s +++ b/libsrc/runtime/and.s @@ -6,7 +6,7 @@ .export tosanda0, tosandax .import addysp1 - .importzp sp, ptr4 + .importzp c_sp, ptr4 .macpack cpu @@ -14,16 +14,16 @@ tosanda0: ldx #$00 tosandax: .if (.cpu .bitand CPU_ISET_65SC02) - and (sp) ; 65SC02 version, saves 2 cycles and 1 byte + and (c_sp) ; 65SC02 version, saves 2 cycles and 1 byte ldy #1 .else ldy #0 - and (sp),y + and (c_sp),y iny .endif pha txa - and (sp),y + and (c_sp),y tax pla jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/bpushbsp.s b/libsrc/runtime/bpushbsp.s index 1c6add4a9..c2cc18cf6 100644 --- a/libsrc/runtime/bpushbsp.s +++ b/libsrc/runtime/bpushbsp.s @@ -6,12 +6,12 @@ .export bpushbsp, bpushbysp .import pusha - .importzp sp + .importzp c_sp bpushbsp: ldy #0 bpushbysp: - lda (sp),y + lda (c_sp),y jmp pusha diff --git a/libsrc/runtime/decsp1.s b/libsrc/runtime/decsp1.s index 3c673664a..4fd5392bb 100644 --- a/libsrc/runtime/decsp1.s +++ b/libsrc/runtime/decsp1.s @@ -5,14 +5,14 @@ ; .export decsp1 - .importzp sp + .importzp c_sp .proc decsp1 - ldy sp + ldy c_sp bne @L1 - dec sp+1 -@L1: dec sp + dec c_sp+1 +@L1: dec c_sp rts .endproc diff --git a/libsrc/runtime/decsp2.s b/libsrc/runtime/decsp2.s index a3793e778..c6c533d83 100644 --- a/libsrc/runtime/decsp2.s +++ b/libsrc/runtime/decsp2.s @@ -5,18 +5,18 @@ ; .export decsp2 - .importzp sp + .importzp c_sp .proc decsp2 - lda sp + lda c_sp sec sbc #2 - sta sp + sta c_sp bcc @L1 rts -@L1: dec sp+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp3.s b/libsrc/runtime/decsp3.s index a3ad7777e..2a2b22a15 100644 --- a/libsrc/runtime/decsp3.s +++ b/libsrc/runtime/decsp3.s @@ -5,18 +5,18 @@ ; .export decsp3 - .importzp sp + .importzp c_sp .proc decsp3 - lda sp + lda c_sp sec sbc #3 - sta sp + sta c_sp bcc @L1 rts -@L1: dec sp+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp4.s b/libsrc/runtime/decsp4.s index 5c7e94943..c756473bd 100644 --- a/libsrc/runtime/decsp4.s +++ b/libsrc/runtime/decsp4.s @@ -5,18 +5,18 @@ ; .export decsp4 - .importzp sp + .importzp c_sp .proc decsp4 - lda sp + lda c_sp sec sbc #4 - sta sp + sta c_sp bcc @L1 rts -@L1: dec sp+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp5.s b/libsrc/runtime/decsp5.s index 7ff4605cf..71b2fb176 100644 --- a/libsrc/runtime/decsp5.s +++ b/libsrc/runtime/decsp5.s @@ -5,18 +5,18 @@ ; .export decsp5 - .importzp sp + .importzp c_sp .proc decsp5 - lda sp + lda c_sp sec sbc #5 - sta sp + sta c_sp bcc @L1 rts -@L1: dec sp+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp6.s b/libsrc/runtime/decsp6.s index 6e55e664d..1d0b93136 100644 --- a/libsrc/runtime/decsp6.s +++ b/libsrc/runtime/decsp6.s @@ -5,18 +5,18 @@ ; .export decsp6 - .importzp sp + .importzp c_sp .proc decsp6 - lda sp + lda c_sp sec sbc #6 - sta sp + sta c_sp bcc @L1 rts -@L1: dec sp+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp7.s b/libsrc/runtime/decsp7.s index ee82232f6..1646d9ec9 100644 --- a/libsrc/runtime/decsp7.s +++ b/libsrc/runtime/decsp7.s @@ -5,18 +5,18 @@ ; .export decsp7 - .importzp sp + .importzp c_sp .proc decsp7 - lda sp + lda c_sp sec sbc #7 - sta sp + sta c_sp bcc @L1 rts -@L1: dec sp+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/decsp8.s b/libsrc/runtime/decsp8.s index 47d44593e..1726331c5 100644 --- a/libsrc/runtime/decsp8.s +++ b/libsrc/runtime/decsp8.s @@ -5,18 +5,18 @@ ; .export decsp8 - .importzp sp + .importzp c_sp .proc decsp8 - lda sp + lda c_sp sec sbc #8 - sta sp + sta c_sp bcc @L1 rts -@L1: dec sp+1 +@L1: dec c_sp+1 rts .endproc diff --git a/libsrc/runtime/enter.s b/libsrc/runtime/enter.s index c51b4f7bb..454c2a6f9 100644 --- a/libsrc/runtime/enter.s +++ b/libsrc/runtime/enter.s @@ -5,14 +5,14 @@ ; .export enter - .importzp sp + .importzp c_sp enter: tya ; get arg size - ldy sp + ldy c_sp bne L1 - dec sp+1 -L1: dec sp + dec c_sp+1 +L1: dec c_sp ldy #0 - sta (sp),y ; Store the arg count + sta (c_sp),y ; Store the arg count rts diff --git a/libsrc/runtime/eq.s b/libsrc/runtime/eq.s index c2a537a35..87cf1c085 100644 --- a/libsrc/runtime/eq.s +++ b/libsrc/runtime/eq.s @@ -6,7 +6,7 @@ .export toseq00, toseqa0, toseqax .import tosicmp, booleq - .importzp sp, tmp1 + .importzp c_sp, tmp1 toseq00: lda #$00 diff --git a/libsrc/runtime/icmp.s b/libsrc/runtime/icmp.s index 05c73bd01..eba8ce561 100644 --- a/libsrc/runtime/icmp.s +++ b/libsrc/runtime/icmp.s @@ -6,7 +6,7 @@ ; .export tosicmp, tosicmp0 - .importzp sp, sreg + .importzp c_sp, sreg tosicmp0: @@ -17,16 +17,16 @@ tosicmp: stx sreg+1 ; Save ax ldy #$00 - lda (sp),y ; Get low byte + lda (c_sp),y ; Get low byte tax - inc sp ; 5 + inc c_sp ; 5 bne @L1 ; 3 - inc sp+1 ; (5) + inc c_sp+1 ; (5) @L1: - lda (sp),y ; Get high byte - inc sp ; 5 + lda (c_sp),y ; Get high byte + inc c_sp ; 5 bne @L2 ; 3 - inc sp+1 ; (5) + inc c_sp+1 ; (5) ; Do the compare. diff --git a/libsrc/runtime/incsp1.s b/libsrc/runtime/incsp1.s index 2272e200f..dde6c47b2 100644 --- a/libsrc/runtime/incsp1.s +++ b/libsrc/runtime/incsp1.s @@ -5,13 +5,13 @@ ; .export incsp1 - .importzp sp + .importzp c_sp .proc incsp1 - inc sp + inc c_sp bne @L1 - inc sp+1 + inc c_sp+1 @L1: rts .endproc diff --git a/libsrc/runtime/incsp2.s b/libsrc/runtime/incsp2.s index 0ed0ffcdf..c3260c19d 100644 --- a/libsrc/runtime/incsp2.s +++ b/libsrc/runtime/incsp2.s @@ -5,7 +5,7 @@ ; this module also contains the popax function. .export popax, incsp2 - .importzp sp + .importzp c_sp .macpack cpu @@ -14,13 +14,13 @@ .proc popax ldy #1 - lda (sp),y ; get hi byte + lda (c_sp),y ; get hi byte tax ; into x .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) ; get lo byte + lda (c_sp) ; get lo byte .else dey - lda (sp),y ; get lo byte + lda (c_sp),y ; get lo byte .endif .endproc @@ -29,14 +29,14 @@ .proc incsp2 - inc sp ; 5 + inc c_sp ; 5 beq @L1 ; 2 - inc sp ; 5 + inc c_sp ; 5 beq @L2 ; 2 rts -@L1: inc sp ; 5 -@L2: inc sp+1 ; 5 +@L1: inc c_sp ; 5 +@L2: inc c_sp+1 ; 5 rts .endproc diff --git a/libsrc/runtime/ladd.s b/libsrc/runtime/ladd.s index 23b3436c0..6c187f32d 100644 --- a/libsrc/runtime/ladd.s +++ b/libsrc/runtime/ladd.s @@ -6,7 +6,7 @@ .export tosadd0ax, tosaddeax .import addysp1 - .importzp sp, sreg, tmp1 + .importzp c_sp, sreg, tmp1 .macpack cpu @@ -20,24 +20,24 @@ tosadd0ax: tosaddeax: clc .if (.cpu .bitand CPU_ISET_65SC02) - adc (sp) ; 65SC02 version - saves 2 cycles + adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else ldy #0 - adc (sp),y ; lo byte + adc (c_sp),y ; lo byte iny .endif sta tmp1 ; use as temp storage txa - adc (sp),y ; byte 1 + adc (c_sp),y ; byte 1 tax iny lda sreg - adc (sp),y ; byte 2 + adc (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - adc (sp),y ; byte 3 + adc (c_sp),y ; byte 3 sta sreg+1 lda tmp1 ; load byte 0 jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/laddeqsp.s b/libsrc/runtime/laddeqsp.s index 46c3c1f29..13dbf8112 100644 --- a/libsrc/runtime/laddeqsp.s +++ b/libsrc/runtime/laddeqsp.s @@ -5,29 +5,29 @@ ; .export laddeq0sp, laddeqysp - .importzp sp, sreg + .importzp c_sp, sreg laddeq0sp: ldy #0 laddeqysp: clc - adc (sp),y - sta (sp),y + adc (c_sp),y + sta (c_sp),y pha iny txa - adc (sp),y - sta (sp),y + adc (c_sp),y + sta (c_sp),y tax iny lda sreg - adc (sp),y - sta (sp),y + adc (c_sp),y + sta (c_sp),y sta sreg iny lda sreg+1 - adc (sp),y - sta (sp),y + adc (c_sp),y + sta (c_sp),y sta sreg+1 pla rts diff --git a/libsrc/runtime/land.s b/libsrc/runtime/land.s index 8e21ebb60..400fede3b 100644 --- a/libsrc/runtime/land.s +++ b/libsrc/runtime/land.s @@ -7,7 +7,7 @@ .export tosand0ax, tosandeax .import addysp1 - .importzp sp, sreg, tmp1 + .importzp c_sp, sreg, tmp1 .macpack cpu @@ -23,24 +23,24 @@ tosand0ax: tosandeax: .if (.cpu .bitand ::CPU_ISET_65SC02) - and (sp) ; byte 0 + and (c_sp) ; byte 0 ldy #1 .else ldy #0 - and (sp),y ; byte 0 + and (c_sp),y ; byte 0 iny .endif sta tmp1 txa - and (sp),y ; byte 1 + and (c_sp),y ; byte 1 tax iny lda sreg - and (sp),y ; byte 2 + and (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - and (sp),y ; byte 3 + and (c_sp),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/lcmp.s b/libsrc/runtime/lcmp.s index d0ba4d81f..59c02dd56 100644 --- a/libsrc/runtime/lcmp.s +++ b/libsrc/runtime/lcmp.s @@ -7,7 +7,7 @@ .export toslcmp .import incsp4 - .importzp sp, sreg, ptr1 + .importzp c_sp, sreg, ptr1 toslcmp: @@ -15,23 +15,23 @@ toslcmp: stx ptr1+1 ; EAX now in sreg:ptr1 ldy #$03 - lda (sp),y + lda (c_sp),y sec sbc sreg+1 bne L4 dey - lda (sp),y + lda (c_sp),y cmp sreg bne L1 dey - lda (sp),y + lda (c_sp),y cmp ptr1+1 bne L1 dey - lda (sp),y + lda (c_sp),y cmp ptr1 L1: php ; Save flags diff --git a/libsrc/runtime/ldau0sp.s b/libsrc/runtime/ldau0sp.s index a986d52da..a808f6f84 100644 --- a/libsrc/runtime/ldau0sp.s +++ b/libsrc/runtime/ldau0sp.s @@ -5,17 +5,17 @@ ; .export ldau00sp, ldau0ysp - .importzp sp, ptr1 + .importzp c_sp, ptr1 .macpack cpu ldau00sp: ldy #1 ldau0ysp: - lda (sp),y + lda (c_sp),y sta ptr1+1 dey - lda (sp),y + lda (c_sp),y sta ptr1 ldx #0 .if (.cpu .bitand CPU_ISET_65SC02) diff --git a/libsrc/runtime/ldauisp.s b/libsrc/runtime/ldauisp.s index 54f4d1bd1..957f245be 100644 --- a/libsrc/runtime/ldauisp.s +++ b/libsrc/runtime/ldauisp.s @@ -5,15 +5,15 @@ ; .export ldaui0sp, ldauiysp - .importzp sp, ptr1 + .importzp c_sp, ptr1 ldaui0sp: ldy #1 ldauiysp: - lda (sp),y + lda (c_sp),y sta ptr1+1 dey - lda (sp),y + lda (c_sp),y sta ptr1 txa tay diff --git a/libsrc/runtime/ldaxsp.s b/libsrc/runtime/ldaxsp.s index aa94b43cd..b744ce242 100644 --- a/libsrc/runtime/ldaxsp.s +++ b/libsrc/runtime/ldaxsp.s @@ -5,16 +5,16 @@ ; .export ldax0sp, ldaxysp - .importzp sp + .importzp c_sp ; Beware: The optimizer knows about the value in Y after return! ldax0sp: ldy #1 ldaxysp: - lda (sp),y ; get high byte + lda (c_sp),y ; get high byte tax ; and save it dey ; point to lo byte - lda (sp),y ; load low byte + lda (c_sp),y ; load low byte rts diff --git a/libsrc/runtime/ldeaxysp.s b/libsrc/runtime/ldeaxysp.s index 1d65e9c38..b6ce7254f 100644 --- a/libsrc/runtime/ldeaxysp.s +++ b/libsrc/runtime/ldeaxysp.s @@ -9,20 +9,20 @@ .export ldeax0sp, ldeaxysp - .importzp sreg, sp + .importzp sreg, c_sp ldeax0sp: ldy #3 ldeaxysp: - lda (sp),y + lda (c_sp),y sta sreg+1 dey - lda (sp),y + lda (c_sp),y sta sreg dey - lda (sp),y + lda (c_sp),y tax dey - lda (sp),y + lda (c_sp),y rts diff --git a/libsrc/runtime/leaaxsp.s b/libsrc/runtime/leaaxsp.s index 0741170ca..451d7191f 100644 --- a/libsrc/runtime/leaaxsp.s +++ b/libsrc/runtime/leaaxsp.s @@ -5,16 +5,16 @@ ; .export leaaxsp, leaa0sp - .importzp sp + .importzp c_sp leaa0sp: ldx #$00 leaaxsp: clc - adc sp + adc c_sp pha txa - adc sp+1 + adc c_sp+1 tax pla rts diff --git a/libsrc/runtime/leave.s b/libsrc/runtime/leave.s index 95dcdec9d..408fdd159 100644 --- a/libsrc/runtime/leave.s +++ b/libsrc/runtime/leave.s @@ -12,7 +12,7 @@ .export leave00, leave0, leavey00, leavey0, leavey .export leave .import addysp - .importzp sp + .importzp c_sp .macpack cpu @@ -31,24 +31,24 @@ leavey: .if (.cpu .bitand ::CPU_ISET_65SC02) leave: tay ; save A a sec - lda (sp) ; that's the pushed arg size + lda (c_sp) ; that's the pushed arg size sec ; Count the byte, the count's stored in - adc sp - sta sp + adc c_sp + sta c_sp bcc L1 - inc sp+1 + inc c_sp+1 L1: tya ; Get return value back .else leave: pha ; save A a sec ldy #0 - lda (sp),y ; that's the pushed arg size + lda (c_sp),y ; that's the pushed arg size sec ; Count the byte, the count's stored in - adc sp - sta sp + adc c_sp + sta c_sp bcc L1 - inc sp+1 + inc c_sp+1 L1: pla ; Get return value back .endif diff --git a/libsrc/runtime/lmul.s b/libsrc/runtime/lmul.s index 90d5f1e97..a68c3e5c1 100644 --- a/libsrc/runtime/lmul.s +++ b/libsrc/runtime/lmul.s @@ -7,7 +7,7 @@ .export tosumul0ax, tosumuleax, tosmul0ax, tosmuleax .import addysp1 - .importzp sp, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 + .importzp c_sp, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 .macpack cpu @@ -27,21 +27,21 @@ tosumuleax: mul32: sta ptr1 stx ptr1+1 ; op2 now in ptr1/sreg .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (c_sp) ldy #1 .else ldy #0 - lda (sp),y + lda (c_sp),y iny .endif sta ptr3 - lda (sp),y + lda (c_sp),y sta ptr3+1 iny - lda (sp),y + lda (c_sp),y sta ptr4 iny - lda (sp),y + lda (c_sp),y sta ptr4+1 ; op1 in pre3/ptr4 jsr addysp1 ; Drop TOS diff --git a/libsrc/runtime/lor.s b/libsrc/runtime/lor.s index f2204b981..888a0c611 100644 --- a/libsrc/runtime/lor.s +++ b/libsrc/runtime/lor.s @@ -7,7 +7,7 @@ .export tosor0ax, tosoreax .import addysp1 - .importzp sp, sreg, tmp1 + .importzp c_sp, sreg, tmp1 .macpack cpu @@ -23,24 +23,24 @@ tosor0ax: tosoreax: .if (.cpu .bitand ::CPU_ISET_65SC02) - ora (sp) + ora (c_sp) ldy #1 .else ldy #0 - ora (sp),y ; byte 0 + ora (c_sp),y ; byte 0 iny .endif sta tmp1 txa - ora (sp),y ; byte 1 + ora (c_sp),y ; byte 1 tax iny lda sreg - ora (sp),y ; byte 2 + ora (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - ora (sp),y ; byte 3 + ora (c_sp),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/lpop.s b/libsrc/runtime/lpop.s index a90ea5fcb..9690aff24 100644 --- a/libsrc/runtime/lpop.s +++ b/libsrc/runtime/lpop.s @@ -7,24 +7,24 @@ .export popeax .import incsp4 - .importzp sp, sreg + .importzp c_sp, sreg .macpack cpu popeax: ldy #3 - lda (sp),y + lda (c_sp),y sta sreg+1 dey - lda (sp),y + lda (c_sp),y sta sreg dey - lda (sp),y + lda (c_sp),y tax .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (c_sp) .else dey - lda (sp),y + lda (c_sp),y .endif jmp incsp4 diff --git a/libsrc/runtime/lpush.s b/libsrc/runtime/lpush.s index 0bc67b523..ec2c865af 100644 --- a/libsrc/runtime/lpush.s +++ b/libsrc/runtime/lpush.s @@ -10,7 +10,7 @@ ; .export pushl0, push0ax, pusheax .import decsp4 - .importzp sp, sreg + .importzp c_sp, sreg .macpack cpu @@ -31,19 +31,19 @@ pusheax: jsr decsp4 ldy #3 lda sreg+1 - sta (sp),y + sta (c_sp),y dey lda sreg - sta (sp),y + sta (c_sp),y dey txa - sta (sp),y + sta (c_sp),y pla .if (.cpu .bitand ::CPU_ISET_65SC02) - sta (sp) + sta (c_sp) .else dey - sta (sp),y + sta (c_sp),y .endif rts diff --git a/libsrc/runtime/lrsub.s b/libsrc/runtime/lrsub.s index 5e8d0b543..456d8d8d5 100644 --- a/libsrc/runtime/lrsub.s +++ b/libsrc/runtime/lrsub.s @@ -10,7 +10,7 @@ ; .export tosrsub0ax, tosrsubeax .import addysp1 - .importzp sp, sreg, tmp1 + .importzp c_sp, sreg, tmp1 .macpack cpu @@ -27,24 +27,24 @@ tosrsub0ax: tosrsubeax: sec .if (.cpu .bitand ::CPU_ISET_65SC02) - sbc (sp) + sbc (c_sp) ldy #1 .else ldy #0 - sbc (sp),y ; byte 0 + sbc (c_sp),y ; byte 0 iny .endif sta tmp1 ; use as temp storage txa - sbc (sp),y ; byte 1 + sbc (c_sp),y ; byte 1 tax iny lda sreg - sbc (sp),y ; byte 2 + sbc (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - sbc (sp),y ; byte 3 + sbc (c_sp),y ; byte 3 sta sreg+1 lda tmp1 jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/lsub.s b/libsrc/runtime/lsub.s index 4c50ded14..17b225404 100644 --- a/libsrc/runtime/lsub.s +++ b/libsrc/runtime/lsub.s @@ -9,7 +9,7 @@ ; .export tossub0ax, tossubeax .import addysp1 - .importzp sp, sreg + .importzp c_sp, sreg .macpack cpu @@ -27,24 +27,24 @@ tossubeax: sec eor #$FF .if (.cpu .bitand ::CPU_ISET_65SC02) - adc (sp) ; 65SC02 version - saves 2 cycles + adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else ldy #0 - adc (sp),y ; lo byte + adc (c_sp),y ; lo byte iny .endif pha ; Save low byte txa eor #$FF - adc (sp),y ; byte 1 + adc (c_sp),y ; byte 1 tax iny - lda (sp),y + lda (c_sp),y sbc sreg ; byte 2 sta sreg iny - lda (sp),y + lda (c_sp),y sbc sreg+1 ; byte 3 sta sreg+1 pla ; Restore byte 0 diff --git a/libsrc/runtime/lsubeqsp.s b/libsrc/runtime/lsubeqsp.s index f32930c69..6f8377484 100644 --- a/libsrc/runtime/lsubeqsp.s +++ b/libsrc/runtime/lsubeqsp.s @@ -5,31 +5,31 @@ ; .export lsubeq0sp, lsubeqysp - .importzp sp, sreg + .importzp c_sp, sreg lsubeq0sp: ldy #0 lsubeqysp: sec eor #$FF - adc (sp),y - sta (sp),y + adc (c_sp),y + sta (c_sp),y pha ; Save low byte iny txa eor #$FF - adc (sp),y - sta (sp),y + adc (c_sp),y + sta (c_sp),y tax iny - lda (sp),y + lda (c_sp),y sbc sreg - sta (sp),y + sta (c_sp),y sta sreg iny - lda (sp),y + lda (c_sp),y sbc sreg+1 - sta (sp),y + sta (c_sp),y sta sreg+1 pla rts diff --git a/libsrc/runtime/ludiv.s b/libsrc/runtime/ludiv.s index 77335d8f5..b47207222 100644 --- a/libsrc/runtime/ludiv.s +++ b/libsrc/runtime/ludiv.s @@ -7,7 +7,7 @@ .export tosudiv0ax, tosudiveax, getlop, udiv32 .import addysp1 - .importzp sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 + .importzp c_sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 .macpack cpu @@ -39,21 +39,21 @@ getlop: sta ptr3 ; Put right operand in place sta ptr4+1 .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (c_sp) ldy #1 .else ldy #0 ; Put left operand in place - lda (sp),y + lda (c_sp),y iny .endif sta ptr1 - lda (sp),y + lda (c_sp),y sta ptr1+1 iny - lda (sp),y + lda (c_sp),y sta sreg iny - lda (sp),y + lda (c_sp),y sta sreg+1 jmp addysp1 ; Drop parameters diff --git a/libsrc/runtime/lxor.s b/libsrc/runtime/lxor.s index a92a59959..6d9f7db3a 100644 --- a/libsrc/runtime/lxor.s +++ b/libsrc/runtime/lxor.s @@ -7,7 +7,7 @@ .export tosxor0ax, tosxoreax .import addysp1 - .importzp sp, sreg, tmp1 + .importzp c_sp, sreg, tmp1 .macpack cpu @@ -23,24 +23,24 @@ tosxor0ax: tosxoreax: .if (.cpu .bitand ::CPU_ISET_65SC02) - eor (sp) ; byte 0 + eor (c_sp) ; byte 0 ldy #1 .else ldy #0 - eor (sp),y ; byte 0 + eor (c_sp),y ; byte 0 iny .endif sta tmp1 txa - eor (sp),y ; byte 1 + eor (c_sp),y ; byte 1 tax iny lda sreg - eor (sp),y ; byte 2 + eor (c_sp),y ; byte 2 sta sreg iny lda sreg+1 - eor (sp),y ; byte 3 + eor (c_sp),y ; byte 3 sta sreg+1 lda tmp1 diff --git a/libsrc/runtime/or.s b/libsrc/runtime/or.s index 735f30f61..04389be5f 100644 --- a/libsrc/runtime/or.s +++ b/libsrc/runtime/or.s @@ -7,7 +7,7 @@ .export tosora0, tosorax .import addysp1 - .importzp sp, tmp1 + .importzp c_sp, tmp1 .macpack cpu @@ -15,16 +15,16 @@ tosora0: ldx #$00 tosorax: .if (.cpu .bitand ::CPU_ISET_65SC02) - ora (sp) + ora (c_sp) ldy #1 .else ldy #0 - ora (sp),y + ora (c_sp),y iny .endif sta tmp1 txa - ora (sp),y + ora (c_sp),y tax lda tmp1 jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/popa.s b/libsrc/runtime/popa.s index bb74df0ca..c1700071d 100644 --- a/libsrc/runtime/popa.s +++ b/libsrc/runtime/popa.s @@ -5,23 +5,23 @@ ; .export popa - .importzp sp + .importzp c_sp .macpack cpu .proc popa .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (c_sp) .else ldy #0 ; (2) - lda (sp),y ; (7) Read byte + lda (c_sp),y ; (7) Read byte .endif - inc sp ; (12) + inc c_sp ; (12) beq @L1 ; (14) rts ; (20) -@L1: inc sp+1 +@L1: inc c_sp+1 rts .endproc diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index b54bb9eb3..45043dd27 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -6,19 +6,19 @@ .export popptr1 .import incsp2 - .importzp sp, ptr1 + .importzp c_sp, ptr1 .macpack cpu .proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) ldy #1 - lda (sp),y ; get hi byte + lda (c_sp),y ; get hi byte sta ptr1+1 ; into ptr hi dey ; dey even for for 65C02 here to have Y=0 at exit! .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) ; get lo byte + lda (c_sp) ; get lo byte .else - lda (sp),y ; get lo byte + lda (c_sp),y ; get lo byte .endif sta ptr1 ; to ptr lo jmp incsp2 diff --git a/libsrc/runtime/popsreg.s b/libsrc/runtime/popsreg.s index 47d67503a..c7f667246 100644 --- a/libsrc/runtime/popsreg.s +++ b/libsrc/runtime/popsreg.s @@ -6,20 +6,20 @@ .export popsreg .import incsp2 - .importzp sp, sreg + .importzp c_sp, sreg .macpack cpu popsreg: pha ; save A ldy #1 - lda (sp),y ; get hi byte + lda (c_sp),y ; get hi byte sta sreg+1 ; store it .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) ; get lo byte + lda (c_sp) ; get lo byte .else dey - lda (sp),y ; get lo byte + lda (c_sp),y ; get lo byte .endif sta sreg ; store it pla ; get A back diff --git a/libsrc/runtime/pusha.s b/libsrc/runtime/pusha.s index 04233282e..399423077 100644 --- a/libsrc/runtime/pusha.s +++ b/libsrc/runtime/pusha.s @@ -5,7 +5,7 @@ ; .export pusha0sp, pushaysp, pusha - .importzp sp + .importzp c_sp .macpack cpu @@ -14,16 +14,16 @@ pusha0sp: ldy #$00 pushaysp: - lda (sp),y -pusha: ldy sp ; (3) + lda (c_sp),y +pusha: ldy c_sp ; (3) beq @L1 ; (6) - dec sp ; (11) + dec c_sp ; (11) ldy #0 ; (13) - sta (sp),y ; (19) + sta (c_sp),y ; (19) rts ; (25) -@L1: dec sp+1 ; (11) - dec sp ; (16) - sta (sp),y ; (22) +@L1: dec c_sp+1 ; (11) + dec c_sp ; (16) + sta (c_sp),y ; (22) rts ; (28) diff --git a/libsrc/runtime/pushax.s b/libsrc/runtime/pushax.s index 27ddf641d..f77a9bcc3 100644 --- a/libsrc/runtime/pushax.s +++ b/libsrc/runtime/pushax.s @@ -5,7 +5,7 @@ ; .export push0, pusha0, pushax - .importzp sp + .importzp c_sp .macpack cpu @@ -20,21 +20,21 @@ pusha0: ldx #0 .proc pushax pha ; (3) - lda sp ; (6) + lda c_sp ; (6) sec ; (8) sbc #2 ; (10) - sta sp ; (13) + sta c_sp ; (13) bcs @L1 ; (17) - dec sp+1 ; (+5) + dec c_sp+1 ; (+5) @L1: ldy #1 ; (19) txa ; (21) - sta (sp),y ; (27) + sta (c_sp),y ; (27) pla ; (31) dey ; (33) .if (.cpu .bitand ::CPU_ISET_65SC02) - sta (sp) ; (37) + sta (c_sp) ; (37) .else - sta (sp),y ; (38) + sta (c_sp),y ; (38) .endif rts ; (44/43) diff --git a/libsrc/runtime/pushbsp.s b/libsrc/runtime/pushbsp.s index 0b5cbe854..45ad93b12 100644 --- a/libsrc/runtime/pushbsp.s +++ b/libsrc/runtime/pushbsp.s @@ -6,12 +6,12 @@ .export pushbsp, pushbysp .import pusha0 - .importzp sp + .importzp c_sp pushbsp: ldy #0 pushbysp: - lda (sp),y ; get lo byte + lda (c_sp),y ; get lo byte jmp pusha0 ; promote to unsigned and push diff --git a/libsrc/runtime/pushlysp.s b/libsrc/runtime/pushlysp.s index ca1834265..86bb87dbd 100644 --- a/libsrc/runtime/pushlysp.s +++ b/libsrc/runtime/pushlysp.s @@ -7,23 +7,23 @@ .export pushlysp .import pusheax - .importzp sreg, sp + .importzp sreg, c_sp .proc pushlysp iny iny - lda (sp),y + lda (c_sp),y iny sta sreg - lda (sp),y + lda (c_sp),y sta sreg+1 dey dey - lda (sp),y + lda (c_sp),y dey tax - lda (sp),y + lda (c_sp),y jmp pusheax .endproc diff --git a/libsrc/runtime/pushwsp.s b/libsrc/runtime/pushwsp.s index f5ebe0d7e..31c08d624 100644 --- a/libsrc/runtime/pushwsp.s +++ b/libsrc/runtime/pushwsp.s @@ -5,27 +5,27 @@ ; .export pushwysp, pushw0sp - .importzp sp + .importzp c_sp .macpack generic pushw0sp: ldy #3 pushwysp: - lda sp ; 3 + lda c_sp ; 3 sub #2 ; 4 - sta sp ; 3 + sta c_sp ; 3 bcs @L1 ; 3(+1) - dec sp+1 ; (5) -@L1: lda (sp),y ; 5 =16 + dec c_sp+1 ; (5) +@L1: lda (c_sp),y ; 5 =16 tax ; 2 dey ; 2 - lda (sp),y ; 5 + lda (c_sp),y ; 5 ldy #$00 ; 2 - sta (sp),y ; 5 + sta (c_sp),y ; 5 iny ; 2 txa ; 2 - sta (sp),y ; 5 + sta (c_sp),y ; 5 rts diff --git a/libsrc/runtime/regswap.s b/libsrc/runtime/regswap.s index 689d8d12a..17db9ee27 100644 --- a/libsrc/runtime/regswap.s +++ b/libsrc/runtime/regswap.s @@ -5,17 +5,17 @@ ; .export regswap - .importzp sp, regbank, tmp1 + .importzp c_sp, regbank, tmp1 .proc regswap sta tmp1 ; Store count @L1: lda regbank,x ; Get old value pha ; Save it - lda (sp),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank,x ; Store new value pla - sta (sp),y ; Store old value + sta (c_sp),y ; Store old value inx iny dec tmp1 diff --git a/libsrc/runtime/regswap1.s b/libsrc/runtime/regswap1.s index 753020acb..22cf170dc 100644 --- a/libsrc/runtime/regswap1.s +++ b/libsrc/runtime/regswap1.s @@ -5,16 +5,16 @@ ; .export regswap1 - .importzp sp, regbank + .importzp c_sp, regbank .proc regswap1 lda regbank,x ; Get old value pha ; Save it - lda (sp),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank,x ; Store new value pla - sta (sp),y ; Store old value + sta (c_sp),y ; Store old value rts .endproc diff --git a/libsrc/runtime/regswap2.s b/libsrc/runtime/regswap2.s index df5109dc6..07bc7c196 100644 --- a/libsrc/runtime/regswap2.s +++ b/libsrc/runtime/regswap2.s @@ -5,7 +5,7 @@ ; .export regswap2 - .importzp sp, regbank + .importzp c_sp, regbank .proc regswap2 @@ -13,20 +13,20 @@ lda regbank,x ; Get old value pha ; Save it - lda (sp),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank,x ; Store new value pla - sta (sp),y ; Store old value + sta (c_sp),y ; Store old value ; Second byte iny lda regbank+1,x ; Get old value pha ; Save it - lda (sp),y ; Get stack loc + lda (c_sp),y ; Get stack loc sta regbank+1,x ; Store new value pla - sta (sp),y ; Store old value + sta (c_sp),y ; Store old value rts diff --git a/libsrc/runtime/rsub.s b/libsrc/runtime/rsub.s index 69ee6da22..bacb3c7fc 100644 --- a/libsrc/runtime/rsub.s +++ b/libsrc/runtime/rsub.s @@ -7,7 +7,7 @@ .export tosrsuba0, tosrsubax .import addysp1 - .importzp sp, tmp1 + .importzp c_sp, tmp1 .macpack cpu @@ -20,16 +20,16 @@ tosrsuba0: tosrsubax: sec .if (.cpu .bitand CPU_ISET_65SC02) - sbc (sp) + sbc (c_sp) ldy #1 .else ldy #0 - sbc (sp),y ; lo byte + sbc (c_sp),y ; lo byte iny .endif sta tmp1 ; save lo byte txa - sbc (sp),y ; hi byte + sbc (c_sp),y ; hi byte tax lda tmp1 jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/staspidx.s b/libsrc/runtime/staspidx.s index c8d42f34c..bd9b0c79d 100644 --- a/libsrc/runtime/staspidx.s +++ b/libsrc/runtime/staspidx.s @@ -6,17 +6,17 @@ .export staspidx .import incsp2 - .importzp sp, tmp1, ptr1 + .importzp c_sp, tmp1, ptr1 .proc staspidx pha sty tmp1 ; Save Index ldy #1 - lda (sp),y + lda (c_sp),y sta ptr1+1 dey - lda (sp),y + lda (c_sp),y sta ptr1 ; Pointer now in ptr1 ldy tmp1 ; Restore offset pla ; Restore value diff --git a/libsrc/runtime/staxsp.s b/libsrc/runtime/staxsp.s index 599e92a32..15bec22ee 100644 --- a/libsrc/runtime/staxsp.s +++ b/libsrc/runtime/staxsp.s @@ -1,20 +1,20 @@ ; ; Ullrich von Bassewitz, 31.08.1998 ; -; CC65 runtime: Store ax at (sp),y +; CC65 runtime: Store ax at (c_sp),y ; .export staxysp, stax0sp - .importzp sp + .importzp c_sp stax0sp: ldy #0 staxysp: - sta (sp),y + sta (c_sp),y iny pha txa - sta (sp),y + sta (c_sp),y pla rts diff --git a/libsrc/runtime/staxspi.s b/libsrc/runtime/staxspi.s index 3114f449c..aefed428f 100644 --- a/libsrc/runtime/staxspi.s +++ b/libsrc/runtime/staxspi.s @@ -7,7 +7,7 @@ .export staxspidx .import incsp2 - .importzp sp, tmp1, ptr1 + .importzp c_sp, tmp1, ptr1 .macpack cpu @@ -16,13 +16,13 @@ sty tmp1 ; Save Y pha ; Save A ldy #1 - lda (sp),y + lda (c_sp),y sta ptr1+1 .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (c_sp) .else dey - lda (sp),y + lda (c_sp),y .endif sta ptr1 ; Address now in ptr1 ldy tmp1 ; Restore Y diff --git a/libsrc/runtime/steaxsp.s b/libsrc/runtime/steaxsp.s index 6ac3891c9..33dbc04d7 100644 --- a/libsrc/runtime/steaxsp.s +++ b/libsrc/runtime/steaxsp.s @@ -1,26 +1,26 @@ ; ; Ullrich von Bassewitz, 31.08.1998 ; -; CC65 runtime: Store eax at (sp),y +; CC65 runtime: Store eax at (c_sp),y ; .export steaxysp, steax0sp - .importzp sp, sreg + .importzp c_sp, sreg steax0sp: ldy #0 steaxysp: - sta (sp),y + sta (c_sp),y iny pha txa - sta (sp),y + sta (c_sp),y iny lda sreg - sta (sp),y + sta (c_sp),y iny lda sreg+1 - sta (sp),y + sta (c_sp),y pla rts diff --git a/libsrc/runtime/stkchk.s b/libsrc/runtime/stkchk.s index ceab4c703..a7ca39f21 100644 --- a/libsrc/runtime/stkchk.s +++ b/libsrc/runtime/stkchk.s @@ -17,7 +17,7 @@ .constructor initstkchk, 25 .import __STACKSIZE__ ; Linker defined .import pusha0, _exit - .importzp sp + .importzp c_sp ; Use macros for better readability .macpack generic @@ -32,11 +32,11 @@ .proc initstkchk - lda sp + lda c_sp sta initialsp sub #<__STACKSIZE__ sta lowwater - lda sp+1 + lda c_sp+1 sta initialsp+1 sbc #>__STACKSIZE__ .if (.cpu .bitand ::CPU_ISET_65SC02) @@ -70,7 +70,7 @@ cstkchk: ; Check the high byte of the software stack @L0: lda lowwater+1 - cmp sp+1 + cmp c_sp+1 bcs @L1 rts @@ -78,7 +78,7 @@ cstkchk: @L1: bne CStackOverflow lda lowwater - cmp sp + cmp c_sp bcs CStackOverflow Done: rts @@ -87,9 +87,9 @@ Done: rts CStackOverflow: lda initialsp - sta sp + sta c_sp lda initialsp+1 - sta sp+1 + sta c_sp+1 ; Generic abort entry. We should output a diagnostic here, but this is ; difficult, since we're operating at a lower level here. diff --git a/libsrc/runtime/sub.s b/libsrc/runtime/sub.s index b41df3d91..58ffb4c91 100644 --- a/libsrc/runtime/sub.s +++ b/libsrc/runtime/sub.s @@ -6,7 +6,7 @@ .export tossuba0, tossubax .import addysp1 - .importzp sp + .importzp c_sp .macpack cpu @@ -18,17 +18,17 @@ tossubax: sec eor #$FF .if (.cpu .bitand CPU_ISET_65SC02) - adc (sp) + adc (c_sp) ldy #1 .else ldy #0 - adc (sp),y ; Subtract low byte + adc (c_sp),y ; Subtract low byte iny .endif pha ; Save high byte txa eor #$FF - adc (sp),y ; Subtract high byte + adc (c_sp),y ; Subtract high byte tax ; High byte into X pla ; Restore low byte jmp addysp1 ; drop TOS diff --git a/libsrc/runtime/subeqsp.s b/libsrc/runtime/subeqsp.s index 24080d97d..880e5f2fc 100644 --- a/libsrc/runtime/subeqsp.s +++ b/libsrc/runtime/subeqsp.s @@ -5,21 +5,21 @@ ; .export subeq0sp, subeqysp - .importzp sp + .importzp c_sp subeq0sp: ldy #0 subeqysp: sec eor #$FF - adc (sp),y - sta (sp),y + adc (c_sp),y + sta (c_sp),y pha ; Save low byte iny txa eor #$FF - adc (sp),y - sta (sp),y + adc (c_sp),y + sta (c_sp),y tax pla ; Restore low byte rts diff --git a/libsrc/runtime/subysp.s b/libsrc/runtime/subysp.s index 9fae44222..8f5bea806 100644 --- a/libsrc/runtime/subysp.s +++ b/libsrc/runtime/subysp.s @@ -6,17 +6,17 @@ ; .export subysp - .importzp sp + .importzp c_sp .proc subysp tya eor #$ff sec - adc sp - sta sp + adc c_sp + sta c_sp bcs @L1 - dec sp+1 + dec c_sp+1 @L1: rts .endproc diff --git a/libsrc/runtime/swap.s b/libsrc/runtime/swap.s index 5358e08d3..3796b0a97 100644 --- a/libsrc/runtime/swap.s +++ b/libsrc/runtime/swap.s @@ -6,7 +6,7 @@ ; .export swapstk - .importzp sp, ptr4 + .importzp c_sp, ptr4 .macpack cpu @@ -14,22 +14,22 @@ swapstk: sta ptr4 stx ptr4+1 ldy #1 ; index - lda (sp),y + lda (c_sp),y tax lda ptr4+1 - sta (sp),y + sta (c_sp),y .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (c_sp) tay lda ptr4 - sta (sp) + sta (c_sp) tya .else dey - lda (sp),y + lda (c_sp),y pha lda ptr4 - sta (sp),y + sta (c_sp),y pla .endif rts ; whew! diff --git a/libsrc/runtime/tosint.s b/libsrc/runtime/tosint.s index ed32298bd..2aaa19ccc 100644 --- a/libsrc/runtime/tosint.s +++ b/libsrc/runtime/tosint.s @@ -6,7 +6,7 @@ .export tosint .import incsp2 - .importzp sp + .importzp c_sp .macpack cpu @@ -16,17 +16,17 @@ pha .if (.cpu .bitand ::CPU_ISET_65SC02) - lda (sp) + lda (c_sp) .else ldy #0 - lda (sp),y ; sp+1 + lda (c_sp),y ; c_sp+1 .endif ldy #2 - sta (sp),y + sta (c_sp),y dey - lda (sp),y + lda (c_sp),y ldy #3 - sta (sp),y + sta (c_sp),y pla jmp incsp2 ; Drop 16 bit diff --git a/libsrc/runtime/toslong.s b/libsrc/runtime/toslong.s index 9065d3e6c..cf8eff031 100644 --- a/libsrc/runtime/toslong.s +++ b/libsrc/runtime/toslong.s @@ -6,7 +6,7 @@ .export tosulong, toslong .import decsp2 - .importzp sp + .importzp c_sp .macpack cpu @@ -16,25 +16,25 @@ tosulong: pha jsr decsp2 ; Make room ldy #2 - lda (sp),y + lda (c_sp),y .if (.cpu .bitand CPU_ISET_65SC02) - sta (sp) ; 65C02 version + sta (c_sp) ; 65C02 version iny ; Y = 3 .else ldy #0 - sta (sp),y + sta (c_sp),y ldy #3 .endif - lda (sp),y + lda (c_sp),y toslong1: ldy #1 - sta (sp),y + sta (c_sp),y lda #0 ; Zero extend toslong2: iny - sta (sp),y + sta (c_sp),y iny - sta (sp),y + sta (c_sp),y pla rts @@ -42,19 +42,19 @@ toslong: pha jsr decsp2 ; Make room ldy #2 - lda (sp),y + lda (c_sp),y .if (.cpu .bitand CPU_ISET_65SC02) - sta (sp) ; 65C02 version + sta (c_sp) ; 65C02 version iny ; Y = 3 .else ldy #0 - sta (sp),y + sta (c_sp),y ldy #3 .endif - lda (sp),y + lda (c_sp),y bpl toslong1 ; Jump if positive, high word is zero ldy #1 - sta (sp),y + sta (c_sp),y lda #$FF bne toslong2 ; Branch always diff --git a/libsrc/runtime/xor.s b/libsrc/runtime/xor.s index e03922926..15394413c 100644 --- a/libsrc/runtime/xor.s +++ b/libsrc/runtime/xor.s @@ -7,7 +7,7 @@ .export tosxora0, tosxorax .import addysp1 - .importzp sp, tmp1 + .importzp c_sp, tmp1 .macpack cpu @@ -15,16 +15,16 @@ tosxora0: ldx #$00 tosxorax: .if (.cpu .bitand CPU_ISET_65SC02) - eor (sp) + eor (c_sp) ldy #1 .else ldy #0 - eor (sp),y + eor (c_sp),y iny .endif sta tmp1 txa - eor (sp),y + eor (c_sp),y tax lda tmp1 jmp addysp1 ; drop TOS, set condition codes diff --git a/libsrc/runtime/zeropage.s b/libsrc/runtime/zeropage.s index 2bbe7ceee..75856f751 100644 --- a/libsrc/runtime/zeropage.s +++ b/libsrc/runtime/zeropage.s @@ -10,7 +10,7 @@ .zeropage -sp: .res 2 ; Stack pointer +c_sp: .res 2 ; Stack pointer sreg: .res 2 ; Secondary register/high 16 bit for longs regsave: .res 4 ; Slot to save/restore (E)AX into ptr1: .res 2 diff --git a/libsrc/sim6502/crt0.s b/libsrc/sim6502/crt0.s index c04a2b8a6..26be7888b 100644 --- a/libsrc/sim6502/crt0.s +++ b/libsrc/sim6502/crt0.s @@ -22,8 +22,8 @@ startup:cld txs lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 + sta c_sp + stx c_sp+1 jsr zerobss jsr initlib jsr callmain diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s index 6487e5b0c..224b2af2d 100644 --- a/libsrc/sim6502/exehdr.s +++ b/libsrc/sim6502/exehdr.s @@ -5,7 +5,7 @@ ; .export __EXEHDR__ : absolute = 1 ; Linker referenced - .importzp sp + .importzp c_sp .import __MAIN_START__ .import startup @@ -24,6 +24,6 @@ .else .error Unknown CPU type. .endif - .byte sp ; sp address + .byte c_sp ; c_sp address .addr __MAIN_START__ ; load address .addr startup ; reset address diff --git a/libsrc/supervision/crt0.s b/libsrc/supervision/crt0.s index fbae1fc46..1cfba1845 100644 --- a/libsrc/supervision/crt0.s +++ b/libsrc/supervision/crt0.s @@ -33,8 +33,8 @@ reset: lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) ldx #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr jsr initlib jsr _main _exit: jsr donelib diff --git a/libsrc/sym1/crt0.s b/libsrc/sym1/crt0.s index 5d4e0449b..d20b4cf6c 100644 --- a/libsrc/sym1/crt0.s +++ b/libsrc/sym1/crt0.s @@ -33,9 +33,9 @@ _init: jsr ACCESS ; Unlock System RAM ; Set cc65 argument stack pointer lda #<(__RAM_START__ + __RAM_SIZE__) - sta sp + sta c_sp lda #>(__RAM_START__ + __RAM_SIZE__) - sta sp+1 + sta c_sp+1 ; Initialize memory storage diff --git a/libsrc/telestrat/crt0.s b/libsrc/telestrat/crt0.s index df75520ce..aa32ed0d0 100644 --- a/libsrc/telestrat/crt0.s +++ b/libsrc/telestrat/crt0.s @@ -47,7 +47,7 @@ _exit: jsr donelib ldx #zpspace - 1 L2: lda zpsave,x - sta sp,x + sta c_sp,x dex bpl L2 @@ -64,7 +64,7 @@ L2: lda zpsave,x ; Save the zero-page area that we're about to use. init: ldx #zpspace - 1 -L1: lda sp,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -74,8 +74,8 @@ L1: lda sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. diff --git a/libsrc/telestrat/open.s b/libsrc/telestrat/open.s index f59d3d31a..08c572e23 100644 --- a/libsrc/telestrat/open.s +++ b/libsrc/telestrat/open.s @@ -2,7 +2,7 @@ .import addysp,popax - .importzp sp,tmp2,tmp3,tmp1 + .importzp c_sp,tmp2,tmp3,tmp1 .include "telestrat.inc" diff --git a/libsrc/telestrat/wherex.s b/libsrc/telestrat/wherex.s index 8616003c8..256b967c3 100644 --- a/libsrc/telestrat/wherex.s +++ b/libsrc/telestrat/wherex.s @@ -3,7 +3,7 @@ ; .export _wherex - .importzp sp + .importzp c_sp .include "telestrat.inc" diff --git a/libsrc/tgi/tgi_outtextxy.s b/libsrc/tgi/tgi_outtextxy.s index 3934df871..24183396f 100644 --- a/libsrc/tgi/tgi_outtextxy.s +++ b/libsrc/tgi/tgi_outtextxy.s @@ -8,7 +8,7 @@ .include "tgi-kernel.inc" .import addysp1 - .importzp sp + .importzp c_sp .proc _tgi_outtextxy @@ -17,16 +17,16 @@ pha ; ldy #0 - lda (sp),y + lda (c_sp),y sta _tgi_cury iny - lda (sp),y + lda (c_sp),y sta _tgi_cury+1 iny - lda (sp),y + lda (c_sp),y sta _tgi_curx iny - lda (sp),y + lda (c_sp),y sta _tgi_curx+1 pla jsr addysp1 ; Drop arguments from stack diff --git a/libsrc/vic20/crt0.s b/libsrc/vic20/crt0.s index c5486063b..189114f5d 100644 --- a/libsrc/vic20/crt0.s +++ b/libsrc/vic20/crt0.s @@ -24,7 +24,7 @@ Start: ; Save the zero-page locations that we need. ldx #zpspace-1 -L1: lda sp,x +L1: lda c_sp,x sta zpsave,x dex bpl L1 @@ -45,8 +45,8 @@ L1: lda sp,x lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__) - sta sp - stx sp+1 ; Set argument stack ptr + sta c_sp + stx c_sp+1 ; Set argument stack ptr ; Call the module constructors. @@ -65,7 +65,7 @@ _exit: pha ; Save the return code on stack ldx #zpspace-1 L2: lda zpsave,x - sta sp,x + sta c_sp,x dex bpl L2 diff --git a/libsrc/zlib/inflatemem.s b/libsrc/zlib/inflatemem.s index 80c19f223..2f2a1b295 100644 --- a/libsrc/zlib/inflatemem.s +++ b/libsrc/zlib/inflatemem.s @@ -12,7 +12,7 @@ .export _inflatemem .import incsp2 - .importzp sp, sreg, ptr1, ptr2, ptr3, ptr4 + .importzp c_sp, sreg, ptr1, ptr2, ptr3, ptr4 ; -------------------------------------------------------------------------- ; @@ -79,10 +79,10 @@ _inflatemem: stx inputPointer+1 ; outputPointer = dest ldy #1 - lda (sp),y + lda (c_sp),y sta outputPointer+1 dey - lda (sp),y + lda (c_sp),y sta outputPointer ; ldy #0 @@ -129,11 +129,11 @@ inflate_nextBlock: lda outputPointer ; ldy #0 ; sec - sbc (sp),y + sbc (c_sp),y iny pha lda outputPointer+1 - sbc (sp),y + sbc (c_sp),y tax pla ; pop dest diff --git a/samples/getsp.s b/samples/getsp.s index 9f169dc0b..95db689f4 100644 --- a/samples/getsp.s +++ b/samples/getsp.s @@ -1,11 +1,11 @@ .export _getsp - .importzp sp + .importzp c_sp .proc _getsp - ldx sp+1 - lda sp + ldx c_sp+1 + lda c_sp rts .endproc diff --git a/samples/tinyshell.c b/samples/tinyshell.c index 71e9b56e3..a8d5340d9 100644 --- a/samples/tinyshell.c +++ b/samples/tinyshell.c @@ -112,17 +112,17 @@ static void get_command(void) #ifdef CHECK_SP static char firstcall = 1; static unsigned int good_sp; - unsigned int sp; + unsigned int c_sp; if (firstcall) - sp = good_sp = getsp(); + c_sp = good_sp = getsp(); else - sp = getsp(); + c_sp = getsp(); - if (sp != good_sp) { - printf("SP: 0x%04X ***MISMATCH*** 0x%04X\n", sp, good_sp); + if (c_sp != good_sp) { + printf("SP: 0x%04X ***MISMATCH*** 0x%04X\n", c_sp, good_sp); } else if (verbose) - printf("SP: 0x%04X\n", sp); + printf("SP: 0x%04X\n", c_sp); #endif arg1 = arg2 = arg3 = NULL; diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 17618e5ff..42be0099a 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -220,7 +220,10 @@ void g_preamble (void) AddTextLine ("\t.debuginfo\t%s", (DebugInfo != 0)? "on" : "off"); /* Import zero page variables */ - AddTextLine ("\t.importzp\tsp, sreg, regsave, regbank"); + AddTextLine ("\t.importzp\t" "c_sp, sreg, regsave, regbank"); + /* The space above is intentional, to ease replacement of the name of + ** the stack pointer. Don't worry, the preprocessor will concatenate them. + */ AddTextLine ("\t.importzp\ttmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4"); /* Define long branch macros */ @@ -571,11 +574,11 @@ void g_swap_regvars (int StackOffs, int RegOffs, unsigned Bytes) AddCodeLine ("ldx #$%02X", RegOffs & 0xFF); AddCodeLine ("jsr regswap1"); } else { - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("ldx regbank%+d", RegOffs); AddCodeLine ("sta regbank%+d", RegOffs); AddCodeLine ("txa"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); } } else if (Bytes == 2) { @@ -617,7 +620,7 @@ void g_save_regvars (int RegOffs, unsigned Bytes) AddCodeLine ("ldx #$%02X", (unsigned char) Bytes); g_defcodelabel (Label); AddCodeLine ("lda regbank%+d,x", RegOffs-1); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("dey"); AddCodeLine ("dex"); AddCodeLine ("bne %s", LocalLabelName (Label)); @@ -641,28 +644,28 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) if (Bytes == 1) { AddCodeLine ("ldy #$%02X", StackOffs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs); } else if (Bytes == 2) { AddCodeLine ("ldy #$%02X", StackOffs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs+1); } else if (Bytes == 3 && IS_Get (&CodeSizeFactor) >= 133) { AddCodeLine ("ldy #$%02X", StackOffs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs+1); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d", RegOffs+2); } else if (StackOffs <= RegOffs) { @@ -674,7 +677,7 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) unsigned Label = GetLocalLabel (); AddCodeLine ("ldy #$%02X", StackOffs); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d,y", RegOffs - StackOffs); AddCodeLine ("iny"); AddCodeLine ("cpy #$%02X", StackOffs + Bytes); @@ -690,7 +693,7 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) AddCodeLine ("ldy #$%02X", (unsigned char) (StackOffs + Bytes - 1)); AddCodeLine ("ldx #$%02X", (unsigned char) (Bytes - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta regbank%+d,x", RegOffs); AddCodeLine ("dey"); AddCodeLine ("dex"); @@ -836,11 +839,11 @@ void g_getlocal (unsigned Flags, int Offs) CheckLocalOffs (Offs); if ((Flags & CF_FORCECHAR) || (Flags & CF_TEST)) { AddCodeLine ("ldy #$%02X", Offs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); } else { AddCodeLine ("ldy #$%02X", Offs); AddCodeLine ("ldx #$00"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); if ((Flags & CF_UNSIGNED) == 0) { unsigned L = GetLocalLabel(); AddCodeLine ("bpl %s", LocalLabelName (L)); @@ -854,9 +857,9 @@ void g_getlocal (unsigned Flags, int Offs) CheckLocalOffs (Offs + 1); AddCodeLine ("ldy #$%02X", (unsigned char) (Offs+1)); if (Flags & CF_TEST) { - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("dey"); - AddCodeLine ("ora (sp),y"); + AddCodeLine ("ora (c_sp),y"); } else { AddCodeLine ("jsr ldaxysp"); } @@ -937,7 +940,7 @@ void g_leasp (int Offs) { unsigned char Lo, Hi; - /* Calculate the offset relative to sp */ + /* Calculate the offset relative to c_sp */ Offs -= StackPtr; /* Get low and high byte */ @@ -947,17 +950,17 @@ void g_leasp (int Offs) /* Generate code */ if (Lo == 0) { if (Hi <= 3) { - AddCodeLine ("lda sp"); - AddCodeLine ("ldx sp+1"); + AddCodeLine ("lda c_sp"); + AddCodeLine ("ldx c_sp+1"); while (Hi--) { AddCodeLine ("inx"); } } else { - AddCodeLine ("lda sp+1"); + AddCodeLine ("lda c_sp+1"); AddCodeLine ("clc"); AddCodeLine ("adc #$%02X", Hi); AddCodeLine ("tax"); - AddCodeLine ("lda sp"); + AddCodeLine ("lda c_sp"); } } else if (Hi == 0) { /* 8 bit offset */ @@ -968,8 +971,8 @@ void g_leasp (int Offs) } else { /* 8 bit offset inlined */ unsigned L = GetLocalLabel (); - AddCodeLine ("lda sp"); - AddCodeLine ("ldx sp+1"); + AddCodeLine ("lda c_sp"); + AddCodeLine ("ldx c_sp+1"); AddCodeLine ("clc"); AddCodeLine ("adc #$%02X", Lo); AddCodeLine ("bcc %s", LocalLabelName (L)); @@ -983,11 +986,11 @@ void g_leasp (int Offs) AddCodeLine ("jsr leaaxsp"); } else { /* Full 16 bit offset inlined */ - AddCodeLine ("lda sp"); + AddCodeLine ("lda c_sp"); AddCodeLine ("clc"); AddCodeLine ("adc #$%02X", Lo); AddCodeLine ("pha"); - AddCodeLine ("lda sp+1"); + AddCodeLine ("lda c_sp+1"); AddCodeLine ("adc #$%02X", Hi); AddCodeLine ("tax"); AddCodeLine ("pla"); @@ -1003,10 +1006,10 @@ void g_leavariadic (int Offs) { unsigned ArgSizeOffs; - /* Calculate the offset relative to sp */ + /* Calculate the offset relative to c_sp */ Offs -= StackPtr; - /* Get the offset of the parameter which is stored at sp+0 on function + /* Get the offset of the parameter which is stored at c_sp+0 on function ** entry and check if this offset is reachable with a byte offset. */ CHECK (StackPtr <= 0); @@ -1015,14 +1018,14 @@ void g_leavariadic (int Offs) /* Get the size of all parameters. */ AddCodeLine ("ldy #$%02X", ArgSizeOffs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); /* Add the value of the stackpointer */ if (IS_Get (&CodeSizeFactor) > 250) { unsigned L = GetLocalLabel(); - AddCodeLine ("ldx sp+1"); + AddCodeLine ("ldx c_sp+1"); AddCodeLine ("clc"); - AddCodeLine ("adc sp"); + AddCodeLine ("adc c_sp"); AddCodeLine ("bcc %s", LocalLabelName (L)); AddCodeLine ("inx"); g_defcodelabel (L); @@ -1094,14 +1097,14 @@ void g_putlocal (unsigned Flags, int Offs, long Val) AddCodeLine ("lda #$%02X", (unsigned char) Val); } AddCodeLine ("ldy #$%02X", Offs); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); break; case CF_INT: if (Flags & CF_CONST) { AddCodeLine ("ldy #$%02X", Offs+1); AddCodeLine ("lda #$%02X", (unsigned char) (Val >> 8)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); if ((Flags & CF_NOKEEP) == 0) { /* Place high byte into X */ AddCodeLine ("tax"); @@ -1114,16 +1117,16 @@ void g_putlocal (unsigned Flags, int Offs, long Val) AddCodeLine ("dey"); AddCodeLine ("lda #$%02X", (unsigned char) Val); } - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); } else { AddCodeLine ("ldy #$%02X", Offs); if ((Flags & CF_NOKEEP) == 0 || IS_Get (&CodeSizeFactor) < 160) { AddCodeLine ("jsr staxysp"); } else { - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCodeLine ("txa"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); } } break; @@ -1163,12 +1166,12 @@ void g_putind (unsigned Flags, unsigned Offs) AddCodeLine ("pha"); } AddCodeLine ("lda #$%02X", Offs & 0xFF); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCodeLine ("lda #$%02X", (Offs >> 8) & 0xFF); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); if ((Flags & CF_NOKEEP) == 0) { AddCodeLine ("pla"); } @@ -1185,8 +1188,8 @@ void g_putind (unsigned Flags, unsigned Offs) AddCodeLine ("pha"); } AddCodeLine ("lda #$%02X", (Offs >> 8) & 0xFF); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); if ((Flags & CF_NOKEEP) == 0) { AddCodeLine ("pla"); } @@ -1620,7 +1623,7 @@ void g_addlocal (unsigned flags, int offs) L = GetLocalLabel(); AddCodeLine ("ldy #$%02X", NewOff & 0xFF); AddCodeLine ("clc"); - AddCodeLine ("adc (sp),y"); + AddCodeLine ("adc (c_sp),y"); AddCodeLine ("bcc %s", LocalLabelName (L)); AddCodeLine ("inx"); g_defcodelabel (L); @@ -1629,11 +1632,11 @@ void g_addlocal (unsigned flags, int offs) case CF_INT: AddCodeLine ("ldy #$%02X", NewOff & 0xFF); AddCodeLine ("clc"); - AddCodeLine ("adc (sp),y"); + AddCodeLine ("adc (c_sp),y"); AddCodeLine ("pha"); AddCodeLine ("txa"); AddCodeLine ("iny"); - AddCodeLine ("adc (sp),y"); + AddCodeLine ("adc (c_sp),y"); AddCodeLine ("tax"); AddCodeLine ("pla"); break; @@ -1841,12 +1844,12 @@ void g_addeqlocal (unsigned flags, int Offs, unsigned long val) if (flags & CF_CONST) { AddCodeLine ("clc"); AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); } else { AddCodeLine ("clc"); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); } if ((flags & CF_UNSIGNED) == 0) { unsigned L = GetLocalLabel(); @@ -1864,16 +1867,16 @@ void g_addeqlocal (unsigned flags, int Offs, unsigned long val) if (IS_Get (&CodeSizeFactor) >= 400) { AddCodeLine ("clc"); AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCodeLine ("lda #$%02X", (int) ((val >> 8) & 0xFF)); - AddCodeLine ("adc (sp),y"); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("adc (c_sp),y"); + AddCodeLine ("sta (c_sp),y"); if ((flags & CF_NOKEEP) == 0) { AddCodeLine ("tax"); AddCodeLine ("dey"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); } } else { g_getimmed (flags, val, 0); @@ -1925,7 +1928,7 @@ void g_addeqind (unsigned flags, unsigned offs, unsigned long val) case CF_INT: case CF_LONG: AddCodeLine ("jsr pushax"); /* Push the address */ - push (CF_PTR); /* Correct the internal sp */ + push (CF_PTR); /* Correct the internal c_sp */ g_getind (flags, offs); /* Fetch the value */ g_inc (flags, val); /* Increment value in primary */ g_putind (flags, offs); /* Store the value back */ @@ -2091,15 +2094,15 @@ void g_subeqlocal (unsigned flags, int Offs, unsigned long val) AddCodeLine ("ldy #$%02X", Offs); AddCodeLine ("ldx #$00"); if (flags & CF_CONST) { - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sec"); AddCodeLine ("sbc #$%02X", (unsigned char)val); } else { AddCodeLine ("eor #$FF"); AddCodeLine ("sec"); - AddCodeLine ("adc (sp),y"); + AddCodeLine ("adc (c_sp),y"); } - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); if ((flags & CF_UNSIGNED) == 0) { unsigned L = GetLocalLabel(); AddCodeLine ("bpl %s", LocalLabelName (L)); @@ -2159,7 +2162,7 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val) case CF_INT: case CF_LONG: AddCodeLine ("jsr pushax"); /* Push the address */ - push (CF_PTR); /* Correct the internal sp */ + push (CF_PTR); /* Correct the internal c_sp */ g_getind (flags, offs); /* Fetch the value */ g_dec (flags, val); /* Increment value in primary */ g_putind (flags, offs); /* Store the value back */ @@ -2210,10 +2213,10 @@ void g_addaddr_local (unsigned flags attribute ((unused)), int offs) /* Label was used above */ g_defcodelabel (L); } - AddCodeLine ("adc sp"); + AddCodeLine ("adc c_sp"); AddCodeLine ("tay"); AddCodeLine ("txa"); - AddCodeLine ("adc sp+1"); + AddCodeLine ("adc c_sp+1"); AddCodeLine ("tax"); AddCodeLine ("tya"); } @@ -2514,10 +2517,10 @@ void g_callind (unsigned Flags, unsigned ArgSize, int Offs) CheckLocalOffs (Offs); AddCodeLine ("pha"); AddCodeLine ("ldy #$%02X", Offs); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta jmpvec+1"); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta jmpvec+2"); AddCodeLine ("pla"); AddCodeLine ("jsr jmpvec"); @@ -2575,11 +2578,11 @@ void g_lateadjustSP (unsigned label) AddCodeLine ("pha"); AddCodeLine ("lda %s", LocalDataLabelName (label)); AddCodeLine ("clc"); - AddCodeLine ("adc sp"); - AddCodeLine ("sta sp"); + AddCodeLine ("adc c_sp"); + AddCodeLine ("sta c_sp"); AddCodeLine ("lda %s+1", LocalDataLabelName (label)); - AddCodeLine ("adc sp+1"); - AddCodeLine ("sta sp+1"); + AddCodeLine ("adc c_sp+1"); + AddCodeLine ("sta c_sp+1"); AddCodeLine ("pla"); } @@ -2593,11 +2596,11 @@ void g_drop (unsigned Space) AddCodeLine ("pha"); AddCodeLine ("lda #$%02X", (unsigned char) Space); AddCodeLine ("clc"); - AddCodeLine ("adc sp"); - AddCodeLine ("sta sp"); + AddCodeLine ("adc c_sp"); + AddCodeLine ("sta c_sp"); AddCodeLine ("lda #$%02X", (unsigned char) (Space >> 8)); - AddCodeLine ("adc sp+1"); - AddCodeLine ("sta sp+1"); + AddCodeLine ("adc c_sp+1"); + AddCodeLine ("sta c_sp+1"); AddCodeLine ("pla"); } else if (Space > 8) { AddCodeLine ("ldy #$%02X", Space); @@ -2620,13 +2623,13 @@ void g_space (int Space) ** overhead. */ AddCodeLine ("pha"); - AddCodeLine ("lda sp"); + AddCodeLine ("lda c_sp"); AddCodeLine ("sec"); AddCodeLine ("sbc #$%02X", (unsigned char) Space); - AddCodeLine ("sta sp"); - AddCodeLine ("lda sp+1"); + AddCodeLine ("sta c_sp"); + AddCodeLine ("lda c_sp+1"); AddCodeLine ("sbc #$%02X", (unsigned char) (Space >> 8)); - AddCodeLine ("sta sp+1"); + AddCodeLine ("sta c_sp+1"); AddCodeLine ("pla"); } else if (Space > 8) { AddCodeLine ("ldy #$%02X", Space); @@ -4586,14 +4589,14 @@ void g_initauto (unsigned Label, unsigned Size) AddCodeLine ("ldy #$%02X", Size-1); g_defcodelabel (CodeLabel); AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, Label, 0)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (CodeLabel)); } else if (Size <= 256) { AddCodeLine ("ldy #$00"); g_defcodelabel (CodeLabel); AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, Label, 0)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Size); AddCodeLine ("bne %s", LocalLabelName (CodeLabel)); diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 29f18cb78..25712d546 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -386,6 +386,8 @@ static const FuncInfo FuncInfoTable[] = { /* CAUTION: table must be sorted for bsearch */ static const ZPInfo ZPInfoTable[] = { /* BEGIN SORTED.SH */ + { 0, "c_sp", 2, REG_SP_LO, REG_SP }, + { 0, "c_sp+1", 1, REG_SP_HI, REG_SP }, { 0, "ptr1", 2, REG_PTR1_LO, REG_PTR1 }, { 0, "ptr1+1", 1, REG_PTR1_HI, REG_PTR1 }, { 0, "ptr2", 2, REG_PTR2_LO, REG_PTR2 }, @@ -395,8 +397,6 @@ static const ZPInfo ZPInfoTable[] = { { 7, "regbank", 6, REG_NONE, REG_NONE }, { 0, "regsave", 4, REG_SAVE_LO, REG_SAVE }, { 0, "regsave+1", 3, REG_SAVE_HI, REG_SAVE }, - { 0, "sp", 2, REG_SP_LO, REG_SP }, - { 0, "sp+1", 1, REG_SP_HI, REG_SP }, { 0, "sreg", 2, REG_SREG_LO, REG_SREG }, { 0, "sreg+1", 1, REG_SREG_HI, REG_SREG }, { 0, "tmp1", 1, REG_TMP1, REG_TMP1 }, diff --git a/src/cc65/codeinfo.h b/src/cc65/codeinfo.h index c57908dad..d03962343 100644 --- a/src/cc65/codeinfo.h +++ b/src/cc65/codeinfo.h @@ -75,8 +75,8 @@ struct RegContents; #define REG_SP_HI 0x2000U /* Defines for some special register usage */ -#define SLV_IND 0x00010000U /* Accesses (sp),y */ -#define SLV_TOP 0x00020000U /* Accesses (sp),0 */ +#define SLV_IND 0x00010000U /* Accesses (c_sp),y */ +#define SLV_TOP 0x00020000U /* Accesses (c_sp),0 */ #define SLV_SP65 0x00200000U /* Accesses 6502 stack pointer */ #define SLV_PH65 0x00400000U /* Pushes onto 6502 stack */ #define SLV_PL65 0x00800000U /* Pops from 6502 stack */ @@ -122,7 +122,7 @@ struct RegContents; typedef struct ZPInfo ZPInfo; struct ZPInfo { unsigned char Len; /* Length of the following string */ - char Name[10]; /* Name of zero page symbol */ + char Name[64]; /* Name of zero page symbol */ unsigned char Size; /* Maximum buffer size of this register */ unsigned short ByteUse; /* Register info for this symbol */ unsigned short WordUse; /* Register info for 16 bit access */ diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 19acfde74..e3869d786 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -825,7 +825,7 @@ static unsigned RunOptGroup5 (CodeSeg* S) static unsigned RunOptGroup6 (CodeSeg* S) -/* This one is quite special. It tries to replace "lda (sp),y" by "lda (sp,x)". +/* This one is quite special. It tries to replace "lda (c_sp),y" by "lda (c_sp,x)". ** The latter is ony cycle slower, but if we're able to remove the necessary ** load of the Y register, because X is zero anyway, we gain 1 cycle and ** shorten the code by one (transfer) or two bytes (load). So what we do is diff --git a/src/cc65/codeoptutil.c b/src/cc65/codeoptutil.c index 7547ef5ba..0d3dba95c 100644 --- a/src/cc65/codeoptutil.c +++ b/src/cc65/codeoptutil.c @@ -333,14 +333,14 @@ static int Affected (LoadRegInfo* LRI, const CodeEntry* E) */ if (E->AM == AM65_ABS || E->AM == AM65_ZP || - (E->AM == AM65_ZP_INDY && strcmp (E->ArgBase, "sp") == 0) + (E->AM == AM65_ZP_INDY && strcmp (E->ArgBase, "c_sp") == 0) ) { if ((LRI->Flags & LI_CHECK_ARG) != 0) { if (AE == 0 || (AE->AM != AM65_ABS && AE->AM != AM65_ZP && (AE->AM != AM65_ZP_INDY || - strcmp (AE->ArgBase, "sp") != 0)) || + strcmp (AE->ArgBase, "c_sp") != 0)) || (AE->ArgOff == E->ArgOff && strcmp (AE->ArgBase, E->ArgBase) == 0)) { @@ -445,7 +445,7 @@ void PrepairLoadRegInfoForArgCheck (CodeSeg* S, LoadRegInfo* LRI, CodeEntry* E) /* These insns are replaceable only if they are not modified later */ LRI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; } else if ((E->AM == AM65_ZP_INDY) && - strcmp (E->Arg, "sp") == 0) { + strcmp (E->Arg, "c_sp") == 0) { /* A load from the stack with known offset is also ok, but in this ** case we must reload the index register later. Please note that ** a load indirect via other zero page locations is not ok, since @@ -556,7 +556,7 @@ unsigned int TrackLoads (LoadInfo* LI, CodeSeg* S, int I) /* These insns are replaceable only if they are not modified later */ LRI->Flags |= LI_CHECK_ARG | LI_CHECK_Y; } else if (E->AM == AM65_ZP_INDY && - strcmp (E->Arg, "sp") == 0) { + strcmp (E->Arg, "c_sp") == 0) { /* A load from the stack with known offset is also ok, but in this ** case we must reload the index register later. Please note that ** a load indirect via other zero page locations is not ok, since @@ -839,7 +839,7 @@ void AdjustStackOffset (StackOpData* D, unsigned Offs) if (E->OPC != OP65_JSR) { /* Check against some things that should not happen */ CHECK (E->AM == AM65_ZP_INDY && E->RI->In.RegY >= (short) Offs); - CHECK (strcmp (E->Arg, "sp") == 0); + CHECK (strcmp (E->Arg, "c_sp") == 0); /* We need to correct this one */ Correction = 2; @@ -1056,8 +1056,8 @@ void AddOpLow (StackOpData* D, opc_t OPC, LoadInfo* LI) InsertEntry (D, X, D->IP++); if (LI->A.LoadEntry->OPC == OP65_JSR) { - /* opc (sp),y */ - X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); + /* opc (c_sp),y */ + X = NewCodeEntry (OPC, AM65_ZP_INDY, "c_sp", 0, D->OpEntry->LI); } else { /* opc src,y */ X = NewCodeEntry (OPC, LI->A.LoadEntry->AM, LI->A.LoadEntry->Arg, 0, D->OpEntry->LI); @@ -1119,8 +1119,8 @@ void AddOpHigh (StackOpData* D, opc_t OPC, LoadInfo* LI, int KeepResult) InsertEntry (D, X, D->IP++); if (LI->X.LoadEntry->OPC == OP65_JSR) { - /* opc (sp),y */ - X = NewCodeEntry (OPC, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); + /* opc (c_sp),y */ + X = NewCodeEntry (OPC, AM65_ZP_INDY, "c_sp", 0, D->OpEntry->LI); } else { /* opc src,y */ X = NewCodeEntry (OPC, LI->X.LoadEntry->AM, LI->X.LoadEntry->Arg, 0, D->OpEntry->LI); @@ -1312,10 +1312,10 @@ const char* GetZPName (unsigned ZPLoc) return "save+1"; } if ((ZPLoc & REG_SP_LO) != 0) { - return "sp"; + return "c_sp"; } if ((ZPLoc & REG_SP_HI) != 0) { - return "sp+1"; + return "c_sp+1"; } return 0; diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index bc67f7a74..3636e0e20 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -62,15 +62,15 @@ unsigned OptAdd1 (CodeSeg* S) ** and replace it by: ** ** ldy #xx-1 -** lda (sp),y +** lda (c_sp),y ** ldy #yy-3 ** clc -** adc (sp),y +** adc (c_sp),y ** pha ** ldy #xx -** lda (sp),y +** lda (c_sp),y ** ldy #yy-2 -** adc (sp),y +** adc (c_sp),y ** tax ** pla */ @@ -104,8 +104,8 @@ unsigned OptAdd1 (CodeSeg* S) /* Correct the stack of the first Y register load */ CE_SetNumArg (L[0], L[0]->Num - 1); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+1); /* ldy #yy-3 */ @@ -117,8 +117,8 @@ unsigned OptAdd1 (CodeSeg* S) X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[5]->LI); CS_InsertEntry (S, X, I+3); - /* adc (sp),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[5]->LI); + /* adc (c_sp),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "c_sp", 0, L[5]->LI); CS_InsertEntry (S, X, I+4); /* pha */ @@ -130,8 +130,8 @@ unsigned OptAdd1 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); CS_InsertEntry (S, X, I+6); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+7); /* ldy #yy-2 */ @@ -139,8 +139,8 @@ unsigned OptAdd1 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[4]->LI); CS_InsertEntry (S, X, I+8); - /* adc (sp),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[5]->LI); + /* adc (c_sp),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "c_sp", 0, L[5]->LI); CS_InsertEntry (S, X, I+9); /* tax */ @@ -181,16 +181,16 @@ unsigned OptAdd2 (CodeSeg* S) ** and replace it by: ** ** ldy #xx-1 -** lda (sp),y +** lda (c_sp),y ** ldy #yy ** clc -** adc (sp),y -** sta (sp),y +** adc (c_sp),y +** sta (c_sp),y ** ldy #xx -** lda (sp),y +** lda (c_sp),y ** ldy #yy+1 -** adc (sp),y -** sta (sp),y +** adc (c_sp),y +** sta (c_sp),y ** ** provided that a/x is not used later. */ @@ -226,8 +226,8 @@ unsigned OptAdd2 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+4); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+5); /* ldy #yy */ @@ -238,20 +238,20 @@ unsigned OptAdd2 (CodeSeg* S) X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[3]->LI); CS_InsertEntry (S, X, I+7); - /* adc (sp),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[3]->LI); + /* adc (c_sp),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "c_sp", 0, L[3]->LI); CS_InsertEntry (S, X, I+8); - /* sta (sp),y */ - X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, L[3]->LI); + /* sta (c_sp),y */ + X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "c_sp", 0, L[3]->LI); CS_InsertEntry (S, X, I+9); /* ldy #xx */ X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+10); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+11); /* ldy #yy+1 */ @@ -259,12 +259,12 @@ unsigned OptAdd2 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[2]->LI); CS_InsertEntry (S, X, I+12); - /* adc (sp),y */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[3]->LI); + /* adc (c_sp),y */ + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "c_sp", 0, L[3]->LI); CS_InsertEntry (S, X, I+13); - /* sta (sp),y */ - X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, L[3]->LI); + /* sta (c_sp),y */ + X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "c_sp", 0, L[3]->LI); CS_InsertEntry (S, X, I+14); /* Delete the old code */ diff --git a/src/cc65/coptadd.h b/src/cc65/coptadd.h index e4df3b304..d29783305 100644 --- a/src/cc65/coptadd.h +++ b/src/cc65/coptadd.h @@ -55,14 +55,14 @@ unsigned OptAdd1 (CodeSeg* S); ** jsr pushax ** ldy xxx ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** jsr tosaddax ** ** and replace it by: ** ** ldy xxx-2 ** clc -** adc (sp),y +** adc (c_sp),y ** bcc L ** inx ** L: @@ -72,26 +72,26 @@ unsigned OptAdd2 (CodeSeg* S); /* Search for the sequence ** ** ldy #xx -** lda (sp),y +** lda (c_sp),y ** tax ** dey -** lda (sp),y +** lda (c_sp),y ** ldy #$yy ** jsr addeqysp ** ** and replace it by: ** ** ldy #xx-1 -** lda (sp),y +** lda (c_sp),y ** ldy #yy ** clc -** adc (sp),y -** sta (sp),y +** adc (c_sp),y +** sta (c_sp),y ** ldy #xx -** lda (sp),y +** lda (c_sp),y ** ldy #yy+1 -** adc (sp),y -** sta (sp),y +** adc (c_sp),y +** sta (c_sp),y ** ** provided that a/x is not used later. */ diff --git a/src/cc65/coptbool.c b/src/cc65/coptbool.c index 3a3b3fa7c..e0a79238e 100644 --- a/src/cc65/coptbool.c +++ b/src/cc65/coptbool.c @@ -743,9 +743,9 @@ unsigned OptBNegAX2 (CodeSeg* S) ** and replace it by ** ** ldy #xx -** lda (sp),y +** lda (c_sp),y ** dey -** ora (sp),y +** ora (c_sp),y ** jeq/jne ... */ { @@ -772,16 +772,16 @@ unsigned OptBNegAX2 (CodeSeg* S) CodeEntry* X; - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+1); /* dey */ X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[1]->LI); CS_InsertEntry (S, X, I+2); - /* ora (sp),y */ - X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + /* ora (c_sp),y */ + X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+3); /* Invert the branch */ diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index 2970b363b..eb138e78d 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -431,22 +431,22 @@ unsigned OptCmp5 (CodeSeg* S) /* The value is zero, we may use the simple code version: ** ldy #o-1 - ** lda (sp),y + ** lda (c_sp),y ** ldy #o - ** ora (sp),y + ** ora (c_sp),y ** jne/jeq ... */ sprintf (Buf, "$%02X", (int)(L[0]->Num-1)); X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI); CS_InsertEntry (S, X, I+1); - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+2); X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+3); - X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + X = NewCodeEntry (OP65_ORA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+4); CS_DelEntries (S, I+5, 3); /* cpx/bne/cmp */ @@ -461,18 +461,18 @@ unsigned OptCmp5 (CodeSeg* S) ** of the low byte after the first branch if possible: ** ** ldy #o - ** lda (sp),y + ** lda (c_sp),y ** cmp #a ** bne L1 ** ldy #o-1 - ** lda (sp),y + ** lda (c_sp),y ** cmp #b ** jne/jeq ... */ X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI); CS_InsertEntry (S, X, I+3); - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+4); X = NewCodeEntry (OP65_CMP, L[2]->AM, L[2]->Arg, 0, L[2]->LI); @@ -482,7 +482,7 @@ unsigned OptCmp5 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI); CS_InsertEntry (S, X, I+7); - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[1]->LI); CS_InsertEntry (S, X, I+8); CS_DelEntries (S, I, 3); /* ldy/jsr/cpx */ diff --git a/src/cc65/coptcmp.h b/src/cc65/coptcmp.h index dd188f7fc..98e75715b 100644 --- a/src/cc65/coptcmp.h +++ b/src/cc65/coptcmp.h @@ -113,10 +113,10 @@ unsigned OptCmp5 (CodeSeg* S); /* Optimize compares of local variables: ** ** ldy #o -** lda (sp),y +** lda (c_sp),y ** tax ** dey -** lda (sp),y +** lda (c_sp),y ** cpx #a ** bne L1 ** cmp #b diff --git a/src/cc65/coptmisc.c b/src/cc65/coptmisc.c index b23ee6e0a..a2cda7495 100644 --- a/src/cc65/coptmisc.c +++ b/src/cc65/coptmisc.c @@ -492,9 +492,9 @@ unsigned OptGotoSPAdj (CodeSeg* S) L[1]->AM == AM65_ABS && L[2]->OPC == OP65_CLC && L[3]->OPC == OP65_ADC && - strcmp (L[3]->Arg, "sp") == 0 && + strcmp (L[3]->Arg, "c_sp") == 0 && L[6]->OPC == OP65_ADC && - strcmp (L[6]->Arg, "sp+1") == 0 && + strcmp (L[6]->Arg, "c_sp+1") == 0 && L[9]->OPC == OP65_JMP) { adjustment = FindSPAdjustment (L[1]->Arg); @@ -663,7 +663,7 @@ unsigned OptLoad1 (CodeSeg* S) CS_InsertEntry (S, X, I+1); /* Load from stack */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, E->LI); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, E->LI); CS_InsertEntry (S, X, I+2); /* Now remove the call to the subroutine */ @@ -719,8 +719,8 @@ unsigned OptLoad2 (CodeSeg* S) ** later */ - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[0]->LI); CS_InsertEntry (S, X, I+3); /* sta abs */ @@ -731,8 +731,8 @@ unsigned OptLoad2 (CodeSeg* S) X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[0]->LI); CS_InsertEntry (S, X, I+5); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[0]->LI); CS_InsertEntry (S, X, I+6); /* sta abs */ @@ -746,8 +746,8 @@ unsigned OptLoad2 (CodeSeg* S) /* Standard replacement */ - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[0]->LI); CS_InsertEntry (S, X, I+1); /* tax */ @@ -758,8 +758,8 @@ unsigned OptLoad2 (CodeSeg* S) X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, L[0]->LI); CS_InsertEntry (S, X, I+3); - /* lda (sp),y */ - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[0]->LI); + /* lda (c_sp),y */ + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "c_sp", 0, L[0]->LI); CS_InsertEntry (S, X, I+4); /* Now remove the call to the subroutine */ diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index 046e65d79..e28bf5d39 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -359,7 +359,7 @@ unsigned OptPtrLoad4 (CodeSeg* S) ** ldx #>(label+0) ** ldy #$xx ** clc -** adc (sp),y +** adc (c_sp),y ** bcc L ** inx ** L: ldy #$00 @@ -368,7 +368,7 @@ unsigned OptPtrLoad4 (CodeSeg* S) ** and replace it by: ** ** ldy #$xx -** lda (sp),y +** lda (c_sp),y ** tay ** ldx #$00 ** lda label,y @@ -553,7 +553,7 @@ unsigned OptPtrLoad6 (CodeSeg* S) ** jsr pushax ** ldy #xxx ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** jsr tosaddax ** ldy #$00 ** jsr ldauidx @@ -563,7 +563,7 @@ unsigned OptPtrLoad6 (CodeSeg* S) ** sta ptr1 ** stx ptr1+1 ** ldy #xxx-2 -** lda (sp),y +** lda (c_sp),y ** tay ** ldx #$00 ** lda (ptr1),y @@ -613,7 +613,7 @@ unsigned OptPtrLoad6 (CodeSeg* S) X = NewCodeEntry (OP65_LDY, AM65_IMM, Arg, 0, L[1]->LI); CS_InsertEntry (S, X, I+9); - /* lda (sp),y */ + /* lda (c_sp),y */ X = NewCodeEntry (OP65_LDA, L[3]->AM, L[3]->Arg, 0, L[3]->LI); CS_InsertEntry (S, X, I+10); diff --git a/src/cc65/coptptrload.h b/src/cc65/coptptrload.h index d4e0e2ed4..259d1587b 100644 --- a/src/cc65/coptptrload.h +++ b/src/cc65/coptptrload.h @@ -127,7 +127,7 @@ unsigned OptPtrLoad4 (CodeSeg* S); ** ldx #>(label+0) ** ldy #$xx ** clc -** adc (sp),y +** adc (c_sp),y ** bcc L ** inx ** L: ldy #$00 @@ -136,7 +136,7 @@ unsigned OptPtrLoad4 (CodeSeg* S); ** and replace it by: ** ** ldy #$xx -** lda (sp),y +** lda (c_sp),y ** tay ** ldx #$00 ** lda label,y @@ -166,7 +166,7 @@ unsigned OptPtrLoad6 (CodeSeg* S); ** jsr pushax ** ldy xxx ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** jsr tosaddax ** ldy #$00 ** jsr ldauidx @@ -176,7 +176,7 @@ unsigned OptPtrLoad6 (CodeSeg* S); ** sta ptr1 ** stx ptr1+1 ** ldy xxx -** lda (sp),y +** lda (c_sp),y ** tay ** lda (ptr1),y */ diff --git a/src/cc65/coptptrstore.c b/src/cc65/coptptrstore.c index 11832910f..6891d8353 100644 --- a/src/cc65/coptptrstore.c +++ b/src/cc65/coptptrstore.c @@ -396,7 +396,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** L: jsr pushax ** ldy yyy ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** ldy #$00 ** jsr staspidx ** @@ -406,7 +406,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** stx ptr1+1 ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** ldy xxx ** sta (ptr1),y ** @@ -414,7 +414,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** ldy xxx ** sta (zp),y ** @@ -422,7 +422,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** ldy xxx ** sta label,y ** @@ -430,7 +430,7 @@ unsigned OptPtrStore2 (CodeSeg* S) ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** ldy xxx ** sta $xxxx,y ** @@ -468,7 +468,7 @@ unsigned OptPtrStore2 (CodeSeg* S) L[6]->OPC == OP65_LDX && L[7]->OPC == OP65_LDA && L[7]->AM == AM65_ZP_INDY && - strcmp (L[7]->Arg, "sp") == 0 && + strcmp (L[7]->Arg, "c_sp") == 0 && L[8]->OPC == OP65_LDY && (L[8]->AM == AM65_ABS || L[8]->AM == AM65_ZP || diff --git a/src/cc65/coptptrstore.h b/src/cc65/coptptrstore.h index 3f8fc91f9..fd36eddba 100644 --- a/src/cc65/coptptrstore.h +++ b/src/cc65/coptptrstore.h @@ -105,7 +105,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** L: jsr pushax ** ldy yyy ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** ldy #$00 ** jsr staspidx ** @@ -115,7 +115,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** stx ptr1+1 ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** ldy xxx ** sta (ptr1),y ** @@ -123,7 +123,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** ldy xxx ** sta (zp),y ** @@ -131,7 +131,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** ldy xxx ** sta label,y ** @@ -139,7 +139,7 @@ unsigned OptPtrStore2 (CodeSeg* S); ** ** ldy yyy-2 ** ldx #$00 -** lda (sp),y +** lda (c_sp),y ** ldy xxx ** sta $xxxx,y ** diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index e5d686d1a..7a9416b51 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -1292,10 +1292,10 @@ static unsigned Opt_a_tosicmp (StackOpData* D) } InsertEntry (D, X, D->IP++); - /* cmp src,y OR cmp (sp),y */ + /* cmp src,y OR cmp (c_sp),y */ if (D->Rhs.A.LoadEntry->OPC == OP65_JSR) { - /* opc (sp),y */ - X = NewCodeEntry (OP65_CMP, AM65_ZP_INDY, "sp", 0, D->OpEntry->LI); + /* opc (c_sp),y */ + X = NewCodeEntry (OP65_CMP, AM65_ZP_INDY, "c_sp", 0, D->OpEntry->LI); } else { /* opc src,y */ X = NewCodeEntry (OP65_CMP, D->Rhs.A.LoadEntry->AM, D->Rhs.A.LoadEntry->Arg, 0, D->OpEntry->LI); diff --git a/src/cc65/coptstore.c b/src/cc65/coptstore.c index b0dfe3b6d..2fc83b5fb 100644 --- a/src/cc65/coptstore.c +++ b/src/cc65/coptstore.c @@ -48,7 +48,7 @@ static void InsertStore (CodeSeg* S, unsigned* IP, LineInfo* LI) { - CodeEntry* X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, LI); + CodeEntry* X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "c_sp", 0, LI); CS_InsertEntry (S, X, (*IP)++); } diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 08e41918e..08fe83b75 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -269,7 +269,7 @@ static void ParseAutoDecl (Declarator* Decl) Sym->V.Offs = F_ReserveLocalSpace (CurrentFunc, Size); /* Next, allocate the space on the stack. This means that the - ** variable is now located at offset 0 from the current sp. + ** variable is now located at offset 0 from the current c_sp. */ F_AllocLocalSpace (CurrentFunc); diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 3f33cdcce..1597380e8 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -371,7 +371,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); g_defcodelabel (Label); AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); } else { @@ -379,7 +379,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); g_defcodelabel (Label); AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("dey"); AddCodeLine ("dex"); AddCodeLine ("bpl %s", LocalLabelName (Label)); @@ -391,7 +391,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); @@ -400,7 +400,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCodeLine ("inx"); AddCmpCodeIfSizeNot256 ("cpx #$%02X", Arg3.Expr.IVal); @@ -448,7 +448,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Offs == 0) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); @@ -456,7 +456,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldx #$%02X", (unsigned char) (Arg3.Expr.IVal-1)); AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); AddCodeLine ("dey"); AddCodeLine ("dex"); @@ -468,7 +468,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Offs == 0 || AllowOneIndex) { AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs)); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); @@ -477,7 +477,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldx #$00"); AddCodeLine ("ldy #$%02X", (unsigned char) Offs); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); AddCodeLine ("iny"); AddCodeLine ("inx"); @@ -512,14 +512,14 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Arg3.Expr.IVal <= 129) { AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta (ptr1),y"); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); } else { AddCodeLine ("ldy #$00"); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta (ptr1),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Arg3.Expr.IVal); @@ -703,7 +703,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) AddCodeLine ("ldy #$%02X", (unsigned char) Offs); AddCodeLine ("lda #$%02X", (unsigned char) Arg2.Expr.IVal); g_defcodelabel (Label); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); AddCodeLine ("iny"); AddCmpCodeIfSizeNot256 ("cpy #$%02X", Offs + Arg3.Expr.IVal); AddCodeLine ("bne %s", LocalLabelName (Label)); @@ -857,7 +857,7 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Generate code */ AddCodeLine ("ldy #$%02X", Offs); AddCodeLine ("ldx #$00"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); } else if (IsArray && ED_IsLocConst (&Arg1.Expr)) { /* Drop the generated code */ RemoveCode (&Arg1.Load); @@ -1090,14 +1090,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (Offs == 0 || AllowOneIndex) { g_defcodelabel (L1); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs)); } else { AddCodeLine ("ldx #$FF"); g_defcodelabel (L1); AddCodeLine ("iny"); AddCodeLine ("inx"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("sta %s,x", ED_GetLabelName (&Arg1.Expr, 0)); } AddCodeLine ("bne %s", LocalLabelName (L1)); @@ -1138,14 +1138,14 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) g_defcodelabel (L1); AddCodeLine ("iny"); AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); } else { AddCodeLine ("ldx #$FF"); g_defcodelabel (L1); AddCodeLine ("iny"); AddCodeLine ("inx"); AddCodeLine ("lda %s,x", ED_GetLabelName (&Arg2.Expr, 0)); - AddCodeLine ("sta (sp),y"); + AddCodeLine ("sta (c_sp),y"); } AddCodeLine ("bne %s", LocalLabelName (L1)); @@ -1285,7 +1285,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) g_defcodelabel (L); AddCodeLine ("inx"); AddCodeLine ("iny"); - AddCodeLine ("lda (sp),y"); + AddCodeLine ("lda (c_sp),y"); AddCodeLine ("bne %s", LocalLabelName (L)); AddCodeLine ("txa"); AddCodeLine ("ldx #$00"); diff --git a/src/dbginfo/dbgsh.c b/src/dbginfo/dbgsh.c index 6a95db2af..280221fc9 100644 --- a/src/dbginfo/dbgsh.c +++ b/src/dbginfo/dbgsh.c @@ -458,7 +458,7 @@ static unsigned FindIdType (const char* TypeName) { "segment", SegmentId }, { "source", SourceId }, { "src", SourceId }, - { "sp", SpanId }, + { "c_sp", SpanId }, { "span", SpanId }, { "sym", SymbolId }, { "symbol", SymbolId }, diff --git a/src/sim65/main.c b/src/sim65/main.c index 828ea498e..3cc9581b5 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -230,7 +230,7 @@ static unsigned char ReadProgramFile (void) } } - /* Get the address of sp from the file header */ + /* Get the address of c_sp from the file header */ if ((Val = fgetc(F)) != EOF) { SPAddr = Val; } diff --git a/targettest/atari/mem.c b/targettest/atari/mem.c index b15b215ed..f063d1e46 100644 --- a/targettest/atari/mem.c +++ b/targettest/atari/mem.c @@ -41,7 +41,7 @@ int main(void) printf(" data: $%04X (data)\n", &data); printf(" _dos_type: $%04X (bss)\n", &_dos_type); printf(" allocmem: $%04X (dyn. data)\n", allocmem); - printf(" sp: $%04X (stack ptr)\n", getsp()); + printf(" c_sp: $%04X (stack ptr)\n", getsp()); if (allocmem) free(allocmem); if (doesclrscrafterexit()) cgetc(); diff --git a/targettest/ft.c b/targettest/ft.c index 3dfa0e37b..a28795f2b 100644 --- a/targettest/ft.c +++ b/targettest/ft.c @@ -10,7 +10,7 @@ ** got one from argv). I then opens the file, ** reads the first 16 bytes and displays them ** (as hex values). -** The values of sp (cc65 runtime stack pointer) +** The values of c_sp (cc65 runtime stack pointer) ** are displayed at some places. The displayed ** value should always be the same. */ @@ -64,16 +64,16 @@ int main(int argc,char **argv) } printf("using filename \"%s\"\n",filename); csp = getsp(); - printf("now opening file... sp = %d\n",csp); + printf("now opening file... c_sp = %d\n",csp); fd = open(filename,O_RDONLY); csp = getsp(); if (fd == -1) { char x1 = _oserror; - printf("open failed: os: %d,\n\terrno: %d, sp = %d\n",x1,errno,csp); + printf("open failed: os: %d,\n\terrno: %d, c_sp = %d\n",x1,errno,csp); cgetc(); return(0); } - printf("open success -- handle = $%x, sp = %d\n",fd,csp); + printf("open success -- handle = $%x, c_sp = %d\n",fd,csp); #ifdef __ATARI__ printf("fd_index:\n "); for (i=0; i<12; i++) printf("%02X ",__fd_index[i]); @@ -88,7 +88,7 @@ int main(int argc,char **argv) lr = read(fd,buf,16); /* read first 16 bytes */ csp = getsp(); if (lr == -1) { - printf("read failed: %d (sp = %d)\n",errno,csp); + printf("read failed: %d (c_sp = %d)\n",errno,csp); cgetc(); return(0); } @@ -99,7 +99,7 @@ int main(int argc,char **argv) return(0); } csp = getsp(); - printf("\n\nThe data read: (%d bytes, sp = %d)\n",lr,csp); + printf("\n\nThe data read: (%d bytes, c_sp = %d)\n",lr,csp); for (i=0; i<lr; i++) { printf("%02X ",buf[i]); if (!((i+1) & 7)) printf("\n"); diff --git a/targettest/getsp.s b/targettest/getsp.s index 9f169dc0b..95db689f4 100644 --- a/targettest/getsp.s +++ b/targettest/getsp.s @@ -1,11 +1,11 @@ .export _getsp - .importzp sp + .importzp c_sp .proc _getsp - ldx sp+1 - lda sp + ldx c_sp+1 + lda c_sp rts .endproc diff --git a/test/val/bug1652-optimizer.c b/test/val/bug1652-optimizer.c index 7926ef770..97d0c5e4d 100644 --- a/test/val/bug1652-optimizer.c +++ b/test/val/bug1652-optimizer.c @@ -10,9 +10,9 @@ before: jsr pusha ldy #$01 ldx #$00 - lda (sp),y + lda (c_sp),y beq L0005 - lda (sp,x) + lda (c_sp,x) beq L0005 txa jmp incsp2 ; <-- @@ -24,9 +24,9 @@ after: jsr pusha ldy #$01 ldx #$00 - lda (sp),y + lda (c_sp),y beq L0004 - lda (sp,x) + lda (c_sp,x) beq L0004 txa jmp L0001 ; <-- diff --git a/test/val/cq85.c b/test/val/cq85.c index 81a99c960..ce836b649 100644 --- a/test/val/cq85.c +++ b/test/val/cq85.c @@ -62,7 +62,7 @@ int s85(struct defs *pd0){ struct tnode *right; }; - struct tnode s1, s2, *sp; + struct tnode s1, s2, *c_sp; struct{ char cdummy; From b2e5d3cd25840338f4ea79aa3f14a42fe49b6406 Mon Sep 17 00:00:00 2001 From: Gorilla Sapiens <embracetheape@gmail.com> Date: Mon, 23 Jun 2025 17:51:44 +0000 Subject: [PATCH 585/707] insipid formatting whack-a-mole --- libsrc/runtime/zeropage.s | 2 +- src/cc65/coptptrstore.c | 2 +- src/dbginfo/dbgsh.c | 2 +- targettest/atari/mem.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libsrc/runtime/zeropage.s b/libsrc/runtime/zeropage.s index 75856f751..2e2b237f6 100644 --- a/libsrc/runtime/zeropage.s +++ b/libsrc/runtime/zeropage.s @@ -10,7 +10,7 @@ .zeropage -c_sp: .res 2 ; Stack pointer +c_sp: .res 2 ; Stack pointer sreg: .res 2 ; Secondary register/high 16 bit for longs regsave: .res 4 ; Slot to save/restore (E)AX into ptr1: .res 2 diff --git a/src/cc65/coptptrstore.c b/src/cc65/coptptrstore.c index 6891d8353..721775380 100644 --- a/src/cc65/coptptrstore.c +++ b/src/cc65/coptptrstore.c @@ -468,7 +468,7 @@ unsigned OptPtrStore2 (CodeSeg* S) L[6]->OPC == OP65_LDX && L[7]->OPC == OP65_LDA && L[7]->AM == AM65_ZP_INDY && - strcmp (L[7]->Arg, "c_sp") == 0 && + strcmp (L[7]->Arg, "c_sp") == 0 && L[8]->OPC == OP65_LDY && (L[8]->AM == AM65_ABS || L[8]->AM == AM65_ZP || diff --git a/src/dbginfo/dbgsh.c b/src/dbginfo/dbgsh.c index 280221fc9..e848c47cd 100644 --- a/src/dbginfo/dbgsh.c +++ b/src/dbginfo/dbgsh.c @@ -458,7 +458,7 @@ static unsigned FindIdType (const char* TypeName) { "segment", SegmentId }, { "source", SourceId }, { "src", SourceId }, - { "c_sp", SpanId }, + { "c_sp", SpanId }, { "span", SpanId }, { "sym", SymbolId }, { "symbol", SymbolId }, diff --git a/targettest/atari/mem.c b/targettest/atari/mem.c index f063d1e46..459c472ec 100644 --- a/targettest/atari/mem.c +++ b/targettest/atari/mem.c @@ -41,7 +41,7 @@ int main(void) printf(" data: $%04X (data)\n", &data); printf(" _dos_type: $%04X (bss)\n", &_dos_type); printf(" allocmem: $%04X (dyn. data)\n", allocmem); - printf(" c_sp: $%04X (stack ptr)\n", getsp()); + printf(" c_sp: $%04X (stack ptr)\n", getsp()); if (allocmem) free(allocmem); if (doesclrscrafterexit()) cgetc(); From 450898513c88e39cfbf5ceeb6c1473f79fd87b49 Mon Sep 17 00:00:00 2001 From: Russell-S-Harper <russell.s.harper@gmail.com> Date: Mon, 23 Jun 2025 21:15:27 -0400 Subject: [PATCH 586/707] Updated doc'n with cscanf --- doc/funcref.sgml | 49 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 7e632f71f..82d5cf8bb 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -302,6 +302,7 @@ function. <item><ref id="cputcxy" name="cputcxy"> <item><ref id="cputs" name="cputs"> <item><ref id="cputsxy" name="cputsxy"> +<item><ref id="cscanf" name="cscanf"> <item><ref id="cursor" name="cursor"> <item><ref id="cvline" name="cvline"> <item><ref id="cvlinexy" name="cvlinexy"> @@ -2720,7 +2721,7 @@ see anything that you type. (See the description of <tt/cbm_k_scnkey()/.) <quote> <descrip> -<tag/Function/Input a string directly to the console. +<tag/Function/Input a string directly from the console. <tag/Header/<tt/<ref id="conio.h" name="conio.h">/ <tag/Declaration/<tt/char* __fastcall__ cgets (const char* buffer, int size);/ <tag/Description/The function inputs a string of at most <tt/size - 1/ @@ -2735,11 +2736,12 @@ be used in the presence of a prototype. </itemize> <tag/Availability/cc65 <tag/See also/ -<ref id="cgetc" name="cgetc"> +<ref id="cgetc" name="cgetc">, +<ref id="cscanf" name="cscanf"> <tag/Example/<verb> #include <conio.h> -int main () +int main (void) { char buffer[200], *p; @@ -3353,6 +3355,47 @@ be used in presence of a prototype. </quote> +<sect1>cscanf<label id="cscanf"><p> + +<quote> +<descrip> +<tag/Function/Read formatted input from the console +<tag/Header/<tt/<ref id="conio.h" name="conio.h">/ +<tag/Declaration/<tt/int cscanf (const char* format, ...);/ +<tag/Description/The <tt/cscanf()/ function scans input from the console under +control of the argument <tt/format/. Following the format string is a list of +addresses to receive values. The format string is identical to that of the +<tt/scanf()/ function. +<tag/Notes/<itemize> +<item>A direct call to <tt/cursor()/ may be required to show the cursor. +<item>Some control characters like backspaces are not recognized. +<item>A better user experience can sometimes be provided by using <tt/cgets()/ +to retrieve the input, and then using <tt/sscanf()/ to parse it. +</itemize> +<tag/Availability/cc65 +<tag/See also/ +<ref id="cgets" name="cgets">, +<ref id="cursor" name="cursor"> +<tag/Example/<verb> +#include <conio.h> + +int main (void) +{ + int a, b, c; + + cputs ("Type three integers that add to 100: "); + if (cscanf ("%d %d %d", &a, &b, &c) == 3 && a + b + c == 100) + cputs ("\r\nYou passed!\r\n"); + else + cputs ("\r\nYou failed!\r\n"); + + return 0; +} +</verb> +</descrip> +</quote> + + <sect1>cursor<label id="cursor"><p> <quote> From c0a1b1b887af536612987847c9344a1226bf4397 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 24 Jun 2025 18:02:24 +0200 Subject: [PATCH 587/707] Add an optimization step that removes compare instructions preceeding an RTS. Since nothing is passed back in the flags, these instructions have no effect. Fixes #2025. --- src/cc65/codeopt.c | 3 +++ src/cc65/coptcmp.c | 37 +++++++++++++++++++++++++++++++++++++ src/cc65/coptcmp.h | 5 +++++ 3 files changed, 45 insertions(+) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 19acfde74..f57417526 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -136,6 +136,7 @@ static OptFunc DOptCmp5 = { OptCmp5, "OptCmp5", 100, 0, static OptFunc DOptCmp7 = { OptCmp7, "OptCmp7", 85, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp8 = { OptCmp8, "OptCmp8", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp9 = { OptCmp9, "OptCmp9", 85, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp10 = { OptCmp10, "OptCmp10", 33, 0, 0, 0, 0, 0 }; static OptFunc DOptComplAX1 = { OptComplAX1, "OptComplAX1", 65, 0, 0, 0, 0, 0 }; static OptFunc DOptCondBranch1 = { OptCondBranch1, "OptCondBranch1", 80, 0, 0, 0, 0, 0 }; static OptFunc DOptCondBranch2 = { OptCondBranch2, "OptCondBranch2", 40, 0, 0, 0, 0, 0 }; @@ -251,6 +252,7 @@ static OptFunc* OptFuncs[] = { &DOptBranchDist, &DOptBranchDist2, &DOptCmp1, + &DOptCmp10, &DOptCmp2, &DOptCmp3, &DOptCmp4, @@ -729,6 +731,7 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptCondBranch3, 1); C += RunOptFunc (S, &DOptCondBranchC, 1); C += RunOptFunc (S, &DOptRTSJumps1, 1); + C += RunOptFunc (S, &DOptCmp10, 1); /* After OptRTSJumps1 */ C += RunOptFunc (S, &DOptBoolCmp, 1); C += RunOptFunc (S, &DOptBoolTrans, 1); C += RunOptFunc (S, &DOptBNegA2, 1); /* After OptCondBranch's */ diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index 2970b363b..25499dc3c 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -741,3 +741,40 @@ unsigned OptCmp9 (CodeSeg* S) /* Return the number of changes made */ return Changes; } + + + +unsigned OptCmp10 (CodeSeg* S) +/* Remove compare instructions before an RTS. This is safe since no C function +** passes back something in the flags. +*/ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* N; + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check for a compare followed by an RTS */ + if ((E->Info & OF_CMP) != 0 && /* Compare insn */ + (N = CS_GetNextEntry (S, I)) != 0 && /* Next entry ... */ + N->OPC == OP65_RTS) { /* ... is RTS */ + + /* Found, remove the compare */ + CS_DelEntry (S, I); + ++Changes; + } + + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} diff --git a/src/cc65/coptcmp.h b/src/cc65/coptcmp.h index dd188f7fc..ff58d37df 100644 --- a/src/cc65/coptcmp.h +++ b/src/cc65/coptcmp.h @@ -146,6 +146,11 @@ unsigned OptCmp9 (CodeSeg* S); ** flag instead of the carry flag and remove the asl. */ +unsigned OptCmp10 (CodeSeg* S); +/* Remove compare instructions before an RTS. This is safe since no C function +** passes back something in the flags. +*/ + /* End of coptcmp.h */ From 7be14a951c6ac9bfd5d7dacb7aab8a6f6c04cb7d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 24 Jun 2025 19:33:49 +0200 Subject: [PATCH 588/707] initial asm includes for c65 and mega65 --- asminc/c65.inc | 235 ++++++++++++++++++++++++++++++++++++++++++ asminc/cbm_kernal.inc | 57 +++++++++- asminc/cpu.mac | 15 ++- asminc/mega65.inc | 235 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 532 insertions(+), 10 deletions(-) create mode 100644 asminc/c65.inc create mode 100644 asminc/mega65.inc diff --git a/asminc/c65.inc b/asminc/c65.inc new file mode 100644 index 000000000..4c10431ab --- /dev/null +++ b/asminc/c65.inc @@ -0,0 +1,235 @@ + +; --------------------------------------------------------------------------- +; Zero page, Commodore stuff + +TXTPTR := $3C ; Pointer into BASIC source code +STATUS := $90 ; Kernal I/O completion status +FNAM_LEN := $B7 ; Length of filename +SECADR := $B9 ; Secondary address +DEVNUM := $BA ; Device number +FNAM := $BB ; Address of filename +FNAM_BANK := $BE ; Bank for filename +KEY_COUNT := $D0 ; Number of keys in input buffer +FKEY_COUNT := $D1 ; Characters for function key +MODE := $D7 ; 40-/80-column mode (bit 7: 80 columns) +GRAPHM := $D8 ; Graphics mode flags (bits 5-7) +CHARDIS := $D9 ; Bit 2 shadow for location $01 +CURS_X := $EC ; Cursor column +CURS_Y := $EB ; Cursor row +SCREEN_PTR := $E0 ; Pointer to current char in text screen +CRAM_PTR := $E2 ; Pointer to current char in color RAM +CHARCOLOR := $F1 +RVS := $F3 ; Reverse output flag +SCROLL := $F8 ; Disable scrolling flag + +BASIC_BUF := $0200 ; Location of command-line +BASIC_BUF_LEN = 161 ; Maximum length of command-line + +FKEY_LEN := $1000 ; Function key lengths +FKEY_TEXT := $100A ; Function key texts + +PALFLAG := $1103 ; $FF=PAL, $00=NTSC +INIT_STATUS := $1104 ; Flags: Reset/Restore initiation status +TIME := $110C ; 60HZ clock + +KBDREPEAT := $111a +KBDREPEATRATE := $111b +KBDREPEATDELAY := $111c + +; --------------------------------------------------------------------------- +; Vectors + +IRQVec := $0314 +BRKVec := $0316 +NMIVec := $0318 + +; --------------------------------------------------------------------------- +; I/O: VIC + +VIC := $D000 +VIC_SPR0_X := $D000 +VIC_SPR0_Y := $D001 +VIC_SPR1_X := $D002 +VIC_SPR1_Y := $D003 +VIC_SPR2_X := $D004 +VIC_SPR2_Y := $D005 +VIC_SPR3_X := $D006 +VIC_SPR3_Y := $D007 +VIC_SPR4_X := $D008 +VIC_SPR4_Y := $D009 +VIC_SPR5_X := $D00A +VIC_SPR5_Y := $D00B +VIC_SPR6_X := $D00C +VIC_SPR6_Y := $D00D +VIC_SPR7_X := $D00E +VIC_SPR7_Y := $D00F +VIC_SPR_HI_X := $D010 +VIC_SPR_ENA := $D015 +VIC_SPR_EXP_Y := $D017 +VIC_SPR_EXP_X := $D01D +VIC_SPR_MCOLOR := $D01C +VIC_SPR_BG_PRIO := $D01B +VIC_SPR_COLL := $D01E +VIC_SPR_BG_COLL := $D01F + +VIC_SPR_MCOLOR0 := $D025 +VIC_SPR_MCOLOR1 := $D026 + +VIC_SPR0_COLOR := $D027 +VIC_SPR1_COLOR := $D028 +VIC_SPR2_COLOR := $D029 +VIC_SPR3_COLOR := $D02A +VIC_SPR4_COLOR := $D02B +VIC_SPR5_COLOR := $D02C +VIC_SPR6_COLOR := $D02D +VIC_SPR7_COLOR := $D02E + +VIC_CTRL1 := $D011 +VIC_CTRL2 := $D016 + +VIC_HLINE := $D012 + +VIC_LPEN_X := $D013 +VIC_LPEN_Y := $D014 + +VIC_VIDEO_ADR := $D018 + +VIC_IRR := $D019 ; Interrupt request register +VIC_IMR := $D01A ; Interrupt mask register + +VIC_BORDERCOLOR := $D020 +VIC_BG_COLOR0 := $D021 +VIC_BG_COLOR1 := $D022 +VIC_BG_COLOR2 := $D023 +VIC_BG_COLOR3 := $D024 + + +; --------------------------------------------------------------------------- +; I/O: FDC + +FDC := $D080 + +; --------------------------------------------------------------------------- +; I/O: SID + +SID0 := $D400 +SID0_S1Lo := $D400 +SID0_S1Hi := $D401 +SID0_PB1Lo := $D402 +SID0_PB1Hi := $D403 +SID0_Ctl1 := $D404 +SID0_AD1 := $D405 +SID0_SUR1 := $D406 + +SID0_S2Lo := $D407 +SID0_S2Hi := $D408 +SID0_PB2Lo := $D409 +SID0_PB2Hi := $D40A +SID0_Ctl2 := $D40B +SID0_AD2 := $D40C +SID0_SUR2 := $D40D + +SID0_S3Lo := $D40E +SID0_S3Hi := $D40F +SID0_PB3Lo := $D410 +SID0_PB3Hi := $D411 +SID0_Ctl3 := $D412 +SID0_AD3 := $D413 +SID0_SUR3 := $D414 + +SID0_FltLo := $D415 +SID0_FltHi := $D416 +SID0_FltCtl := $D417 +SID0_Amp := $D418 +SID0_ADConv1 := $D419 +SID0_ADConv2 := $D41A +SID0_Noise := $D41B +SID0_Read3 := $D41C + +SID1 := $D420 +SID1_S1Lo := $D420 +SID1_S1Hi := $D421 +SID1_PB1Lo := $D422 +SID1_PB1Hi := $D423 +SID1_Ctl1 := $D424 +SID1_AD1 := $D425 +SID1_SUR1 := $D426 + +SID1_S2Lo := $D427 +SID1_S2Hi := $D428 +SID1_PB2Lo := $D429 +SID1_PB2Hi := $D42A +SID1_Ctl2 := $D42B +SID1_AD2 := $D42C +SID1_SUR2 := $D42D + +SID1_S3Lo := $D42E +SID1_S3Hi := $D42F +SID1_PB3Lo := $D430 +SID1_PB3Hi := $D431 +SID1_Ctl3 := $D432 +SID1_AD3 := $D433 +SID1_SUR3 := $D434 + +SID1_FltLo := $D435 +SID1_FltHi := $D436 +SID1_FltCtl := $D437 +SID1_Amp := $D438 +SID1_ADConv1 := $D439 +SID1_ADConv2 := $D43A +SID1_Noise := $D43B +SID1_Read3 := $D43C + +; --------------------------------------------------------------------------- +; I/O: Complex Interface Adapters + +CIA1 := $DC00 +CIA1_PRA := $DC00 ; Port A +CIA1_PRB := $DC01 ; Port B +CIA1_DDRA := $DC02 ; Data direction register for port A +CIA1_DDRB := $DC03 ; Data direction register for port B +CIA1_TA := $DC04 ; 16-bit timer A +CIA1_TB := $DC06 ; 16-bit timer B +CIA1_TOD10 := $DC08 ; Time-of-day tenths of a second +CIA1_TODSEC := $DC09 ; Time-of-day seconds +CIA1_TODMIN := $DC0A ; Time-of-day minutes +CIA1_TODHR := $DC0B ; Time-of-day hours +CIA1_SDR := $DC0C ; Serial data register +CIA1_ICR := $DC0D ; Interrupt control register +CIA1_CRA := $DC0E ; Control register for timer A +CIA1_CRB := $DC0F ; Control register for timer B + +CIA2 := $DD00 +CIA2_PRA := $DD00 +CIA2_PRB := $DD01 +CIA2_DDRA := $DD02 +CIA2_DDRB := $DD03 +CIA2_TA := $DD04 +CIA2_TB := $DD06 +CIA2_TOD10 := $DD08 +CIA2_TODSEC := $DD09 +CIA2_TODMIN := $DD0A +CIA2_TODHR := $DD0B +CIA2_SDR := $DD0C +CIA2_ICR := $DD0D +CIA2_CRA := $DD0E +CIA2_CRB := $DD0F + +; --------------------------------------------------------------------------- +; I/O: DMA + +DMA := $D700 + + +; --------------------------------------------------------------------------- +; Processor Port at $01 + +LORAM = $01 ; Enable the basic rom +HIRAM = $02 ; Enable the kernal rom +IOEN = $04 ; Enable I/O +CASSDATA = $08 ; Cassette data +CASSPLAY = $10 ; Cassette: Play +CASSMOT = $20 ; Cassette motor on +TP_FAST = $80 ; Switch Rossmoeller TurboProcess to fast mode + +RAMONLY = $F8 ; (~(LORAM | HIRAM | IOEN)) & $FF diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 4d78cf93f..e38131ab4 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -63,6 +63,35 @@ MOUSE_GET := $FF6B .endif +.if .def(__C65__) || .def (__MEGA65__) + ; extended C65 jump table + VERSIONQ := $FF2F + RESET_RUN := $FF32 + CURSOR := $FF35 + SAVEFL := $FF3B + GETIO := $FF41 + GETLFS := $FF44 + KEYLOCKS := $FF47 + ADDKEY := $FF4A + SPIN_SPOUT := $FF4D + CLSALL := $FF50 + C64MODE := $FF53 + MonitorCall := $FF56 + BOOT_SYS := $FF59 + PHOENIX := $FF5C + LKUPLA := $FF5F + LKUPSA := $FF62 + SWAPPER := $FF65 + PFKEY := $FF68 + SETBNK := $FF6B + JSRFAR := $FF6E + JMPFAR := $FF71 + LDA_FAR := $FF74 + STA_FAR := $FF77 + CMP_FAR := $FF7A + PRIMM := $FF7D +.endif + .if .def(__C128__) ; C128 extended jump table C64MODE := $FF4D @@ -83,7 +112,7 @@ PRIMM := $FF7D .endif -.if .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) +.if .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) || .def(__C65__) || .def (__MEGA65__) CINT := $FF81 IOINIT := $FF84 RAMTAS := $FF87 @@ -96,7 +125,7 @@ CINT := $FF7E .endif -.if .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) +.if .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) || .def(__C65__) || .def (__MEGA65__) RESTOR := $FF8A VECTOR := $FF8D .elseif .def(__CBM510__) || .def(__CBM610__) @@ -112,6 +141,17 @@ MEMBOT := $FF9C SCNKEY := $FF9F SETTMO := $FFA2 +.elseif .def(__C65__) || .def (__MEGA65__) + SETMSG := $FF90 + SECOND := $FF93 + TKSA := $FF96 + MEMTOP := $FF99 + MEMBOT := $FF9C + SCNKEY := $FF9F + MONEXIT := $FFA2 +.endif + +.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) || .def(__C65__) || .def(__MEGA65__) ACPTR := $FFA5 CIOUT := $FFA8 UNTLK := $FFAB @@ -136,7 +176,7 @@ CHRIN := $FFCF BSOUT := $FFD2 CHROUT := $FFD2 -.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) +.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) || .def(__C65__) || .def(__MEGA65__) LOAD := $FFD5 SAVE := $FFD8 SETTIM := $FFDB @@ -147,9 +187,14 @@ CHROUT := $FFD2 STOP := $FFE1 GETIN := $FFE4 CLALL := $FFE7 -UDTIM := $FFEA -.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) +.if .def(__C65__) || .def(__MEGA65__) +ScanStopKey := $FFEA +.else +UDTIM := $FFEA +.endif + +.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) || .def(__C65__) || .def(__MEGA65__) SCREEN := $FFED PLOT := $FFF0 IOBASE := $FFF3 @@ -189,4 +234,6 @@ UDTIM := $FFEA .elseif .def(__C16__) CLRSCR := $D88B KBDREAD := $D8C1 +.elseif .def(__C65__) || .def(__MEGA65__) +; CLRSCR := $E0EC ; ??? .endif diff --git a/asminc/cpu.mac b/asminc/cpu.mac index e3ab49014..be35265b7 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -1,12 +1,15 @@ -; CPU bitmask constants +; CPU bitmask constants (make sure this matches src/common/cpu.h) + CPU_ISET_NONE = $0001 CPU_ISET_6502 = $0002 CPU_ISET_6502X = $0004 CPU_ISET_6502DTV = $0008 + CPU_ISET_65SC02 = $0010 CPU_ISET_65C02 = $0020 CPU_ISET_65816 = $0040 CPU_ISET_SWEET16 = $0080 + CPU_ISET_HUC6280 = $0100 CPU_ISET_M740 = $0200 CPU_ISET_4510 = $0400 @@ -21,9 +24,11 @@ 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 CPU_SWEET16 = CPU_ISET_SWEET16 +; FIXME: CPU_ISET_65SC02 does not apply to the following, because the zp-indirect +; addressing was replaced with zp-indirect,z-indexed in 652SCE02 ; NOTE: HUC6280 removes "wai" ($cb) and "stp" ($db) from the 65C02 instruction set -CPU_HUC6280 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_HUC6280 -; NOTE: 45100 replaces "wai" ($cb) and "stp" ($db) of the 65C02 instruction set -CPU_4510 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_4510 -CPU_45GS02 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_4510|CPU_ISET_45GS02 +CPU_HUC6280 = CPU_ISET_6502|CPU_ISET_65C02|CPU_ISET_HUC6280 +; NOTE: 4510 replaces "wai" ($cb) and "stp" ($db) of the 65C02 instruction set +CPU_4510 = CPU_ISET_6502|CPU_ISET_65C02|CPU_ISET_4510 +CPU_45GS02 = CPU_ISET_6502|CPU_ISET_65C02|CPU_ISET_4510|CPU_ISET_45GS02 CPU_M740 = CPU_ISET_6502|CPU_ISET_M740 diff --git a/asminc/mega65.inc b/asminc/mega65.inc new file mode 100644 index 000000000..4c10431ab --- /dev/null +++ b/asminc/mega65.inc @@ -0,0 +1,235 @@ + +; --------------------------------------------------------------------------- +; Zero page, Commodore stuff + +TXTPTR := $3C ; Pointer into BASIC source code +STATUS := $90 ; Kernal I/O completion status +FNAM_LEN := $B7 ; Length of filename +SECADR := $B9 ; Secondary address +DEVNUM := $BA ; Device number +FNAM := $BB ; Address of filename +FNAM_BANK := $BE ; Bank for filename +KEY_COUNT := $D0 ; Number of keys in input buffer +FKEY_COUNT := $D1 ; Characters for function key +MODE := $D7 ; 40-/80-column mode (bit 7: 80 columns) +GRAPHM := $D8 ; Graphics mode flags (bits 5-7) +CHARDIS := $D9 ; Bit 2 shadow for location $01 +CURS_X := $EC ; Cursor column +CURS_Y := $EB ; Cursor row +SCREEN_PTR := $E0 ; Pointer to current char in text screen +CRAM_PTR := $E2 ; Pointer to current char in color RAM +CHARCOLOR := $F1 +RVS := $F3 ; Reverse output flag +SCROLL := $F8 ; Disable scrolling flag + +BASIC_BUF := $0200 ; Location of command-line +BASIC_BUF_LEN = 161 ; Maximum length of command-line + +FKEY_LEN := $1000 ; Function key lengths +FKEY_TEXT := $100A ; Function key texts + +PALFLAG := $1103 ; $FF=PAL, $00=NTSC +INIT_STATUS := $1104 ; Flags: Reset/Restore initiation status +TIME := $110C ; 60HZ clock + +KBDREPEAT := $111a +KBDREPEATRATE := $111b +KBDREPEATDELAY := $111c + +; --------------------------------------------------------------------------- +; Vectors + +IRQVec := $0314 +BRKVec := $0316 +NMIVec := $0318 + +; --------------------------------------------------------------------------- +; I/O: VIC + +VIC := $D000 +VIC_SPR0_X := $D000 +VIC_SPR0_Y := $D001 +VIC_SPR1_X := $D002 +VIC_SPR1_Y := $D003 +VIC_SPR2_X := $D004 +VIC_SPR2_Y := $D005 +VIC_SPR3_X := $D006 +VIC_SPR3_Y := $D007 +VIC_SPR4_X := $D008 +VIC_SPR4_Y := $D009 +VIC_SPR5_X := $D00A +VIC_SPR5_Y := $D00B +VIC_SPR6_X := $D00C +VIC_SPR6_Y := $D00D +VIC_SPR7_X := $D00E +VIC_SPR7_Y := $D00F +VIC_SPR_HI_X := $D010 +VIC_SPR_ENA := $D015 +VIC_SPR_EXP_Y := $D017 +VIC_SPR_EXP_X := $D01D +VIC_SPR_MCOLOR := $D01C +VIC_SPR_BG_PRIO := $D01B +VIC_SPR_COLL := $D01E +VIC_SPR_BG_COLL := $D01F + +VIC_SPR_MCOLOR0 := $D025 +VIC_SPR_MCOLOR1 := $D026 + +VIC_SPR0_COLOR := $D027 +VIC_SPR1_COLOR := $D028 +VIC_SPR2_COLOR := $D029 +VIC_SPR3_COLOR := $D02A +VIC_SPR4_COLOR := $D02B +VIC_SPR5_COLOR := $D02C +VIC_SPR6_COLOR := $D02D +VIC_SPR7_COLOR := $D02E + +VIC_CTRL1 := $D011 +VIC_CTRL2 := $D016 + +VIC_HLINE := $D012 + +VIC_LPEN_X := $D013 +VIC_LPEN_Y := $D014 + +VIC_VIDEO_ADR := $D018 + +VIC_IRR := $D019 ; Interrupt request register +VIC_IMR := $D01A ; Interrupt mask register + +VIC_BORDERCOLOR := $D020 +VIC_BG_COLOR0 := $D021 +VIC_BG_COLOR1 := $D022 +VIC_BG_COLOR2 := $D023 +VIC_BG_COLOR3 := $D024 + + +; --------------------------------------------------------------------------- +; I/O: FDC + +FDC := $D080 + +; --------------------------------------------------------------------------- +; I/O: SID + +SID0 := $D400 +SID0_S1Lo := $D400 +SID0_S1Hi := $D401 +SID0_PB1Lo := $D402 +SID0_PB1Hi := $D403 +SID0_Ctl1 := $D404 +SID0_AD1 := $D405 +SID0_SUR1 := $D406 + +SID0_S2Lo := $D407 +SID0_S2Hi := $D408 +SID0_PB2Lo := $D409 +SID0_PB2Hi := $D40A +SID0_Ctl2 := $D40B +SID0_AD2 := $D40C +SID0_SUR2 := $D40D + +SID0_S3Lo := $D40E +SID0_S3Hi := $D40F +SID0_PB3Lo := $D410 +SID0_PB3Hi := $D411 +SID0_Ctl3 := $D412 +SID0_AD3 := $D413 +SID0_SUR3 := $D414 + +SID0_FltLo := $D415 +SID0_FltHi := $D416 +SID0_FltCtl := $D417 +SID0_Amp := $D418 +SID0_ADConv1 := $D419 +SID0_ADConv2 := $D41A +SID0_Noise := $D41B +SID0_Read3 := $D41C + +SID1 := $D420 +SID1_S1Lo := $D420 +SID1_S1Hi := $D421 +SID1_PB1Lo := $D422 +SID1_PB1Hi := $D423 +SID1_Ctl1 := $D424 +SID1_AD1 := $D425 +SID1_SUR1 := $D426 + +SID1_S2Lo := $D427 +SID1_S2Hi := $D428 +SID1_PB2Lo := $D429 +SID1_PB2Hi := $D42A +SID1_Ctl2 := $D42B +SID1_AD2 := $D42C +SID1_SUR2 := $D42D + +SID1_S3Lo := $D42E +SID1_S3Hi := $D42F +SID1_PB3Lo := $D430 +SID1_PB3Hi := $D431 +SID1_Ctl3 := $D432 +SID1_AD3 := $D433 +SID1_SUR3 := $D434 + +SID1_FltLo := $D435 +SID1_FltHi := $D436 +SID1_FltCtl := $D437 +SID1_Amp := $D438 +SID1_ADConv1 := $D439 +SID1_ADConv2 := $D43A +SID1_Noise := $D43B +SID1_Read3 := $D43C + +; --------------------------------------------------------------------------- +; I/O: Complex Interface Adapters + +CIA1 := $DC00 +CIA1_PRA := $DC00 ; Port A +CIA1_PRB := $DC01 ; Port B +CIA1_DDRA := $DC02 ; Data direction register for port A +CIA1_DDRB := $DC03 ; Data direction register for port B +CIA1_TA := $DC04 ; 16-bit timer A +CIA1_TB := $DC06 ; 16-bit timer B +CIA1_TOD10 := $DC08 ; Time-of-day tenths of a second +CIA1_TODSEC := $DC09 ; Time-of-day seconds +CIA1_TODMIN := $DC0A ; Time-of-day minutes +CIA1_TODHR := $DC0B ; Time-of-day hours +CIA1_SDR := $DC0C ; Serial data register +CIA1_ICR := $DC0D ; Interrupt control register +CIA1_CRA := $DC0E ; Control register for timer A +CIA1_CRB := $DC0F ; Control register for timer B + +CIA2 := $DD00 +CIA2_PRA := $DD00 +CIA2_PRB := $DD01 +CIA2_DDRA := $DD02 +CIA2_DDRB := $DD03 +CIA2_TA := $DD04 +CIA2_TB := $DD06 +CIA2_TOD10 := $DD08 +CIA2_TODSEC := $DD09 +CIA2_TODMIN := $DD0A +CIA2_TODHR := $DD0B +CIA2_SDR := $DD0C +CIA2_ICR := $DD0D +CIA2_CRA := $DD0E +CIA2_CRB := $DD0F + +; --------------------------------------------------------------------------- +; I/O: DMA + +DMA := $D700 + + +; --------------------------------------------------------------------------- +; Processor Port at $01 + +LORAM = $01 ; Enable the basic rom +HIRAM = $02 ; Enable the kernal rom +IOEN = $04 ; Enable I/O +CASSDATA = $08 ; Cassette data +CASSPLAY = $10 ; Cassette: Play +CASSMOT = $20 ; Cassette motor on +TP_FAST = $80 ; Switch Rossmoeller TurboProcess to fast mode + +RAMONLY = $F8 ; (~(LORAM | HIRAM | IOEN)) & $FF From 681b49a1119e9539250da723e208ef963684bfbd Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 24 Jun 2025 19:55:28 +0200 Subject: [PATCH 589/707] initial target header files for c65 and mega65 --- include/c65.h | 102 +++++++++++++++++++++++++++++++++++++++++++++++ include/cbm.h | 4 ++ include/mega65.h | 102 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 include/c65.h create mode 100644 include/mega65.h diff --git a/include/c65.h b/include/c65.h new file mode 100644 index 000000000..35ddadc3d --- /dev/null +++ b/include/c65.h @@ -0,0 +1,102 @@ +/*****************************************************************************/ +/* */ +/* c65.h */ +/* */ +/* C65 system specific definitions */ +/* */ +/* */ +/* */ +/* (C) 1998-2013, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _C65_H +#define _C65_H + + + +/* Check for errors */ +#if !defined(__C65__) +# error This module may only be used when compiling for the MEGA65! +#endif + + + +/* Additional key defines */ +#define CH_F1 133 +#define CH_F2 137 +#define CH_F3 134 +#define CH_F4 138 +#define CH_F5 135 +#define CH_F6 139 +#define CH_F7 136 +#define CH_F8 140 + +/* Color defines */ +#define COLOR_BLACK 0x00 +#define COLOR_WHITE 0x01 +#define COLOR_RED 0x02 +#define COLOR_CYAN 0x03 +#define COLOR_PURPLE 0x04 +#define COLOR_GREEN 0x05 +#define COLOR_BLUE 0x06 +#define COLOR_YELLOW 0x07 +#define COLOR_ORANGE 0x08 +#define COLOR_BROWN 0x09 +#define COLOR_LIGHTRED 0x0A +#define COLOR_GRAY1 0x0B +#define COLOR_GRAY2 0x0C +#define COLOR_LIGHTGREEN 0x0D +#define COLOR_LIGHTBLUE 0x0E +#define COLOR_GRAY3 0x0F + +/* Masks for joy_read */ +#define JOY_UP_MASK 0x01 +#define JOY_DOWN_MASK 0x02 +#define JOY_LEFT_MASK 0x04 +#define JOY_RIGHT_MASK 0x08 +#define JOY_BTN_1_MASK 0x10 + + +/* Define hardware */ +#include <_vic2.h> +#define VIC (*(struct __vic2*)0xD000) + +#include <_sid.h> +#define SID1 (*(struct __sid*)0xD400) +#define SID2 (*(struct __sid*)0xD420) + +#include <_6526.h> +#define CIA1 (*(struct __6526*)0xDC00) +#define CIA2 (*(struct __6526*)0xDD00) + + +/* Define special memory areas */ +#define COLOR_RAM ((unsigned char*)0xD800) + + +/* End of c65.h */ +#endif diff --git a/include/cbm.h b/include/cbm.h index 0679b2d65..89c01ffc0 100644 --- a/include/cbm.h +++ b/include/cbm.h @@ -67,6 +67,10 @@ # include <pet.h> #elif defined(__CX16__) && !defined(_CX16_H) # include <cx16.h> +#elif defined(__C65__) && !defined(_C65_H) +# include <c65.h> +#elif defined(__MEGA65__) && !defined(_MEGA65_H) +# include <mega65.h> #endif /* Include definitions for CBM file types */ diff --git a/include/mega65.h b/include/mega65.h new file mode 100644 index 000000000..260ab5e5f --- /dev/null +++ b/include/mega65.h @@ -0,0 +1,102 @@ +/*****************************************************************************/ +/* */ +/* mega65.h */ +/* */ +/* MEGA65 system specific definitions */ +/* */ +/* */ +/* */ +/* (C) 1998-2013, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _MEGA65_H +#define _MEGA65_H + + + +/* Check for errors */ +#if !defined(__MEGA65__) +# error This module may only be used when compiling for the MEGA65! +#endif + + + +/* Additional key defines */ +#define CH_F1 133 +#define CH_F2 137 +#define CH_F3 134 +#define CH_F4 138 +#define CH_F5 135 +#define CH_F6 139 +#define CH_F7 136 +#define CH_F8 140 + +/* Color defines */ +#define COLOR_BLACK 0x00 +#define COLOR_WHITE 0x01 +#define COLOR_RED 0x02 +#define COLOR_CYAN 0x03 +#define COLOR_PURPLE 0x04 +#define COLOR_GREEN 0x05 +#define COLOR_BLUE 0x06 +#define COLOR_YELLOW 0x07 +#define COLOR_ORANGE 0x08 +#define COLOR_BROWN 0x09 +#define COLOR_LIGHTRED 0x0A +#define COLOR_GRAY1 0x0B +#define COLOR_GRAY2 0x0C +#define COLOR_LIGHTGREEN 0x0D +#define COLOR_LIGHTBLUE 0x0E +#define COLOR_GRAY3 0x0F + +/* Masks for joy_read */ +#define JOY_UP_MASK 0x01 +#define JOY_DOWN_MASK 0x02 +#define JOY_LEFT_MASK 0x04 +#define JOY_RIGHT_MASK 0x08 +#define JOY_BTN_1_MASK 0x10 + + +/* Define hardware */ +#include <_vic2.h> +#define VIC (*(struct __vic2*)0xD000) + +#include <_sid.h> +#define SID1 (*(struct __sid*)0xD400) +#define SID2 (*(struct __sid*)0xD420) + +#include <_6526.h> +#define CIA1 (*(struct __6526*)0xDC00) +#define CIA2 (*(struct __6526*)0xDD00) + + +/* Define special memory areas */ +#define COLOR_RAM ((unsigned char*)0xD800) + + +/* End of mega65.h */ +#endif From 7a6c60ade423c186d11b89be9fb1d99aa8a33a6b Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 24 Jun 2025 20:21:43 +0200 Subject: [PATCH 590/707] Do also sort variables to satisfy sorted_codeopt.sh. --- src/cc65/codeopt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index f57417526..e9cf8914f 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -129,6 +129,7 @@ static OptFunc DOptBoolUnary3 = { OptBoolUnary3, "OptBoolUnary3", 40, 0, static OptFunc DOptBranchDist = { OptBranchDist, "OptBranchDist", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptBranchDist2 = { OptBranchDist2, "OptBranchDist2", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp1 = { OptCmp1, "OptCmp1", 42, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp10 = { OptCmp10, "OptCmp10", 33, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp2 = { OptCmp2, "OptCmp2", 85, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp3 = { OptCmp3, "OptCmp3", 75, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp4 = { OptCmp4, "OptCmp4", 75, 0, 0, 0, 0, 0 }; @@ -136,7 +137,6 @@ static OptFunc DOptCmp5 = { OptCmp5, "OptCmp5", 100, 0, static OptFunc DOptCmp7 = { OptCmp7, "OptCmp7", 85, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp8 = { OptCmp8, "OptCmp8", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp9 = { OptCmp9, "OptCmp9", 85, 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp10 = { OptCmp10, "OptCmp10", 33, 0, 0, 0, 0, 0 }; static OptFunc DOptComplAX1 = { OptComplAX1, "OptComplAX1", 65, 0, 0, 0, 0, 0 }; static OptFunc DOptCondBranch1 = { OptCondBranch1, "OptCondBranch1", 80, 0, 0, 0, 0, 0 }; static OptFunc DOptCondBranch2 = { OptCondBranch2, "OptCondBranch2", 40, 0, 0, 0, 0, 0 }; From a37a88d5bf7c5a0a7856e680e8a295c8f72f75a2 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 24 Jun 2025 21:19:38 +0200 Subject: [PATCH 591/707] std cbm tgi colors --- include/c65.h | 18 ++++++++++++++++++ include/mega65.h | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/c65.h b/include/c65.h index 35ddadc3d..5ba485978 100644 --- a/include/c65.h +++ b/include/c65.h @@ -73,6 +73,24 @@ #define COLOR_LIGHTBLUE 0x0E #define COLOR_GRAY3 0x0F +/* TGI color defines */ +#define TGI_COLOR_BLACK COLOR_BLACK +#define TGI_COLOR_WHITE COLOR_WHITE +#define TGI_COLOR_RED COLOR_RED +#define TGI_COLOR_CYAN COLOR_CYAN +#define TGI_COLOR_PURPLE COLOR_PURPLE +#define TGI_COLOR_GREEN COLOR_GREEN +#define TGI_COLOR_BLUE COLOR_BLUE +#define TGI_COLOR_YELLOW COLOR_YELLOW +#define TGI_COLOR_ORANGE COLOR_ORANGE +#define TGI_COLOR_BROWN COLOR_BROWN +#define TGI_COLOR_LIGHTRED COLOR_LIGHTRED +#define TGI_COLOR_GRAY1 COLOR_GRAY1 +#define TGI_COLOR_GRAY2 COLOR_GRAY2 +#define TGI_COLOR_LIGHTGREEN COLOR_LIGHTGREEN +#define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE +#define TGI_COLOR_GRAY3 COLOR_GRAY3 + /* Masks for joy_read */ #define JOY_UP_MASK 0x01 #define JOY_DOWN_MASK 0x02 diff --git a/include/mega65.h b/include/mega65.h index 260ab5e5f..9f13d2e6c 100644 --- a/include/mega65.h +++ b/include/mega65.h @@ -73,6 +73,24 @@ #define COLOR_LIGHTBLUE 0x0E #define COLOR_GRAY3 0x0F +/* TGI color defines */ +#define TGI_COLOR_BLACK COLOR_BLACK +#define TGI_COLOR_WHITE COLOR_WHITE +#define TGI_COLOR_RED COLOR_RED +#define TGI_COLOR_CYAN COLOR_CYAN +#define TGI_COLOR_PURPLE COLOR_PURPLE +#define TGI_COLOR_GREEN COLOR_GREEN +#define TGI_COLOR_BLUE COLOR_BLUE +#define TGI_COLOR_YELLOW COLOR_YELLOW +#define TGI_COLOR_ORANGE COLOR_ORANGE +#define TGI_COLOR_BROWN COLOR_BROWN +#define TGI_COLOR_LIGHTRED COLOR_LIGHTRED +#define TGI_COLOR_GRAY1 COLOR_GRAY1 +#define TGI_COLOR_GRAY2 COLOR_GRAY2 +#define TGI_COLOR_LIGHTGREEN COLOR_LIGHTGREEN +#define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE +#define TGI_COLOR_GRAY3 COLOR_GRAY3 + /* Masks for joy_read */ #define JOY_UP_MASK 0x01 #define JOY_DOWN_MASK 0x02 From bfb16888d142dcefce054c307d74a82ccd0673fc Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 24 Jun 2025 21:20:31 +0200 Subject: [PATCH 592/707] simple linker config for c65 and mega65 --- cfg/c65.cfg | 44 ++++++++++++++++++++++++++++++++++++++++++++ cfg/mega65.cfg | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 cfg/c65.cfg create mode 100644 cfg/mega65.cfg diff --git a/cfg/c65.cfg b/cfg/c65.cfg new file mode 100644 index 000000000..914f84f3c --- /dev/null +++ b/cfg/c65.cfg @@ -0,0 +1,44 @@ +FEATURES { + STARTADDRESS: default = $2001; +} +SYMBOLS { + __LOADADDR__: type = import; + __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __HIMEM__: type = weak, value = $8000; +} +MEMORY { + ZP: file = "", define = yes, start = $0002, size = $001A; + LOADADDR: file = %O, start = %S - 2, size = $0002; + HEADER: file = %O, define = yes, start = %S, size = $0010; + MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__; + BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__; +} +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; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = rw; # uninitialized, but reserves output space + 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__; +} diff --git a/cfg/mega65.cfg b/cfg/mega65.cfg new file mode 100644 index 000000000..914f84f3c --- /dev/null +++ b/cfg/mega65.cfg @@ -0,0 +1,44 @@ +FEATURES { + STARTADDRESS: default = $2001; +} +SYMBOLS { + __LOADADDR__: type = import; + __EXEHDR__: type = import; + __STACKSIZE__: type = weak, value = $0800; # 2k stack + __HIMEM__: type = weak, value = $8000; +} +MEMORY { + ZP: file = "", define = yes, start = $0002, size = $001A; + LOADADDR: file = %O, start = %S - 2, size = $0002; + HEADER: file = %O, define = yes, start = %S, size = $0010; + MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__; + BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__; +} +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; + RODATA: load = MAIN, type = ro; + DATA: load = MAIN, type = rw; + INIT: load = MAIN, type = rw; # uninitialized, but reserves output space + 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__; +} From 450c8f7c558cd74bd9c5b1e4c77bb8914e1a1d1e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 24 Jun 2025 21:23:04 +0200 Subject: [PATCH 593/707] startup code and minimalist kernal support for c65 and mega65 --- asminc/cbm_kernal.inc | 6 +- libsrc/c65/crt0.s | 124 +++++++++++++++++++++++++++++++++++++++++ libsrc/c65/kernal.s | 48 ++++++++++++++++ libsrc/mega65/crt0.s | 124 +++++++++++++++++++++++++++++++++++++++++ libsrc/mega65/kernal.s | 48 ++++++++++++++++ 5 files changed, 347 insertions(+), 3 deletions(-) create mode 100644 libsrc/c65/crt0.s create mode 100644 libsrc/c65/kernal.s create mode 100644 libsrc/mega65/crt0.s create mode 100644 libsrc/mega65/kernal.s diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index e38131ab4..a2fb05cb0 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -218,10 +218,10 @@ UDTIM := $FFEA KBDREAD := $E5CF UPDCRAMPTR := $EAB2 .elseif .def(__C64__) - CLRSCR := $E544 - KBDREAD := $E5B4 + CLRSCR := $E544 ; Clear the screen + KBDREAD := $E5B4 ; Get Character From Keyboard Buffer NMIEXIT := $FEBC - UPDCRAMPTR := $EA24 + UPDCRAMPTR := $EA24 ; Update color ram pointer .elseif .def(__C128__) CLRSCR := $C142 KBDREAD := $C006 diff --git a/libsrc/c65/crt0.s b/libsrc/c65/crt0.s new file mode 100644 index 000000000..855b4ccf6 --- /dev/null +++ b/libsrc/c65/crt0.s @@ -0,0 +1,124 @@ +; +; Startup code for cc65 (C65 version) +; + + .export _exit + .export __STARTUP__ : absolute = 1 ; Mark as startup + + .import initlib, donelib + .import zerobss, callmain + .import BSOUT + .import __MAIN_START__, __MAIN_SIZE__ ; Linker generated + .import __STACKSIZE__ ; from configure file + + .include "zeropage.inc" + .include "c65.inc" + + +; ------------------------------------------------------------------------ +; Startup code + +.segment "STARTUP" + +Start: + +; Switch off the BASIC ROM. + +; FIXME +; lda $01 +; sta mmusave ; Save the memory configuration +; and #$F8 +; ora #$06 ; Enable Kernal+I/O, disable BASIC +; sta $01 +; sei +; lda #%00000000 ; lower offset 15-8 +; ldx #%00000000 ; map blk3-1 | lower offset 19-6 +; ldy #%00000000 ; upper offset 15-8 +; ldz #%00000000 ; map blk7-4 | upper offset 19-6 +; map +; eom + + tsx + stx spsave ; Save the system stack ptr + +; Save space by putting some of the start-up code in the ONCE segment, +; which can be re-used by the BSS segment, the heap and the C stack. + + jsr init + +; Clear the BSS data. + + jsr zerobss + +; Push the command-line arguments; and, call main(). + + jsr callmain + +; Back from main() [this is also the exit() entry]. Run the module destructors. + +_exit: pha ; Save the return code on stack + jsr donelib + +; Copy back the zero-page stuff. + + ldx #zpspace-1 +L2: lda zpsave,x + sta c_sp,x + dex + bpl L2 + +; Place the program return code into BASIC's status variable. + + pla + sta STATUS + +; Restore the system stuff. + + ldx spsave + txs ; Restore stack pointer + +; Back to BASIC. + + rts + + +; ------------------------------------------------------------------------ + +.segment "ONCE" + +init: + +; Save the zero-page locations that we need. + + ldx #zpspace-1 +L1: lda c_sp,x + sta zpsave,x + dex + bpl L1 + +; Set up the stack. + + lda #<(__MAIN_START__ + __MAIN_SIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__) + sta c_sp + stx c_sp+1 ; Set argument stack ptr + +; Switch to the second charset. + +; FIXME + lda #14 + jsr BSOUT + +; Call the module constructors. + + jmp initlib + + +; ------------------------------------------------------------------------ +; Data + +.segment "INIT" + +mmusave:.res 1 +spsave: .res 1 +zpsave: .res zpspace diff --git a/libsrc/c65/kernal.s b/libsrc/c65/kernal.s new file mode 100644 index 000000000..ea07f9ce6 --- /dev/null +++ b/libsrc/c65/kernal.s @@ -0,0 +1,48 @@ +; +; Ullrich von Bassewitz, 19.11.2002 +; +; C65 Kernal functions +; + + .include "cbm_kernal.inc" + + .export CINT + .export IOINIT + .export RAMTAS + .export RESTOR + .export VECTOR + .export SETMSG + .export SECOND + .export TKSA + .export MEMTOP + .export MEMBOT + .export SCNKEY + .export ACPTR + .export CIOUT + .export UNTLK + .export UNLSN + .export LISTEN + .export TALK + .export READST + .export SETLFS + .export SETNAM + .export OPEN + .export CLOSE + .export CHKIN + .export CKOUT + .export CLRCH + .export BASIN + .export CHRIN + .export BSOUT + .export CHROUT + .export LOAD + .export SAVE + .export SETTIM + .export RDTIM + .export STOP + .export GETIN + .export CLALL + .export UDTIM + .export SCREEN + .export IOBASE + .export PLOT diff --git a/libsrc/mega65/crt0.s b/libsrc/mega65/crt0.s new file mode 100644 index 000000000..401095c55 --- /dev/null +++ b/libsrc/mega65/crt0.s @@ -0,0 +1,124 @@ +; +; Startup code for cc65 (MEGA65 version) +; + + .export _exit + .export __STARTUP__ : absolute = 1 ; Mark as startup + + .import initlib, donelib + .import zerobss, callmain + .import BSOUT + .import __MAIN_START__, __MAIN_SIZE__ ; Linker generated + .import __STACKSIZE__ ; from configure file + + .include "zeropage.inc" + .include "mega65.inc" + + +; ------------------------------------------------------------------------ +; Startup code + +.segment "STARTUP" + +Start: + +; Switch off the BASIC ROM. + +; FIXME +; lda $01 +; sta mmusave ; Save the memory configuration +; and #$F8 +; ora #$06 ; Enable Kernal+I/O, disable BASIC +; sta $01 +; sei +; lda #%00000000 ; lower offset 15-8 +; ldx #%00000000 ; map blk3-1 | lower offset 19-6 +; ldy #%00000000 ; upper offset 15-8 +; ldz #%00000000 ; map blk7-4 | upper offset 19-6 +; map +; eom + + tsx + stx spsave ; Save the system stack ptr + +; Save space by putting some of the start-up code in the ONCE segment, +; which can be re-used by the BSS segment, the heap and the C stack. + + jsr init + +; Clear the BSS data. + + jsr zerobss + +; Push the command-line arguments; and, call main(). + + jsr callmain + +; Back from main() [this is also the exit() entry]. Run the module destructors. + +_exit: pha ; Save the return code on stack + jsr donelib + +; Copy back the zero-page stuff. + + ldx #zpspace-1 +L2: lda zpsave,x + sta c_sp,x + dex + bpl L2 + +; Place the program return code into BASIC's status variable. + + pla + sta STATUS + +; Restore the system stuff. + + ldx spsave + txs ; Restore stack pointer + +; Back to BASIC. + + rts + + +; ------------------------------------------------------------------------ + +.segment "ONCE" + +init: + +; Save the zero-page locations that we need. + + ldx #zpspace-1 +L1: lda c_sp,x + sta zpsave,x + dex + bpl L1 + +; Set up the stack. + + lda #<(__MAIN_START__ + __MAIN_SIZE__) + ldx #>(__MAIN_START__ + __MAIN_SIZE__) + sta c_sp + stx c_sp+1 ; Set argument stack ptr + +; Switch to the second charset. + +; FIXME + lda #14 + jsr BSOUT + +; Call the module constructors. + + jmp initlib + + +; ------------------------------------------------------------------------ +; Data + +.segment "INIT" + +mmusave:.res 1 +spsave: .res 1 +zpsave: .res zpspace diff --git a/libsrc/mega65/kernal.s b/libsrc/mega65/kernal.s new file mode 100644 index 000000000..45f4c4d02 --- /dev/null +++ b/libsrc/mega65/kernal.s @@ -0,0 +1,48 @@ +; +; Ullrich von Bassewitz, 19.11.2002 +; +; MEGA65 Kernal functions +; + + .include "cbm_kernal.inc" + + .export CINT + .export IOINIT + .export RAMTAS + .export RESTOR + .export VECTOR + .export SETMSG + .export SECOND + .export TKSA + .export MEMTOP + .export MEMBOT + .export SCNKEY + .export ACPTR + .export CIOUT + .export UNTLK + .export UNLSN + .export LISTEN + .export TALK + .export READST + .export SETLFS + .export SETNAM + .export OPEN + .export CLOSE + .export CHKIN + .export CKOUT + .export CLRCH + .export BASIN + .export CHRIN + .export BSOUT + .export CHROUT + .export LOAD + .export SAVE + .export SETTIM + .export RDTIM + .export STOP + .export GETIN + .export CLALL + .export UDTIM + .export SCREEN + .export IOBASE + .export PLOT From d374ea2cde07f6dbfc3cfe09d4857e2fcc387c67 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 24 Jun 2025 21:30:53 +0200 Subject: [PATCH 594/707] include target header to allow lib to build --- libsrc/cbm/cpeekc.s | 4 ++++ libsrc/cbm/cpeekcolor.s | 4 ++++ libsrc/cbm/cpeekrevers.s | 4 ++++ libsrc/cbm/cpeeks.s | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/libsrc/cbm/cpeekc.s b/libsrc/cbm/cpeekc.s index 05c7fc718..32dc0456e 100644 --- a/libsrc/cbm/cpeekc.s +++ b/libsrc/cbm/cpeekc.s @@ -22,6 +22,10 @@ .include "pet.inc" .elseif .def(__VIC20__) .include "vic20.inc" +.elseif .def(__C65__) + .include "c65.inc" +.elseif .def(__MEGA65__) + .include "mega65.inc" .endif diff --git a/libsrc/cbm/cpeekcolor.s b/libsrc/cbm/cpeekcolor.s index 9c961b771..a0d7efe6c 100644 --- a/libsrc/cbm/cpeekcolor.s +++ b/libsrc/cbm/cpeekcolor.s @@ -17,6 +17,10 @@ .include "c64.inc" .elseif .def(__VIC20__) .include "vic20.inc" +.elseif .def(__C65__) + .include "c65.inc" +.elseif .def(__MEGA65__) + .include "mega65.inc" .endif diff --git a/libsrc/cbm/cpeekrevers.s b/libsrc/cbm/cpeekrevers.s index e8e210167..0e500605d 100644 --- a/libsrc/cbm/cpeekrevers.s +++ b/libsrc/cbm/cpeekrevers.s @@ -22,6 +22,10 @@ .include "pet.inc" .elseif .def(__VIC20__) .include "vic20.inc" +.elseif .def(__C65__) + .include "c65.inc" +.elseif .def(__MEGA65__) + .include "mega65.inc" .endif diff --git a/libsrc/cbm/cpeeks.s b/libsrc/cbm/cpeeks.s index 215998e37..d73192d73 100644 --- a/libsrc/cbm/cpeeks.s +++ b/libsrc/cbm/cpeeks.s @@ -26,6 +26,10 @@ .include "pet.inc" .elseif .def(__VIC20__) .include "vic20.inc" +.elseif .def(__C65__) + .include "c65.inc" +.elseif .def(__MEGA65__) + .include "mega65.inc" .endif From d6cc8939404b1bbba68efd893dd140b6f9f2a623 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 24 Jun 2025 21:39:39 +0200 Subject: [PATCH 595/707] fix instruction set bits set by the compiler. in particular do not set the 65SC02 bit for 4510/45GS02, else we get clashes with sta(zp) --- src/common/cpu.c | 26 ++++++++++++++++---------- src/common/cpu.h | 4 ++-- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index 2c29eb1c4..54bb8a3fb 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -66,20 +66,26 @@ const char* CPUNames[CPU_COUNT] = { "45GS02" }; -/* Tables with CPU instruction sets */ +/* Tables with CPU instruction sets + * NOTE: make sure to only combine the instruction sets that are 100% compatible + */ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_NONE, CPU_ISET_6502, - CPU_ISET_6502 | CPU_ISET_6502X, - CPU_ISET_6502 | CPU_ISET_6502DTV, - CPU_ISET_6502 | CPU_ISET_65SC02, - CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, - CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_65816, + CPU_ISET_6502X | CPU_ISET_6502, + CPU_ISET_6502DTV | CPU_ISET_6502, + CPU_ISET_65SC02 | CPU_ISET_6502, + CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02, + /* FIXME: does 65816 have both wai/stp and indirect-zp (without z)? */ + CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, CPU_ISET_SWEET16, - CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_HUC6280, - CPU_ISET_6502 | CPU_ISET_M740, - CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_4510, - CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_4510 | CPU_ISET_45GS02, + /* FIXME: HUC6280 does not have wai/stp */ + CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + CPU_ISET_M740 | CPU_ISET_6502, + /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ + /* FIXME: 4510 does not have wai/stp */ + CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02, + CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_4510, }; diff --git a/src/common/cpu.h b/src/common/cpu.h index 6d8b72469..81795e146 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -47,7 +47,7 @@ /* CPUs */ typedef enum { CPU_UNKNOWN = -1, /* Not specified or invalid target */ - CPU_NONE, /* No CPU - for assembler */ + CPU_NONE = 0, /* No CPU - for assembler */ CPU_6502, CPU_6502X, /* "Extended", that is: with illegal opcodes */ CPU_6502DTV, /* CPU_6502 + DTV extra and illegal opcodes */ @@ -62,7 +62,7 @@ typedef enum { CPU_COUNT /* Number of different CPUs */ } cpu_t; -/* CPU instruction sets */ +/* CPU instruction sets (make sure this matches asminc/cpu.mac) */ enum { CPU_ISET_NONE = 1 << CPU_NONE, CPU_ISET_6502 = 1 << CPU_6502, From faa287f57888540bd7c50caf693acd787dbed085 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 24 Jun 2025 21:40:59 +0200 Subject: [PATCH 596/707] enable building library and samples --- libsrc/Makefile | 13 +++---------- samples/Makefile | 8 ++++++++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index 9bbb0aadb..9e1592dd3 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -11,9 +11,11 @@ endif CBMS = c128 \ c16 \ c64 \ + c65 \ cbm510 \ cbm610 \ cx16 \ + mega65 \ pet \ plus4 \ vic20 @@ -21,7 +23,6 @@ CBMS = c128 \ GEOS = geos-apple \ geos-cbm -# FIXME: c65 (and perhaps mega65?) should be moved up to CBMS maybe TARGETS = agat \ apple2 \ apple2enh \ @@ -31,7 +32,6 @@ TARGETS = agat \ atari5200 \ atari7800 \ atmos \ - c65 \ creativision \ $(CBMS) \ $(GEOS) \ @@ -47,8 +47,7 @@ TARGETS = agat \ sim65c02 \ supervision \ sym1 \ - telestrat \ - mega65 + telestrat TARGETTEST = none \ sim6502 \ @@ -196,11 +195,6 @@ ifeq ($(TARGET),$(filter $(TARGET),$(GEOS))) SRCDIRS += $(addprefix geos-common/,$(GEOSDIRS)) endif -ifeq ($(TARGET),c65) -# FIXME: this does not work because of the SP vs C_SP clash -else ifeq ($(TARGET),mega65) -# FIXME: this does not work because of the SP vs C_SP clash -else SRCDIRS += common \ conio \ dbg \ @@ -211,7 +205,6 @@ SRCDIRS += common \ serial \ tgi \ zlib -endif vpath %.s $(SRCDIRS) vpath %.c $(SRCDIRS) diff --git a/samples/Makefile b/samples/Makefile index 0a56af3c1..8974ce1b6 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -240,6 +240,9 @@ EXELIST_c64 = \ tinyshell \ tgidemo +EXELIST_c65 = \ + checkversion + EXELIST_c128 = \ ascii \ checkversion \ @@ -312,6 +315,9 @@ EXELIST_lunix = \ EXELIST_lynx = \ notavailable +EXELIST_mega65 = \ + checkversion + EXELIST_nes = \ hello @@ -418,6 +424,7 @@ TARGETS := \ c128 \ c16 \ c64 \ + c65 \ cbm510 \ cbm610 \ creativision \ @@ -426,6 +433,7 @@ TARGETS := \ kim1 \ lunix \ lynx \ + mega65 \ nes \ osic1p \ pce \ From f787e0857aa9396cece5b534d6971e7aeba0bb89 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 24 Jun 2025 21:52:48 +0200 Subject: [PATCH 597/707] remove non existing kernal export --- asminc/cpu.mac | 21 ++++++++++----------- libsrc/c65/kernal.s | 1 - libsrc/mega65/kernal.s | 1 - 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index be35265b7..c66641078 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -4,31 +4,30 @@ CPU_ISET_NONE = $0001 CPU_ISET_6502 = $0002 CPU_ISET_6502X = $0004 CPU_ISET_6502DTV = $0008 - CPU_ISET_65SC02 = $0010 CPU_ISET_65C02 = $0020 CPU_ISET_65816 = $0040 CPU_ISET_SWEET16 = $0080 - CPU_ISET_HUC6280 = $0100 CPU_ISET_M740 = $0200 CPU_ISET_4510 = $0400 CPU_ISET_45GS02 = $0800 ; CPU capabilities +; make sure to only combine the instruction sets that are 100% compatible 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_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 +CPU_6502X = CPU_ISET_6502X | CPU_ISET_6502 +CPU_6502DTV = CPU_ISET_6502DTV | CPU_ISET_6502 +CPU_65SC02 = CPU_ISET_65SC02 | CPU_ISET_6502 +CPU_65C02 = CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 +CPU_65816 = CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 CPU_SWEET16 = CPU_ISET_SWEET16 ; FIXME: CPU_ISET_65SC02 does not apply to the following, because the zp-indirect ; addressing was replaced with zp-indirect,z-indexed in 652SCE02 ; NOTE: HUC6280 removes "wai" ($cb) and "stp" ($db) from the 65C02 instruction set -CPU_HUC6280 = CPU_ISET_6502|CPU_ISET_65C02|CPU_ISET_HUC6280 +CPU_HUC6280 = CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02 ; NOTE: 4510 replaces "wai" ($cb) and "stp" ($db) of the 65C02 instruction set -CPU_4510 = CPU_ISET_6502|CPU_ISET_65C02|CPU_ISET_4510 -CPU_45GS02 = CPU_ISET_6502|CPU_ISET_65C02|CPU_ISET_4510|CPU_ISET_45GS02 -CPU_M740 = CPU_ISET_6502|CPU_ISET_M740 +CPU_4510 = CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 +CPU_45GS02 = CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_4510 +CPU_M740 = CPU_ISET_M740 | CPU_ISET_6502 diff --git a/libsrc/c65/kernal.s b/libsrc/c65/kernal.s index ea07f9ce6..fac8be514 100644 --- a/libsrc/c65/kernal.s +++ b/libsrc/c65/kernal.s @@ -42,7 +42,6 @@ .export STOP .export GETIN .export CLALL - .export UDTIM .export SCREEN .export IOBASE .export PLOT diff --git a/libsrc/mega65/kernal.s b/libsrc/mega65/kernal.s index 45f4c4d02..198e8fbb4 100644 --- a/libsrc/mega65/kernal.s +++ b/libsrc/mega65/kernal.s @@ -42,7 +42,6 @@ .export STOP .export GETIN .export CLALL - .export UDTIM .export SCREEN .export IOBASE .export PLOT From 4d1fbe3f908ae12f7c6718eb995ffef7ea3f3f36 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Tue, 24 Jun 2025 21:59:35 +0200 Subject: [PATCH 598/707] fix refs (remove 652SC02) --- test/asm/cpudetect/4510-cpudetect.ref | Bin 60 -> 44 bytes test/asm/cpudetect/45GS02-cpudetect.ref | Bin 80 -> 64 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/test/asm/cpudetect/4510-cpudetect.ref b/test/asm/cpudetect/4510-cpudetect.ref index 515557c854d36f3bc8310b6c2a9cc0b2b0a98ade..484469a79bf38aa6e631fc1f0bc96cdb0ccf61bc 100644 GIT binary patch delta 7 OcmcD~nIJt;TMz&U2?5~% delta 10 RcmdO~nIO#+>^zZI9smu#0%-sM diff --git a/test/asm/cpudetect/45GS02-cpudetect.ref b/test/asm/cpudetect/45GS02-cpudetect.ref index e9aa843cda2fb487e49b4380205f4b31d1ffb805..b6e8e797fe3a85e410b0b3ceee7db2a06acebc2c 100644 GIT binary patch delta 7 OcmWG=m>@q<Ul9NaH3A_3 delta 10 RcmZ<=m>|y->^xCW9{>+-0;vE1 From fa6d72cae5de6e275813b0ba6d227b2280148bb5 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 00:14:19 +0200 Subject: [PATCH 599/707] move zp range to a somewhat safer place --- cfg/c65.cfg | 2 +- cfg/mega65.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cfg/c65.cfg b/cfg/c65.cfg index 914f84f3c..2d78d26d2 100644 --- a/cfg/c65.cfg +++ b/cfg/c65.cfg @@ -8,7 +8,7 @@ SYMBOLS { __HIMEM__: type = weak, value = $8000; } MEMORY { - ZP: file = "", define = yes, start = $0002, size = $001A; + ZP: file = "", define = yes, start = $0018, size = $001A; LOADADDR: file = %O, start = %S - 2, size = $0002; HEADER: file = %O, define = yes, start = %S, size = $0010; MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__; diff --git a/cfg/mega65.cfg b/cfg/mega65.cfg index 914f84f3c..2d78d26d2 100644 --- a/cfg/mega65.cfg +++ b/cfg/mega65.cfg @@ -8,7 +8,7 @@ SYMBOLS { __HIMEM__: type = weak, value = $8000; } MEMORY { - ZP: file = "", define = yes, start = $0002, size = $001A; + ZP: file = "", define = yes, start = $0018, size = $001A; LOADADDR: file = %O, start = %S - 2, size = $0002; HEADER: file = %O, define = yes, start = %S, size = $0010; MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__; From 23336420b16dc32a68dd4a97515a6493fb2e0178 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 00:23:58 +0200 Subject: [PATCH 600/707] a bunch of simple conio fixes, makes a few more samples work --- asminc/c65.inc | 4 ++ asminc/mega65.inc | 4 ++ libsrc/c65/_scrsize.s | 12 ++++ libsrc/c65/bordercolor.s | 17 ++++++ libsrc/c65/clrscr.s | 15 +++++ libsrc/c65/color.s | 24 ++++++++ libsrc/c65/conio.s | 10 +++ libsrc/c65/cputc.s | 118 ++++++++++++++++++++++++++++++++++++ libsrc/c65/devnum.s | 7 +++ libsrc/c65/kbhit.s | 24 ++++++++ libsrc/c65/status.s | 5 ++ libsrc/mega65/_scrsize.s | 12 ++++ libsrc/mega65/bordercolor.s | 17 ++++++ libsrc/mega65/clrscr.s | 15 +++++ libsrc/mega65/color.s | 24 ++++++++ libsrc/mega65/conio.s | 10 +++ libsrc/mega65/cputc.s | 118 ++++++++++++++++++++++++++++++++++++ libsrc/mega65/devnum.s | 7 +++ libsrc/mega65/kbhit.s | 24 ++++++++ libsrc/mega65/status.s | 5 ++ samples/Makefile | 14 ++++- 21 files changed, 484 insertions(+), 2 deletions(-) create mode 100644 libsrc/c65/_scrsize.s create mode 100644 libsrc/c65/bordercolor.s create mode 100644 libsrc/c65/clrscr.s create mode 100644 libsrc/c65/color.s create mode 100644 libsrc/c65/conio.s create mode 100644 libsrc/c65/cputc.s create mode 100644 libsrc/c65/devnum.s create mode 100644 libsrc/c65/kbhit.s create mode 100644 libsrc/c65/status.s create mode 100644 libsrc/mega65/_scrsize.s create mode 100644 libsrc/mega65/bordercolor.s create mode 100644 libsrc/mega65/clrscr.s create mode 100644 libsrc/mega65/color.s create mode 100644 libsrc/mega65/conio.s create mode 100644 libsrc/mega65/cputc.s create mode 100644 libsrc/mega65/devnum.s create mode 100644 libsrc/mega65/kbhit.s create mode 100644 libsrc/mega65/status.s diff --git a/asminc/c65.inc b/asminc/c65.inc index 4c10431ab..79a4e7b03 100644 --- a/asminc/c65.inc +++ b/asminc/c65.inc @@ -233,3 +233,7 @@ CASSMOT = $20 ; Cassette motor on TP_FAST = $80 ; Switch Rossmoeller TurboProcess to fast mode RAMONLY = $F8 ; (~(LORAM | HIRAM | IOEN)) & $FF + +; temporary, to get conio working +XSIZE = 80 +YSIZE = 50 diff --git a/asminc/mega65.inc b/asminc/mega65.inc index 4c10431ab..79a4e7b03 100644 --- a/asminc/mega65.inc +++ b/asminc/mega65.inc @@ -233,3 +233,7 @@ CASSMOT = $20 ; Cassette motor on TP_FAST = $80 ; Switch Rossmoeller TurboProcess to fast mode RAMONLY = $F8 ; (~(LORAM | HIRAM | IOEN)) & $FF + +; temporary, to get conio working +XSIZE = 80 +YSIZE = 50 diff --git a/libsrc/c65/_scrsize.s b/libsrc/c65/_scrsize.s new file mode 100644 index 000000000..57ad4f30f --- /dev/null +++ b/libsrc/c65/_scrsize.s @@ -0,0 +1,12 @@ +; +; Ullrich von Bassewitz, 26.10.2000 +; +; Screen size variables +; + + .export screensize + .import SCREEN + +screensize = SCREEN + + diff --git a/libsrc/c65/bordercolor.s b/libsrc/c65/bordercolor.s new file mode 100644 index 000000000..6b3c7f86c --- /dev/null +++ b/libsrc/c65/bordercolor.s @@ -0,0 +1,17 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; +; unsigned char __fastcall__ bordercolor (unsigned char color); +; + + + .export _bordercolor + + .include "c65.inc" + +_bordercolor: + ldx VIC_BORDERCOLOR ; get old value + sta VIC_BORDERCOLOR ; set new value + txa + rts + diff --git a/libsrc/c65/clrscr.s b/libsrc/c65/clrscr.s new file mode 100644 index 000000000..84fef5eac --- /dev/null +++ b/libsrc/c65/clrscr.s @@ -0,0 +1,15 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; +; void clrscr (void); +; + + .export _clrscr + + .include "cbm_kernal.inc" + +;_clrscr = CLRSCR + +_clrscr: + lda #$93 + jmp CHROUT diff --git a/libsrc/c65/color.s b/libsrc/c65/color.s new file mode 100644 index 000000000..b80ba2367 --- /dev/null +++ b/libsrc/c65/color.s @@ -0,0 +1,24 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; +; unsigned char __fastcall__ textcolor (unsigned char color); +; unsigned char __fastcall__ bgcolor (unsigned char color); +; + + + .export _textcolor, _bgcolor + + .include "c65.inc" + +_textcolor: + ldx CHARCOLOR ; get old value + sta CHARCOLOR ; set new value + txa + rts + + +_bgcolor: + ldx VIC_BG_COLOR0 ; get old value + sta VIC_BG_COLOR0 ; set new value + txa + rts diff --git a/libsrc/c65/conio.s b/libsrc/c65/conio.s new file mode 100644 index 000000000..6c90a6d2e --- /dev/null +++ b/libsrc/c65/conio.s @@ -0,0 +1,10 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; +; Low level stuff for screen output/console input +; + + .exportzp CURS_X, CURS_Y + + .include "c65.inc" + diff --git a/libsrc/c65/cputc.s b/libsrc/c65/cputc.s new file mode 100644 index 000000000..a34262437 --- /dev/null +++ b/libsrc/c65/cputc.s @@ -0,0 +1,118 @@ +; +; Ullrich von Bassewitz, 1998-08-06, 2009-09-26 +; +; void __fastcall__ cputcxy (unsigned char x, unsigned char y, char c); +; void __fastcall__ cputc (char c); +; + + .export _cputcxy, _cputc, cputdirect, putchar + .export newline, plot + .import gotoxy + .import PLOT + + .include "c65.inc" + + +_cputcxy: + pha ; Save C + jsr gotoxy ; Set cursor, drop x and y + pla ; Restore C + +; Plot a character - also used as internal function + +_cputc: cmp #$0A ; CR? + bne L1 + lda #0 + sta CURS_X + beq plot ; Recalculate pointers + +L1: cmp #$0D ; LF? + beq newline ; Recalculate pointers + +; Printable char of some sort + + cmp #' ' + bcc cputdirect ; Other control char + tay + bmi L10 + cmp #$60 + bcc L2 + and #$DF + bne cputdirect ; Branch always +L2: and #$3F + +cputdirect: + jsr putchar ; Write the character to the screen + +; Advance cursor position + +advance: + iny + cpy #XSIZE + bne L3 + jsr newline ; new line + ldy #0 ; + cr +L3: sty CURS_X + rts + +newline: + clc + lda #XSIZE + adc SCREEN_PTR + sta SCREEN_PTR + bcc L4 + inc SCREEN_PTR+1 + clc +L4: lda #XSIZE + adc CRAM_PTR + sta CRAM_PTR + bcc L5 + inc CRAM_PTR+1 +L5: inc CURS_Y + rts + +; Handle character if high bit set + +L10: and #$7F + cmp #$7F ; PI? + bne L11 + lda #$5E ; Load screen code for PI +L11: ora #$40 + bne cputdirect + + + +; Set cursor position, calculate RAM pointers. + +plot: ldy CURS_X + ldx CURS_Y + clc + jmp PLOT ; Set the new cursor + + + +; Write one character to the screen without doing anything else, return X +; position in Y + +putchar: + ora RVS ; Set revers bit + ldy CURS_X + + pha + lda SCREEN_PTR + 1 + clc + adc #>$0800 + sta SCREEN_PTR + 1 + pla + + sta (SCREEN_PTR),y ; Set char + + lda SCREEN_PTR + 1 + sec + sbc #>$0800 + sta SCREEN_PTR + 1 + + lda CHARCOLOR +; lda #$88 +; sta (CRAM_PTR),y ; Set color + rts diff --git a/libsrc/c65/devnum.s b/libsrc/c65/devnum.s new file mode 100644 index 000000000..412b63fd7 --- /dev/null +++ b/libsrc/c65/devnum.s @@ -0,0 +1,7 @@ +; +; Oliver Schmidt, 2010-02-14 +; + + .include "c65.inc" + + .exportzp devnum := DEVNUM diff --git a/libsrc/c65/kbhit.s b/libsrc/c65/kbhit.s new file mode 100644 index 000000000..63b34629b --- /dev/null +++ b/libsrc/c65/kbhit.s @@ -0,0 +1,24 @@ + + + ; FIXME: is $d610 mega65 specific? + ; FIXME: this should rather use the kernal (with keyboard buffer etc) + + .export _cgetc +_cgetc: + +: lda $d610 + beq :- + ldx #0 + stx $d610 + rts + + .export _kbhit +_kbhit: + lda $d610 + beq :+ + + lda #1 +: + ldx #0 + rts + diff --git a/libsrc/c65/status.s b/libsrc/c65/status.s new file mode 100644 index 000000000..c6f279230 --- /dev/null +++ b/libsrc/c65/status.s @@ -0,0 +1,5 @@ +; +; Oliver Schmidt, 2012-09-30 +; + + .exportzp ST := $90 ; IEC status byte diff --git a/libsrc/mega65/_scrsize.s b/libsrc/mega65/_scrsize.s new file mode 100644 index 000000000..57ad4f30f --- /dev/null +++ b/libsrc/mega65/_scrsize.s @@ -0,0 +1,12 @@ +; +; Ullrich von Bassewitz, 26.10.2000 +; +; Screen size variables +; + + .export screensize + .import SCREEN + +screensize = SCREEN + + diff --git a/libsrc/mega65/bordercolor.s b/libsrc/mega65/bordercolor.s new file mode 100644 index 000000000..2ebf83766 --- /dev/null +++ b/libsrc/mega65/bordercolor.s @@ -0,0 +1,17 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; +; unsigned char __fastcall__ bordercolor (unsigned char color); +; + + + .export _bordercolor + + .include "mega65.inc" + +_bordercolor: + ldx VIC_BORDERCOLOR ; get old value + sta VIC_BORDERCOLOR ; set new value + txa + rts + diff --git a/libsrc/mega65/clrscr.s b/libsrc/mega65/clrscr.s new file mode 100644 index 000000000..84fef5eac --- /dev/null +++ b/libsrc/mega65/clrscr.s @@ -0,0 +1,15 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; +; void clrscr (void); +; + + .export _clrscr + + .include "cbm_kernal.inc" + +;_clrscr = CLRSCR + +_clrscr: + lda #$93 + jmp CHROUT diff --git a/libsrc/mega65/color.s b/libsrc/mega65/color.s new file mode 100644 index 000000000..094bf9ed8 --- /dev/null +++ b/libsrc/mega65/color.s @@ -0,0 +1,24 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; +; unsigned char __fastcall__ textcolor (unsigned char color); +; unsigned char __fastcall__ bgcolor (unsigned char color); +; + + + .export _textcolor, _bgcolor + + .include "mega65.inc" + +_textcolor: + ldx CHARCOLOR ; get old value + sta CHARCOLOR ; set new value + txa + rts + + +_bgcolor: + ldx VIC_BG_COLOR0 ; get old value + sta VIC_BG_COLOR0 ; set new value + txa + rts diff --git a/libsrc/mega65/conio.s b/libsrc/mega65/conio.s new file mode 100644 index 000000000..14052c5a1 --- /dev/null +++ b/libsrc/mega65/conio.s @@ -0,0 +1,10 @@ +; +; Ullrich von Bassewitz, 06.08.1998 +; +; Low level stuff for screen output/console input +; + + .exportzp CURS_X, CURS_Y + + .include "mega65.inc" + diff --git a/libsrc/mega65/cputc.s b/libsrc/mega65/cputc.s new file mode 100644 index 000000000..ad93ba7e5 --- /dev/null +++ b/libsrc/mega65/cputc.s @@ -0,0 +1,118 @@ +; +; Ullrich von Bassewitz, 1998-08-06, 2009-09-26 +; +; void __fastcall__ cputcxy (unsigned char x, unsigned char y, char c); +; void __fastcall__ cputc (char c); +; + + .export _cputcxy, _cputc, cputdirect, putchar + .export newline, plot + .import gotoxy + .import PLOT + + .include "mega65.inc" + + +_cputcxy: + pha ; Save C + jsr gotoxy ; Set cursor, drop x and y + pla ; Restore C + +; Plot a character - also used as internal function + +_cputc: cmp #$0A ; CR? + bne L1 + lda #0 + sta CURS_X + beq plot ; Recalculate pointers + +L1: cmp #$0D ; LF? + beq newline ; Recalculate pointers + +; Printable char of some sort + + cmp #' ' + bcc cputdirect ; Other control char + tay + bmi L10 + cmp #$60 + bcc L2 + and #$DF + bne cputdirect ; Branch always +L2: and #$3F + +cputdirect: + jsr putchar ; Write the character to the screen + +; Advance cursor position + +advance: + iny + cpy #XSIZE + bne L3 + jsr newline ; new line + ldy #0 ; + cr +L3: sty CURS_X + rts + +newline: + clc + lda #XSIZE + adc SCREEN_PTR + sta SCREEN_PTR + bcc L4 + inc SCREEN_PTR+1 + clc +L4: lda #XSIZE + adc CRAM_PTR + sta CRAM_PTR + bcc L5 + inc CRAM_PTR+1 +L5: inc CURS_Y + rts + +; Handle character if high bit set + +L10: and #$7F + cmp #$7F ; PI? + bne L11 + lda #$5E ; Load screen code for PI +L11: ora #$40 + bne cputdirect + + + +; Set cursor position, calculate RAM pointers. + +plot: ldy CURS_X + ldx CURS_Y + clc + jmp PLOT ; Set the new cursor + + + +; Write one character to the screen without doing anything else, return X +; position in Y + +putchar: + ora RVS ; Set revers bit + ldy CURS_X + + pha + lda SCREEN_PTR + 1 + clc + adc #>$0800 + sta SCREEN_PTR + 1 + pla + + sta (SCREEN_PTR),y ; Set char + + lda SCREEN_PTR + 1 + sec + sbc #>$0800 + sta SCREEN_PTR + 1 + + lda CHARCOLOR +; lda #$88 +; sta (CRAM_PTR),y ; Set color + rts diff --git a/libsrc/mega65/devnum.s b/libsrc/mega65/devnum.s new file mode 100644 index 000000000..898989766 --- /dev/null +++ b/libsrc/mega65/devnum.s @@ -0,0 +1,7 @@ +; +; Oliver Schmidt, 2010-02-14 +; + + .include "mega65.inc" + + .exportzp devnum := DEVNUM diff --git a/libsrc/mega65/kbhit.s b/libsrc/mega65/kbhit.s new file mode 100644 index 000000000..63b34629b --- /dev/null +++ b/libsrc/mega65/kbhit.s @@ -0,0 +1,24 @@ + + + ; FIXME: is $d610 mega65 specific? + ; FIXME: this should rather use the kernal (with keyboard buffer etc) + + .export _cgetc +_cgetc: + +: lda $d610 + beq :- + ldx #0 + stx $d610 + rts + + .export _kbhit +_kbhit: + lda $d610 + beq :+ + + lda #1 +: + ldx #0 + rts + diff --git a/libsrc/mega65/status.s b/libsrc/mega65/status.s new file mode 100644 index 000000000..c6f279230 --- /dev/null +++ b/libsrc/mega65/status.s @@ -0,0 +1,5 @@ +; +; Oliver Schmidt, 2012-09-30 +; + + .exportzp ST := $90 ; IEC status byte diff --git a/samples/Makefile b/samples/Makefile index 8974ce1b6..7d506e135 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -241,7 +241,12 @@ EXELIST_c64 = \ tgidemo EXELIST_c65 = \ - checkversion + ascii \ + checkversion \ + enumdevdir \ + hello \ + sieve \ + tinyshell EXELIST_c128 = \ ascii \ @@ -316,7 +321,12 @@ EXELIST_lynx = \ notavailable EXELIST_mega65 = \ - checkversion + ascii \ + checkversion \ + enumdevdir \ + hello \ + sieve \ + tinyshell EXELIST_nes = \ hello From 79b2d25840656d5b2beb36f18e56b79eaf2fff0f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 02:32:46 +0200 Subject: [PATCH 601/707] name the SIDs 1 and 2 just like the CIAs --- asminc/c65.inc | 120 ++++++++++++++++++++++++------------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/asminc/c65.inc b/asminc/c65.inc index 79a4e7b03..ff3572f1f 100644 --- a/asminc/c65.inc +++ b/asminc/c65.inc @@ -112,73 +112,73 @@ FDC := $D080 ; --------------------------------------------------------------------------- ; I/O: SID -SID0 := $D400 -SID0_S1Lo := $D400 -SID0_S1Hi := $D401 -SID0_PB1Lo := $D402 -SID0_PB1Hi := $D403 -SID0_Ctl1 := $D404 -SID0_AD1 := $D405 -SID0_SUR1 := $D406 +SID1 := $D400 +SID1_S1Lo := $D400 +SID1_S1Hi := $D401 +SID1_PB1Lo := $D402 +SID1_PB1Hi := $D403 +SID1_Ctl1 := $D404 +SID1_AD1 := $D405 +SID1_SUR1 := $D406 -SID0_S2Lo := $D407 -SID0_S2Hi := $D408 -SID0_PB2Lo := $D409 -SID0_PB2Hi := $D40A -SID0_Ctl2 := $D40B -SID0_AD2 := $D40C -SID0_SUR2 := $D40D +SID1_S2Lo := $D407 +SID1_S2Hi := $D408 +SID1_PB2Lo := $D409 +SID1_PB2Hi := $D40A +SID1_Ctl2 := $D40B +SID1_AD2 := $D40C +SID1_SUR2 := $D40D -SID0_S3Lo := $D40E -SID0_S3Hi := $D40F -SID0_PB3Lo := $D410 -SID0_PB3Hi := $D411 -SID0_Ctl3 := $D412 -SID0_AD3 := $D413 -SID0_SUR3 := $D414 +SID1_S3Lo := $D40E +SID1_S3Hi := $D40F +SID1_PB3Lo := $D410 +SID1_PB3Hi := $D411 +SID1_Ctl3 := $D412 +SID1_AD3 := $D413 +SID1_SUR3 := $D414 -SID0_FltLo := $D415 -SID0_FltHi := $D416 -SID0_FltCtl := $D417 -SID0_Amp := $D418 -SID0_ADConv1 := $D419 -SID0_ADConv2 := $D41A -SID0_Noise := $D41B -SID0_Read3 := $D41C +SID1_FltLo := $D415 +SID1_FltHi := $D416 +SID1_FltCtl := $D417 +SID1_Amp := $D418 +SID1_ADConv1 := $D419 +SID1_ADConv2 := $D41A +SID1_Noise := $D41B +SID1_Read3 := $D41C -SID1 := $D420 -SID1_S1Lo := $D420 -SID1_S1Hi := $D421 -SID1_PB1Lo := $D422 -SID1_PB1Hi := $D423 -SID1_Ctl1 := $D424 -SID1_AD1 := $D425 -SID1_SUR1 := $D426 +SID2 := $D420 +SID2_S1Lo := $D420 +SID2_S1Hi := $D421 +SID2_PB1Lo := $D422 +SID2_PB1Hi := $D423 +SID2_Ctl1 := $D424 +SID2_AD1 := $D425 +SID2_SUR1 := $D426 -SID1_S2Lo := $D427 -SID1_S2Hi := $D428 -SID1_PB2Lo := $D429 -SID1_PB2Hi := $D42A -SID1_Ctl2 := $D42B -SID1_AD2 := $D42C -SID1_SUR2 := $D42D +SID2_S2Lo := $D427 +SID2_S2Hi := $D428 +SID2_PB2Lo := $D429 +SID2_PB2Hi := $D42A +SID2_Ctl2 := $D42B +SID2_AD2 := $D42C +SID2_SUR2 := $D42D -SID1_S3Lo := $D42E -SID1_S3Hi := $D42F -SID1_PB3Lo := $D430 -SID1_PB3Hi := $D431 -SID1_Ctl3 := $D432 -SID1_AD3 := $D433 -SID1_SUR3 := $D434 +SID2_S3Lo := $D42E +SID2_S3Hi := $D42F +SID2_PB3Lo := $D430 +SID2_PB3Hi := $D431 +SID2_Ctl3 := $D432 +SID2_AD3 := $D433 +SID2_SUR3 := $D434 -SID1_FltLo := $D435 -SID1_FltHi := $D436 -SID1_FltCtl := $D437 -SID1_Amp := $D438 -SID1_ADConv1 := $D439 -SID1_ADConv2 := $D43A -SID1_Noise := $D43B -SID1_Read3 := $D43C +SID2_FltLo := $D435 +SID2_FltHi := $D436 +SID2_FltCtl := $D437 +SID2_Amp := $D438 +SID2_ADConv1 := $D439 +SID2_ADConv2 := $D43A +SID2_Noise := $D43B +SID2_Read3 := $D43C ; --------------------------------------------------------------------------- ; I/O: Complex Interface Adapters From db494325615910fb9f5136e02bed8ff5091cdec8 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 02:38:40 +0200 Subject: [PATCH 602/707] some more simple fixes, make targettest(s) work --- libsrc/c65/crt0.s | 1 - libsrc/c65/get_tv.s | 25 +++++++ libsrc/c65/gettime.s | 83 +++++++++++++++++++++++ libsrc/c65/mainargs.s | 137 ++++++++++++++++++++++++++++++++++++++ libsrc/c65/randomize.s | 18 +++++ libsrc/c65/revers.s | 27 ++++++++ libsrc/c65/settime.s | 84 +++++++++++++++++++++++ libsrc/c65/sysuname.s | 37 ++++++++++ libsrc/c65/tmcommon.s | 64 ++++++++++++++++++ libsrc/mega65/crt0.s | 1 - libsrc/mega65/get_tv.s | 25 +++++++ libsrc/mega65/gettime.s | 83 +++++++++++++++++++++++ libsrc/mega65/mainargs.s | 137 ++++++++++++++++++++++++++++++++++++++ libsrc/mega65/randomize.s | 18 +++++ libsrc/mega65/revers.s | 27 ++++++++ libsrc/mega65/sysuname.s | 37 ++++++++++ libsrc/mega65/tmcommon.s | 64 ++++++++++++++++++ targettest/Makefile | 60 +++++++++++++++++ targettest/cpeek-test.c | 4 ++ 19 files changed, 930 insertions(+), 2 deletions(-) create mode 100644 libsrc/c65/get_tv.s create mode 100644 libsrc/c65/gettime.s create mode 100644 libsrc/c65/mainargs.s create mode 100644 libsrc/c65/randomize.s create mode 100644 libsrc/c65/revers.s create mode 100644 libsrc/c65/settime.s create mode 100644 libsrc/c65/sysuname.s create mode 100644 libsrc/c65/tmcommon.s create mode 100644 libsrc/mega65/get_tv.s create mode 100644 libsrc/mega65/gettime.s create mode 100644 libsrc/mega65/mainargs.s create mode 100644 libsrc/mega65/randomize.s create mode 100644 libsrc/mega65/revers.s create mode 100644 libsrc/mega65/sysuname.s create mode 100644 libsrc/mega65/tmcommon.s diff --git a/libsrc/c65/crt0.s b/libsrc/c65/crt0.s index 855b4ccf6..380d04e2e 100644 --- a/libsrc/c65/crt0.s +++ b/libsrc/c65/crt0.s @@ -105,7 +105,6 @@ L1: lda c_sp,x ; Switch to the second charset. -; FIXME lda #14 jsr BSOUT diff --git a/libsrc/c65/get_tv.s b/libsrc/c65/get_tv.s new file mode 100644 index 000000000..2093e45fd --- /dev/null +++ b/libsrc/c65/get_tv.s @@ -0,0 +1,25 @@ +; +; Ullrich von Bassewitz, 2002-12-03 +; +; unsigned char get_tv (void); +; /* Return the video mode the machine is using */ +; + + .include "get_tv.inc" + .include "c65.inc" + + +;-------------------------------------------------------------------------- +; _get_tv + +.proc _get_tv + + ldx #TV::PAL ; Assume PAL + lda PALFLAG + bne pal + dex ; NTSC +pal: txa + ldx #0 + rts + +.endproc diff --git a/libsrc/c65/gettime.s b/libsrc/c65/gettime.s new file mode 100644 index 000000000..c4b200a5d --- /dev/null +++ b/libsrc/c65/gettime.s @@ -0,0 +1,83 @@ +; +; Stefan Haubenthal, 27.7.2009 +; Oliver Schmidt, 14.8.2018 +; +; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp); +; + + .include "time.inc" + .include "c65.inc" + + .importzp sreg, tmp1, tmp2 + .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_gettime + + jsr pushax + jsr pushax + + lda CIA1_TODHR + sed + tax ; Save PM flag + and #%01111111 + cmp #$12 ; 12 AM/PM + bcc @L1 + sbc #$12 +@L1: inx ; Get PM flag + bpl @L2 + clc + adc #$12 +@L2: cld + jsr BCD2dec + sta TM + tm::tm_hour + lda CIA1_TODMIN + jsr BCD2dec + sta TM + tm::tm_min + lda CIA1_TODSEC + jsr BCD2dec + sta TM + tm::tm_sec + lda #<TM + ldx #>TM + jsr _mktime + + ldy #timespec::tv_sec + jsr steaxspidx ; Pops address pushed by 2. pushax + + jsr load_tenth + jsr pusheax + lda CIA1_TOD10 + ldx #>$0000 + jsr tosmul0ax + + ldy #timespec::tv_nsec + jsr steaxspidx ; Pops address pushed by 1. pushax + + jsr incsp1 + jmp return0 + +.endproc + +;---------------------------------------------------------------------------- +; dec = (((BCD>>4)*10) + (BCD&0xf)) + +.proc BCD2dec + + tax + and #%00001111 + sta tmp1 + txa + and #%11110000 ; *16 + lsr ; *8 + sta tmp2 + lsr + lsr ; *2 + adc tmp2 ; = *10 + adc tmp1 + rts + +.endproc diff --git a/libsrc/c65/mainargs.s b/libsrc/c65/mainargs.s new file mode 100644 index 000000000..e2249819f --- /dev/null +++ b/libsrc/c65/mainargs.s @@ -0,0 +1,137 @@ +; mainargs.s +; +; Ullrich von Bassewitz, 2003-03-07 +; Based on code from Stefan A. Haubenthal, <polluks@web.de> +; 2003-05-18, Greg King +; 2004-04-28, 2005-02-26, Ullrich von Bassewitz +; +; Scan a group of arguments that are in BASIC's input-buffer. +; Build an array that points to the beginning of each argument. +; Send, to main(), that array and the count of the arguments. +; +; Command-lines look like these lines: +; +; run +; run : rem +; run:rem arg1 " arg 2 is quoted " arg3 "" arg5 +; +; "run" and "rem" are entokenned; the args. are not. Leading and trailing +; spaces outside of quotes are ignored. +; +; TO-DO: +; - The "file-name" might be a path-name; don't copy the directory-components. +; - Add a control-character quoting mechanism. + + .constructor initmainargs, 24 + .import __argc, __argv + + .include "c65.inc" + + +MAXARGS = 10 ; Maximum number of arguments allowed +REM = $8f ; BASIC token-code +NAME_LEN = 16 ; Maximum length of command-name + +; Get possible command-line arguments. Goes into the special ONCE segment, +; which may be reused after the startup code is run + +.segment "ONCE" + +initmainargs: + +; Assume that the program was loaded, a moment ago, by the traditional LOAD +; statement. Save the "most-recent filename" as argument #0. + + lda #0 ; The terminating NUL character + ldy FNAM_LEN + cpy #NAME_LEN + 1 + bcc L1 + ldy #NAME_LEN ; Limit the length + bne L1 ; Branch always +L0: lda (FNAM),y +L1: sta name,y + dey + bpl L0 + inc __argc ; argc always is equal to, at least, 1 + +; Find the "rem" token. + + ldx #0 +L2: lda BASIC_BUF,x + beq done ; No "rem," no args. + inx + cmp #REM + bne L2 + ldy #1 * 2 + +; Find the next argument + +next: lda BASIC_BUF,x + beq done ; End of line reached + inx + cmp #' ' ; Skip leading spaces + beq next + +; Found start of next argument. We've incremented the pointer in X already, so +; it points to the second character of the argument. This is useful since we +; will check now for a quoted argument, in which case we will have to skip this +; first character. + +found: cmp #'"' ; Is the argument quoted? + beq setterm ; Jump if so + dex ; Reset pointer to first argument character + lda #' ' ; A space ends the argument +setterm:sta term ; Set end of argument marker + +; Now store a pointer to the argument into the next slot. Since the BASIC +; input buffer is located at the start of a RAM page, no calculations are +; necessary. + + txa ; Get low byte + sta argv,y ; argv[y]= &arg + iny + lda #>BASIC_BUF + sta argv,y + iny + inc __argc ; Found another arg + +; Search for the end of the argument + +argloop:lda BASIC_BUF,x + beq done + inx + cmp term + bne argloop + +; We've found the end of the argument. X points one character behind it, and +; A contains the terminating character. To make the argument a valid C string, +; replace the terminating character by a zero. + + lda #0 + sta BASIC_BUF-1,x + +; Check if the maximum number of command line arguments is reached. If not, +; parse the next one. + + lda __argc ; Get low byte of argument count + cmp #MAXARGS ; Maximum number of arguments reached? + bcc next ; Parse next one if not + +; (The last vector in argv[] already is NULL.) + +done: lda #<argv + ldx #>argv + sta __argv + stx __argv + 1 + rts + +.segment "INIT" + +term: .res 1 +name: .res NAME_LEN + 1 + +.data + +; char* argv[MAXARGS+1]={name}; +argv: .addr name + .res MAXARGS * 2 diff --git a/libsrc/c65/randomize.s b/libsrc/c65/randomize.s new file mode 100644 index 000000000..8ee5d1381 --- /dev/null +++ b/libsrc/c65/randomize.s @@ -0,0 +1,18 @@ +; +; 2002-11-05, Ullrich von Bassewitz +; 2015-09-11, Greg King +; +; void __randomize (void); +; /* Initialize the random number generator */ +; + + .export ___randomize + .import _srand + + .include "c65.inc" + +___randomize: + ldx VIC_HLINE ; Use VIC rasterline as high byte + lda TIME+2 ; Use 60HZ clock as low byte + jmp _srand ; Initialize generator + diff --git a/libsrc/c65/revers.s b/libsrc/c65/revers.s new file mode 100644 index 000000000..f6bd88688 --- /dev/null +++ b/libsrc/c65/revers.s @@ -0,0 +1,27 @@ +; +; Ullrich von Bassewitz, 07.08.1998 +; +; unsigned char revers (unsigned char onoff); +; + + .export _revers + + .include "c65.inc" + +.proc _revers + + ldx #$00 ; Assume revers off + tay ; Test onoff + beq L1 ; Jump if off + ldx #$80 ; Load on value + ldy #$00 ; Assume old value is zero +L1: lda RVS ; Load old value + stx RVS ; Set new value + beq L2 ; Jump if old value zero + iny ; Make old value = 1 +L2: ldx #$00 ; Load high byte of result + tya ; Load low byte, set CC + rts + +.endproc + diff --git a/libsrc/c65/settime.s b/libsrc/c65/settime.s new file mode 100644 index 000000000..8b376e089 --- /dev/null +++ b/libsrc/c65/settime.s @@ -0,0 +1,84 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .include "time.inc" + .include "c65.inc" + + .importzp sreg, ptr1 + .import pushax, pusheax, ldax0sp, ldeaxidx + .import tosdiveax, incsp3, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_settime + + jsr pushax + + .assert timespec::tv_sec = 0, error + jsr _localtime + sta ptr1 + stx ptr1+1 + ldy #.sizeof(tm)-1 +@L1: lda (ptr1),y + sta TM,y + dey + bpl @L1 + + lda TM + tm::tm_hour + jsr dec2BCD + tax ; Force flags + bne @L2 + lda #$92 ; 12 AM + bne @L3 +@L2: cmp #$13 ; 1 PM + bcc @L3 + sed + sbc #$12 + cld + ora #%10000000 +@L3: sta CIA1_TODHR + lda TM + tm::tm_min + jsr dec2BCD + sta CIA1_TODMIN + lda TM + tm::tm_sec + jsr dec2BCD + sta CIA1_TODSEC + + jsr ldax0sp + ldy #3+timespec::tv_nsec + jsr ldeaxidx + jsr pusheax + jsr load_tenth + jsr tosdiveax + sta CIA1_TOD10 + + jsr incsp3 + jmp return0 + +.endproc + +;---------------------------------------------------------------------------- +; Just sum up the value in BCD mode. +; http://forum.6502.org/viewtopic.php?p=7629#p7629 + +.proc dec2BCD + + tax + dex + bmi @L9 + lda #0 + clc + sed +@L1: adc #1 + dex + bpl @L1 + cld +@L9: rts + +.endproc diff --git a/libsrc/c65/sysuname.s b/libsrc/c65/sysuname.s new file mode 100644 index 000000000..b0a24a236 --- /dev/null +++ b/libsrc/c65/sysuname.s @@ -0,0 +1,37 @@ +; +; Ullrich von Bassewitz, 2003-08-12 +; +; unsigned char __fastcall__ _sysuname (struct utsname* buf); +; + + .export __sysuname, utsdata + + .import utscopy + + __sysuname = utscopy + +;-------------------------------------------------------------------------- +; Data. We define a fixed utsname struct here and just copy it. + +.rodata + +utsdata: + ; sysname + .asciiz "cc65" + + ; nodename + .asciiz "" + + ; release + .byte .string (>.version) + .byte '.' + .byte .string (<.version) + .byte $00 + + ; version + .byte '0' ; unused + .byte $00 + + ; machine + .asciiz "Commodore 65" + diff --git a/libsrc/c65/tmcommon.s b/libsrc/c65/tmcommon.s new file mode 100644 index 000000000..52094b68e --- /dev/null +++ b/libsrc/c65/tmcommon.s @@ -0,0 +1,64 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; Common stuff for the clock routines +; + + .include "c65.inc" + .include "get_tv.inc" + + .export TM, load_tenth + + .constructor inittime + .importzp sreg + .import _get_tv + + +;---------------------------------------------------------------------------- +.code + +.proc load_tenth + + lda #<(100 * 1000 * 1000 / $10000) + ldx #>(100 * 1000 * 1000 / $10000) + sta sreg + stx sreg+1 + lda #<(100 * 1000 * 1000) + ldx #>(100 * 1000 * 1000) + rts + +.endproc + +;---------------------------------------------------------------------------- +; Constructor that writes to the 1/10 sec register of the TOD to kick it +; into action. If this is not done, the clock hangs. We will read the register +; and write it again, ignoring a possible change in between. +.segment "ONCE" + +.proc inittime + + lda CIA1_TOD10 + sta CIA1_TOD10 + jsr _get_tv + cmp #TV::PAL + bne @60Hz + lda CIA1_CRA + ora #$80 + sta CIA1_CRA +@60Hz: rts + +.endproc + +;---------------------------------------------------------------------------- +; TM struct with date set to 1970-01-01 +.data + +TM: .word 0 ; tm_sec + .word 0 ; tm_min + .word 0 ; tm_hour + .word 1 ; tm_mday + .word 0 ; tm_mon + .word 70 ; tm_year + .word 0 ; tm_wday + .word 0 ; tm_yday + .word 0 ; tm_isdst diff --git a/libsrc/mega65/crt0.s b/libsrc/mega65/crt0.s index 401095c55..c7be6b7ee 100644 --- a/libsrc/mega65/crt0.s +++ b/libsrc/mega65/crt0.s @@ -105,7 +105,6 @@ L1: lda c_sp,x ; Switch to the second charset. -; FIXME lda #14 jsr BSOUT diff --git a/libsrc/mega65/get_tv.s b/libsrc/mega65/get_tv.s new file mode 100644 index 000000000..eb2dafd1d --- /dev/null +++ b/libsrc/mega65/get_tv.s @@ -0,0 +1,25 @@ +; +; Ullrich von Bassewitz, 2002-12-03 +; +; unsigned char get_tv (void); +; /* Return the video mode the machine is using */ +; + + .include "get_tv.inc" + .include "mega65.inc" + + +;-------------------------------------------------------------------------- +; _get_tv + +.proc _get_tv + + ldx #TV::PAL ; Assume PAL + lda PALFLAG + bne pal + dex ; NTSC +pal: txa + ldx #0 + rts + +.endproc diff --git a/libsrc/mega65/gettime.s b/libsrc/mega65/gettime.s new file mode 100644 index 000000000..34c5054d5 --- /dev/null +++ b/libsrc/mega65/gettime.s @@ -0,0 +1,83 @@ +; +; Stefan Haubenthal, 27.7.2009 +; Oliver Schmidt, 14.8.2018 +; +; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp); +; + + .include "time.inc" + .include "mega65.inc" + + .importzp sreg, tmp1, tmp2 + .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_gettime + + jsr pushax + jsr pushax + + lda CIA1_TODHR + sed + tax ; Save PM flag + and #%01111111 + cmp #$12 ; 12 AM/PM + bcc @L1 + sbc #$12 +@L1: inx ; Get PM flag + bpl @L2 + clc + adc #$12 +@L2: cld + jsr BCD2dec + sta TM + tm::tm_hour + lda CIA1_TODMIN + jsr BCD2dec + sta TM + tm::tm_min + lda CIA1_TODSEC + jsr BCD2dec + sta TM + tm::tm_sec + lda #<TM + ldx #>TM + jsr _mktime + + ldy #timespec::tv_sec + jsr steaxspidx ; Pops address pushed by 2. pushax + + jsr load_tenth + jsr pusheax + lda CIA1_TOD10 + ldx #>$0000 + jsr tosmul0ax + + ldy #timespec::tv_nsec + jsr steaxspidx ; Pops address pushed by 1. pushax + + jsr incsp1 + jmp return0 + +.endproc + +;---------------------------------------------------------------------------- +; dec = (((BCD>>4)*10) + (BCD&0xf)) + +.proc BCD2dec + + tax + and #%00001111 + sta tmp1 + txa + and #%11110000 ; *16 + lsr ; *8 + sta tmp2 + lsr + lsr ; *2 + adc tmp2 ; = *10 + adc tmp1 + rts + +.endproc diff --git a/libsrc/mega65/mainargs.s b/libsrc/mega65/mainargs.s new file mode 100644 index 000000000..b4063b93c --- /dev/null +++ b/libsrc/mega65/mainargs.s @@ -0,0 +1,137 @@ +; mainargs.s +; +; Ullrich von Bassewitz, 2003-03-07 +; Based on code from Stefan A. Haubenthal, <polluks@web.de> +; 2003-05-18, Greg King +; 2004-04-28, 2005-02-26, Ullrich von Bassewitz +; +; Scan a group of arguments that are in BASIC's input-buffer. +; Build an array that points to the beginning of each argument. +; Send, to main(), that array and the count of the arguments. +; +; Command-lines look like these lines: +; +; run +; run : rem +; run:rem arg1 " arg 2 is quoted " arg3 "" arg5 +; +; "run" and "rem" are entokenned; the args. are not. Leading and trailing +; spaces outside of quotes are ignored. +; +; TO-DO: +; - The "file-name" might be a path-name; don't copy the directory-components. +; - Add a control-character quoting mechanism. + + .constructor initmainargs, 24 + .import __argc, __argv + + .include "mega65.inc" + + +MAXARGS = 10 ; Maximum number of arguments allowed +REM = $8f ; BASIC token-code +NAME_LEN = 16 ; Maximum length of command-name + +; Get possible command-line arguments. Goes into the special ONCE segment, +; which may be reused after the startup code is run + +.segment "ONCE" + +initmainargs: + +; Assume that the program was loaded, a moment ago, by the traditional LOAD +; statement. Save the "most-recent filename" as argument #0. + + lda #0 ; The terminating NUL character + ldy FNAM_LEN + cpy #NAME_LEN + 1 + bcc L1 + ldy #NAME_LEN ; Limit the length + bne L1 ; Branch always +L0: lda (FNAM),y +L1: sta name,y + dey + bpl L0 + inc __argc ; argc always is equal to, at least, 1 + +; Find the "rem" token. + + ldx #0 +L2: lda BASIC_BUF,x + beq done ; No "rem," no args. + inx + cmp #REM + bne L2 + ldy #1 * 2 + +; Find the next argument + +next: lda BASIC_BUF,x + beq done ; End of line reached + inx + cmp #' ' ; Skip leading spaces + beq next + +; Found start of next argument. We've incremented the pointer in X already, so +; it points to the second character of the argument. This is useful since we +; will check now for a quoted argument, in which case we will have to skip this +; first character. + +found: cmp #'"' ; Is the argument quoted? + beq setterm ; Jump if so + dex ; Reset pointer to first argument character + lda #' ' ; A space ends the argument +setterm:sta term ; Set end of argument marker + +; Now store a pointer to the argument into the next slot. Since the BASIC +; input buffer is located at the start of a RAM page, no calculations are +; necessary. + + txa ; Get low byte + sta argv,y ; argv[y]= &arg + iny + lda #>BASIC_BUF + sta argv,y + iny + inc __argc ; Found another arg + +; Search for the end of the argument + +argloop:lda BASIC_BUF,x + beq done + inx + cmp term + bne argloop + +; We've found the end of the argument. X points one character behind it, and +; A contains the terminating character. To make the argument a valid C string, +; replace the terminating character by a zero. + + lda #0 + sta BASIC_BUF-1,x + +; Check if the maximum number of command line arguments is reached. If not, +; parse the next one. + + lda __argc ; Get low byte of argument count + cmp #MAXARGS ; Maximum number of arguments reached? + bcc next ; Parse next one if not + +; (The last vector in argv[] already is NULL.) + +done: lda #<argv + ldx #>argv + sta __argv + stx __argv + 1 + rts + +.segment "INIT" + +term: .res 1 +name: .res NAME_LEN + 1 + +.data + +; char* argv[MAXARGS+1]={name}; +argv: .addr name + .res MAXARGS * 2 diff --git a/libsrc/mega65/randomize.s b/libsrc/mega65/randomize.s new file mode 100644 index 000000000..89feebe11 --- /dev/null +++ b/libsrc/mega65/randomize.s @@ -0,0 +1,18 @@ +; +; 2002-11-05, Ullrich von Bassewitz +; 2015-09-11, Greg King +; +; void __randomize (void); +; /* Initialize the random number generator */ +; + + .export ___randomize + .import _srand + + .include "mega65.inc" + +___randomize: + ldx VIC_HLINE ; Use VIC rasterline as high byte + lda TIME+2 ; Use 60HZ clock as low byte + jmp _srand ; Initialize generator + diff --git a/libsrc/mega65/revers.s b/libsrc/mega65/revers.s new file mode 100644 index 000000000..3dc508f79 --- /dev/null +++ b/libsrc/mega65/revers.s @@ -0,0 +1,27 @@ +; +; Ullrich von Bassewitz, 07.08.1998 +; +; unsigned char revers (unsigned char onoff); +; + + .export _revers + + .include "mega65.inc" + +.proc _revers + + ldx #$00 ; Assume revers off + tay ; Test onoff + beq L1 ; Jump if off + ldx #$80 ; Load on value + ldy #$00 ; Assume old value is zero +L1: lda RVS ; Load old value + stx RVS ; Set new value + beq L2 ; Jump if old value zero + iny ; Make old value = 1 +L2: ldx #$00 ; Load high byte of result + tya ; Load low byte, set CC + rts + +.endproc + diff --git a/libsrc/mega65/sysuname.s b/libsrc/mega65/sysuname.s new file mode 100644 index 000000000..2feab6fb1 --- /dev/null +++ b/libsrc/mega65/sysuname.s @@ -0,0 +1,37 @@ +; +; Ullrich von Bassewitz, 2003-08-12 +; +; unsigned char __fastcall__ _sysuname (struct utsname* buf); +; + + .export __sysuname, utsdata + + .import utscopy + + __sysuname = utscopy + +;-------------------------------------------------------------------------- +; Data. We define a fixed utsname struct here and just copy it. + +.rodata + +utsdata: + ; sysname + .asciiz "cc65" + + ; nodename + .asciiz "" + + ; release + .byte .string (>.version) + .byte '.' + .byte .string (<.version) + .byte $00 + + ; version + .byte '0' ; unused + .byte $00 + + ; machine + .asciiz "MEGA65" + diff --git a/libsrc/mega65/tmcommon.s b/libsrc/mega65/tmcommon.s new file mode 100644 index 000000000..52094b68e --- /dev/null +++ b/libsrc/mega65/tmcommon.s @@ -0,0 +1,64 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; Common stuff for the clock routines +; + + .include "c65.inc" + .include "get_tv.inc" + + .export TM, load_tenth + + .constructor inittime + .importzp sreg + .import _get_tv + + +;---------------------------------------------------------------------------- +.code + +.proc load_tenth + + lda #<(100 * 1000 * 1000 / $10000) + ldx #>(100 * 1000 * 1000 / $10000) + sta sreg + stx sreg+1 + lda #<(100 * 1000 * 1000) + ldx #>(100 * 1000 * 1000) + rts + +.endproc + +;---------------------------------------------------------------------------- +; Constructor that writes to the 1/10 sec register of the TOD to kick it +; into action. If this is not done, the clock hangs. We will read the register +; and write it again, ignoring a possible change in between. +.segment "ONCE" + +.proc inittime + + lda CIA1_TOD10 + sta CIA1_TOD10 + jsr _get_tv + cmp #TV::PAL + bne @60Hz + lda CIA1_CRA + ora #$80 + sta CIA1_CRA +@60Hz: rts + +.endproc + +;---------------------------------------------------------------------------- +; TM struct with date set to 1970-01-01 +.data + +TM: .word 0 ; tm_sec + .word 0 ; tm_min + .word 0 ; tm_hour + .word 1 ; tm_mday + .word 0 ; tm_mon + .word 70 ; tm_year + .word 0 ; tm_wday + .word 0 ; tm_yday + .word 0 ; tm_isdst diff --git a/targettest/Makefile b/targettest/Makefile index 56b5df446..a9a7ef77d 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -608,6 +608,64 @@ EXELIST_cx16 = \ strqtok-test \ uname-test +# omitted: deb em-test joy-test mouse-test ser-test seek +EXELIST_c65 = \ + arg-test \ + clock \ + clock-test \ + conio \ + cpeek-test \ + cprintf \ + cursor \ + dir-test \ + div-test \ + exec-test1 \ + exec-test2 \ + fileio-test \ + ft \ + getopt-test \ + heaptest \ + moddiv-test \ + mul-test \ + posixio-test \ + rename-test \ + scanf-test \ + strdup-test \ + strnlen \ + stroserror-test \ + strqtok-test \ + uname-test \ + minimal + +# omitted: deb em-test joy-test mouse-test ser-test seek +EXELIST_mega65 = \ + arg-test \ + clock \ + clock-test \ + conio \ + cpeek-test \ + cprintf \ + cursor \ + dir-test \ + div-test \ + exec-test1 \ + exec-test2 \ + fileio-test \ + ft \ + getopt-test \ + heaptest \ + moddiv-test \ + mul-test \ + posixio-test \ + rename-test \ + scanf-test \ + strdup-test \ + strnlen \ + stroserror-test \ + strqtok-test \ + uname-test \ + minimal + # omitted: arg-test clock-test clock cpeek-test cprintf cursor deb dir-test div-test # em-test exec-test1 exec-test2 fileio-test ft getopt-test heaptest joy-test moddiv-test # mouse-test mul-test posixio-test rename-test scanf-test seek ser-test strdup-test @@ -756,6 +814,7 @@ TARGETS := \ c128 \ c16 \ c64 \ + c65 \ cbm510 \ cbm610 \ creativision \ @@ -764,6 +823,7 @@ TARGETS := \ kim1 \ lunix \ lynx \ + mega65 \ nes \ osic1p \ pce \ diff --git a/targettest/cpeek-test.c b/targettest/cpeek-test.c index 4c1aadcb2..6f6556935 100644 --- a/targettest/cpeek-test.c +++ b/targettest/cpeek-test.c @@ -24,6 +24,10 @@ # define SCREEN_RAM ((unsigned char*)0x8000) #elif defined(__VIC20__) # define SCREEN_RAM ((unsigned char*)0x1000) +#elif defined(__C65__) +# define SCREEN_RAM ((unsigned char*)0x0800) +#elif defined(__MEGA65__) +# define SCREEN_RAM ((unsigned char*)0x0800) #else # error This program cannot test that target. # define SCREEN_RAM ((unsigned char*)0) From 955c6627c0dc94d38e14e228e1ace6637b0e2671 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 02:47:33 +0200 Subject: [PATCH 603/707] forgot settime... --- libsrc/mega65/settime.s | 84 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 libsrc/mega65/settime.s diff --git a/libsrc/mega65/settime.s b/libsrc/mega65/settime.s new file mode 100644 index 000000000..22a17fb61 --- /dev/null +++ b/libsrc/mega65/settime.s @@ -0,0 +1,84 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .include "time.inc" + .include "mega65.inc" + + .importzp sreg, ptr1 + .import pushax, pusheax, ldax0sp, ldeaxidx + .import tosdiveax, incsp3, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_settime + + jsr pushax + + .assert timespec::tv_sec = 0, error + jsr _localtime + sta ptr1 + stx ptr1+1 + ldy #.sizeof(tm)-1 +@L1: lda (ptr1),y + sta TM,y + dey + bpl @L1 + + lda TM + tm::tm_hour + jsr dec2BCD + tax ; Force flags + bne @L2 + lda #$92 ; 12 AM + bne @L3 +@L2: cmp #$13 ; 1 PM + bcc @L3 + sed + sbc #$12 + cld + ora #%10000000 +@L3: sta CIA1_TODHR + lda TM + tm::tm_min + jsr dec2BCD + sta CIA1_TODMIN + lda TM + tm::tm_sec + jsr dec2BCD + sta CIA1_TODSEC + + jsr ldax0sp + ldy #3+timespec::tv_nsec + jsr ldeaxidx + jsr pusheax + jsr load_tenth + jsr tosdiveax + sta CIA1_TOD10 + + jsr incsp3 + jmp return0 + +.endproc + +;---------------------------------------------------------------------------- +; Just sum up the value in BCD mode. +; http://forum.6502.org/viewtopic.php?p=7629#p7629 + +.proc dec2BCD + + tax + dex + bmi @L9 + lda #0 + clc + sed +@L1: adc #1 + dex + bpl @L1 + cld +@L9: rts + +.endproc From 4db5ac6c142479ec92f4bc09cd19e7aa98184209 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 05:13:09 +0200 Subject: [PATCH 604/707] SCREEN_PTR does only contain the offset apparently (unlike on other cbm systems), so we need extra handling --- libsrc/c65/cpeekc.s | 45 +++++++++++++++++++++ libsrc/c65/cpeekcolor.s | 25 ++++++++++++ libsrc/c65/cpeeks.s | 80 +++++++++++++++++++++++++++++++++++++ libsrc/c65/cputc.s | 24 ++++++----- libsrc/cbm/cpeekc.s | 4 -- libsrc/cbm/cpeekcolor.s | 4 -- libsrc/cbm/cpeeks.s | 4 -- libsrc/mega65/cpeekc.s | 45 +++++++++++++++++++++ libsrc/mega65/cpeekcolor.s | 25 ++++++++++++ libsrc/mega65/cpeekrevers.s | 28 +++++++++++++ libsrc/mega65/cpeeks.s | 80 +++++++++++++++++++++++++++++++++++++ libsrc/mega65/cputc.s | 26 ++++++------ libsrc/mega65/kbhit.s | 2 +- 13 files changed, 356 insertions(+), 36 deletions(-) create mode 100644 libsrc/c65/cpeekc.s create mode 100644 libsrc/c65/cpeekcolor.s create mode 100644 libsrc/c65/cpeeks.s create mode 100644 libsrc/mega65/cpeekc.s create mode 100644 libsrc/mega65/cpeekcolor.s create mode 100644 libsrc/mega65/cpeekrevers.s create mode 100644 libsrc/mega65/cpeeks.s diff --git a/libsrc/c65/cpeekc.s b/libsrc/c65/cpeekc.s new file mode 100644 index 000000000..a64e13cfd --- /dev/null +++ b/libsrc/c65/cpeekc.s @@ -0,0 +1,45 @@ +; +; 2016-02-28, Groepaz +; 2017-06-22, Greg King +; +; char cpeekc (void); +; + + .include "c65.inc" + + .export _cpeekc + .importzp ptr1 + +_cpeekc: + lda SCREEN_PTR + 1 + clc + adc #>$0800 + sta ptr1 + 1 + lda SCREEN_PTR + sta ptr1 + + ldy CURS_X + lda (ptr1),y ; get screen code + ldx #>$0000 + and #<~$80 ; remove reverse bit + +; Convert the screen code into a PetSCII code. +; $00 - $1F: +$40 +; $20 - $3F +; $40 - $5f: +$20 +; $60 - $7F: +$40 + + cmp #$20 + bcs @sk1 ;(bge) + ora #$40 + rts + +@sk1: cmp #$40 + bcc @end ;(blt) + cmp #$60 + bcc @sk2 ;(blt) + ;sec + adc #$20 - $01 +@sk2: ;clc ; both above cmp and adc clear carry flag + adc #$20 +@end: rts diff --git a/libsrc/c65/cpeekcolor.s b/libsrc/c65/cpeekcolor.s new file mode 100644 index 000000000..f4b4a5573 --- /dev/null +++ b/libsrc/c65/cpeekcolor.s @@ -0,0 +1,25 @@ +; +; 2016-02-28, Groepaz +; 2017-06-22, Greg King +; +; unsigned char cpeekcolor (void); +; + + .include "c65.inc" + + .export _cpeekcolor + .importzp ptr1 + +_cpeekcolor: + lda SCREEN_PTR + 1 + clc + adc #>$D800 + sta ptr1 + 1 + lda SCREEN_PTR + sta ptr1 + + ldy #0 + lda (ptr1),y + + ldx #>$0000 + rts diff --git a/libsrc/c65/cpeeks.s b/libsrc/c65/cpeeks.s new file mode 100644 index 000000000..9c33831f1 --- /dev/null +++ b/libsrc/c65/cpeeks.s @@ -0,0 +1,80 @@ +; +; 2017-07-05, Greg King +; +; void cpeeks (char* s, unsigned length); +; + + .include "c65.inc" + + .export _cpeeks + + .import popax + .importzp ptr1, ptr2, ptr3, tmp1, tmp2 + + .macpack generic + +_cpeeks: + eor #<$FFFF ; counting a word upward is faster + sta ptr3 ; so, we use -(length + 1) + txa + eor #>$FFFF + sta ptr3+1 + + lda SCREEN_PTR + sta ptr2 + lda SCREEN_PTR+1 + clc + adc #>$0800 + sta ptr2+1 + + ldy CURS_X + sty tmp2 + + jsr popax + sta tmp1 ; (will be a .Y index) + stx ptr1+1 + ldx #<$0000 + stx ptr1 + bze L3 ; branch always + +L4: ldy tmp2 + lda (ptr2),y ; get char + iny + bnz L2 + inc ptr2+1 +L2: sty tmp2 + and #<~$80 ; remove reverse bit + +; Convert the screen code into a PetSCII code. +; $00 - $1F: +$40 +; $20 - $3F +; $40 - $5f: +$20 +; $60 - $7F: +$40 + + cmp #$20 + blt @sk1 ;(bcc) + cmp #$40 + blt L5 + cmp #$60 + blt @sk2 ;(bcc) + clc +@sk1: adc #$20 +@sk2: ;clc ; both above cmp and adc clear carry flag + adc #$20 + +L5: ldy tmp1 + sta (ptr1),y + iny + bnz L1 + inc ptr1+1 +L1: sty tmp1 + +L3: inc ptr3 ; count length + bnz L4 + inc ptr3+1 + bnz L4 + + txa ; terminate the string + ldy tmp1 + sta (ptr1),y + rts diff --git a/libsrc/c65/cputc.s b/libsrc/c65/cputc.s index a34262437..99a81b67d 100644 --- a/libsrc/c65/cputc.s +++ b/libsrc/c65/cputc.s @@ -96,23 +96,25 @@ plot: ldy CURS_X putchar: ora RVS ; Set revers bit - ldy CURS_X - pha + tay lda SCREEN_PTR + 1 clc adc #>$0800 - sta SCREEN_PTR + 1 - pla + sta ptr4 + 1 + lda SCREEN_PTR + sta ptr4 + tya - sta (SCREEN_PTR),y ; Set char + ldy CURS_X + sta (ptr4),y ; Set char - lda SCREEN_PTR + 1 - sec - sbc #>$0800 - sta SCREEN_PTR + 1 + lda ptr4 + 1 + clc + adc #>$d000 + sta ptr4 + 1 lda CHARCOLOR -; lda #$88 -; sta (CRAM_PTR),y ; Set color + sta (ptr4),y ; Set color + rts diff --git a/libsrc/cbm/cpeekc.s b/libsrc/cbm/cpeekc.s index 32dc0456e..05c7fc718 100644 --- a/libsrc/cbm/cpeekc.s +++ b/libsrc/cbm/cpeekc.s @@ -22,10 +22,6 @@ .include "pet.inc" .elseif .def(__VIC20__) .include "vic20.inc" -.elseif .def(__C65__) - .include "c65.inc" -.elseif .def(__MEGA65__) - .include "mega65.inc" .endif diff --git a/libsrc/cbm/cpeekcolor.s b/libsrc/cbm/cpeekcolor.s index a0d7efe6c..9c961b771 100644 --- a/libsrc/cbm/cpeekcolor.s +++ b/libsrc/cbm/cpeekcolor.s @@ -17,10 +17,6 @@ .include "c64.inc" .elseif .def(__VIC20__) .include "vic20.inc" -.elseif .def(__C65__) - .include "c65.inc" -.elseif .def(__MEGA65__) - .include "mega65.inc" .endif diff --git a/libsrc/cbm/cpeeks.s b/libsrc/cbm/cpeeks.s index d73192d73..215998e37 100644 --- a/libsrc/cbm/cpeeks.s +++ b/libsrc/cbm/cpeeks.s @@ -26,10 +26,6 @@ .include "pet.inc" .elseif .def(__VIC20__) .include "vic20.inc" -.elseif .def(__C65__) - .include "c65.inc" -.elseif .def(__MEGA65__) - .include "mega65.inc" .endif diff --git a/libsrc/mega65/cpeekc.s b/libsrc/mega65/cpeekc.s new file mode 100644 index 000000000..f75926d3e --- /dev/null +++ b/libsrc/mega65/cpeekc.s @@ -0,0 +1,45 @@ +; +; 2016-02-28, Groepaz +; 2017-06-22, Greg King +; +; char cpeekc (void); +; + + .include "mega65.inc" + + .export _cpeekc + .importzp ptr1 + +_cpeekc: + lda SCREEN_PTR + 1 + clc + adc #>$0800 + sta ptr1 + 1 + lda SCREEN_PTR + sta ptr1 + + ldy CURS_X + lda (ptr1),y ; get screen code + ldx #>$0000 + and #<~$80 ; remove reverse bit + +; Convert the screen code into a PetSCII code. +; $00 - $1F: +$40 +; $20 - $3F +; $40 - $5f: +$20 +; $60 - $7F: +$40 + + cmp #$20 + bcs @sk1 ;(bge) + ora #$40 + rts + +@sk1: cmp #$40 + bcc @end ;(blt) + cmp #$60 + bcc @sk2 ;(blt) + ;sec + adc #$20 - $01 +@sk2: ;clc ; both above cmp and adc clear carry flag + adc #$20 +@end: rts diff --git a/libsrc/mega65/cpeekcolor.s b/libsrc/mega65/cpeekcolor.s new file mode 100644 index 000000000..45a59f3cb --- /dev/null +++ b/libsrc/mega65/cpeekcolor.s @@ -0,0 +1,25 @@ +; +; 2016-02-28, Groepaz +; 2017-06-22, Greg King +; +; unsigned char cpeekcolor (void); +; + + .include "mega65.inc" + + .export _cpeekcolor + .importzp ptr1 + +_cpeekcolor: + lda SCREEN_PTR + 1 + clc + adc #>$d800 + sta ptr1 + 1 + lda SCREEN_PTR + sta ptr1 + + ldy CURS_X + lda (ptr1),y + + ldx #>$0000 + rts diff --git a/libsrc/mega65/cpeekrevers.s b/libsrc/mega65/cpeekrevers.s new file mode 100644 index 000000000..a8e03e91e --- /dev/null +++ b/libsrc/mega65/cpeekrevers.s @@ -0,0 +1,28 @@ +; +; 2016-02-28, Groepaz +; 2017-06-15, Greg King +; +; unsigned char cpeekrevers (void); +; + + .include "mega65.inc" + + .export _cpeekrevers + .importzp ptr1 + +_cpeekrevers: + lda SCREEN_PTR + 1 + clc + adc #>$0800 + sta ptr1 + 1 + lda SCREEN_PTR + sta ptr1 + + ldy CURS_X + lda (ptr1),y ; get screen code + and #$80 ; get reverse bit + asl a + tax ; ldx #>$0000 + rol a ; return boolean value + + rts diff --git a/libsrc/mega65/cpeeks.s b/libsrc/mega65/cpeeks.s new file mode 100644 index 000000000..9c33831f1 --- /dev/null +++ b/libsrc/mega65/cpeeks.s @@ -0,0 +1,80 @@ +; +; 2017-07-05, Greg King +; +; void cpeeks (char* s, unsigned length); +; + + .include "c65.inc" + + .export _cpeeks + + .import popax + .importzp ptr1, ptr2, ptr3, tmp1, tmp2 + + .macpack generic + +_cpeeks: + eor #<$FFFF ; counting a word upward is faster + sta ptr3 ; so, we use -(length + 1) + txa + eor #>$FFFF + sta ptr3+1 + + lda SCREEN_PTR + sta ptr2 + lda SCREEN_PTR+1 + clc + adc #>$0800 + sta ptr2+1 + + ldy CURS_X + sty tmp2 + + jsr popax + sta tmp1 ; (will be a .Y index) + stx ptr1+1 + ldx #<$0000 + stx ptr1 + bze L3 ; branch always + +L4: ldy tmp2 + lda (ptr2),y ; get char + iny + bnz L2 + inc ptr2+1 +L2: sty tmp2 + and #<~$80 ; remove reverse bit + +; Convert the screen code into a PetSCII code. +; $00 - $1F: +$40 +; $20 - $3F +; $40 - $5f: +$20 +; $60 - $7F: +$40 + + cmp #$20 + blt @sk1 ;(bcc) + cmp #$40 + blt L5 + cmp #$60 + blt @sk2 ;(bcc) + clc +@sk1: adc #$20 +@sk2: ;clc ; both above cmp and adc clear carry flag + adc #$20 + +L5: ldy tmp1 + sta (ptr1),y + iny + bnz L1 + inc ptr1+1 +L1: sty tmp1 + +L3: inc ptr3 ; count length + bnz L4 + inc ptr3+1 + bnz L4 + + txa ; terminate the string + ldy tmp1 + sta (ptr1),y + rts diff --git a/libsrc/mega65/cputc.s b/libsrc/mega65/cputc.s index ad93ba7e5..df44f5bdd 100644 --- a/libsrc/mega65/cputc.s +++ b/libsrc/mega65/cputc.s @@ -9,10 +9,10 @@ .export newline, plot .import gotoxy .import PLOT + .importzp ptr4 .include "mega65.inc" - _cputcxy: pha ; Save C jsr gotoxy ; Set cursor, drop x and y @@ -96,23 +96,25 @@ plot: ldy CURS_X putchar: ora RVS ; Set revers bit - ldy CURS_X - pha + tay lda SCREEN_PTR + 1 clc adc #>$0800 - sta SCREEN_PTR + 1 - pla + sta ptr4 + 1 + lda SCREEN_PTR + sta ptr4 + tya - sta (SCREEN_PTR),y ; Set char + ldy CURS_X + sta (ptr4),y ; Set char - lda SCREEN_PTR + 1 - sec - sbc #>$0800 - sta SCREEN_PTR + 1 + lda ptr4 + 1 + clc + adc #>$d000 + sta ptr4 + 1 lda CHARCOLOR -; lda #$88 -; sta (CRAM_PTR),y ; Set color + sta (ptr4),y ; Set color + rts diff --git a/libsrc/mega65/kbhit.s b/libsrc/mega65/kbhit.s index 63b34629b..b88b0f48a 100644 --- a/libsrc/mega65/kbhit.s +++ b/libsrc/mega65/kbhit.s @@ -19,6 +19,6 @@ _kbhit: lda #1 : - ldx #0 + ldx #>$0000 rts From 1e209b1f150c681c208c28ebd0f7641f9e6d0683 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 05:14:26 +0200 Subject: [PATCH 605/707] forgot, need sleep --- libsrc/c65/cputc.s | 1 + 1 file changed, 1 insertion(+) diff --git a/libsrc/c65/cputc.s b/libsrc/c65/cputc.s index 99a81b67d..d9f63c1dd 100644 --- a/libsrc/c65/cputc.s +++ b/libsrc/c65/cputc.s @@ -9,6 +9,7 @@ .export newline, plot .import gotoxy .import PLOT + .importzp ptr4 .include "c65.inc" From 1feeee9ce076bff2aead0ddfa8427a0f9e452d6a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Wed, 25 Jun 2025 09:37:58 +0200 Subject: [PATCH 606/707] Do only check .c and .h files. --- .github/checks/sorted_codeopt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/checks/sorted_codeopt.sh b/.github/checks/sorted_codeopt.sh index c78662b9d..20145851a 100755 --- a/.github/checks/sorted_codeopt.sh +++ b/.github/checks/sorted_codeopt.sh @@ -63,6 +63,6 @@ function checkarray } -for N in `grep -rl "BEGIN DECL SORTED_CODEOPT.SH" "$CHECK_DIR"`; do - checkarray $N +find "$CHECK_DIR" -name \*.\[ch\] -print | while read N; do + grep -q "BEGIN DECL SORTED_CODEOPT.SH" "$N" && checkarray $N done From 2206b8d1998b35bdad3248cb9fb57f5df54a36f2 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 18:52:36 +0200 Subject: [PATCH 607/707] fix getscreensize --- libsrc/c65/_scrsize.s | 9 +++++++-- libsrc/mega65/_scrsize.s | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libsrc/c65/_scrsize.s b/libsrc/c65/_scrsize.s index 57ad4f30f..3fc955657 100644 --- a/libsrc/c65/_scrsize.s +++ b/libsrc/c65/_scrsize.s @@ -5,8 +5,13 @@ ; .export screensize - .import SCREEN + .include "cbm_kernal.inc" -screensize = SCREEN +.proc screensize + jsr SCREEN + inx + iny + rts +.endproc diff --git a/libsrc/mega65/_scrsize.s b/libsrc/mega65/_scrsize.s index 57ad4f30f..3fc955657 100644 --- a/libsrc/mega65/_scrsize.s +++ b/libsrc/mega65/_scrsize.s @@ -5,8 +5,13 @@ ; .export screensize - .import SCREEN + .include "cbm_kernal.inc" -screensize = SCREEN +.proc screensize + jsr SCREEN + inx + iny + rts +.endproc From 55d9b2dbd0530aa5f355be94126676ff100f2cc9 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Wed, 25 Jun 2025 20:07:36 +0200 Subject: [PATCH 608/707] Rewrite the optimization step from c0a1b1b887af536612987847c9344a1226bf4397 to remove compares not only before RTS but also befoire function calls that don't use the flags but destroy all of them. The latter is currently the case for all functions called. This way the optimization covers a lot more cases than just checking for RTS. --- src/cc65/codeopt.c | 6 ++-- src/cc65/coptcmp.c | 82 +++++++++++++++++++++++++--------------------- src/cc65/coptcmp.h | 10 +++--- 3 files changed, 53 insertions(+), 45 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index e9cf8914f..f7e3d4a1a 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -129,11 +129,11 @@ static OptFunc DOptBoolUnary3 = { OptBoolUnary3, "OptBoolUnary3", 40, 0, static OptFunc DOptBranchDist = { OptBranchDist, "OptBranchDist", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptBranchDist2 = { OptBranchDist2, "OptBranchDist2", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp1 = { OptCmp1, "OptCmp1", 42, 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp10 = { OptCmp10, "OptCmp10", 33, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp2 = { OptCmp2, "OptCmp2", 85, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp3 = { OptCmp3, "OptCmp3", 75, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp4 = { OptCmp4, "OptCmp4", 75, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp5 = { OptCmp5, "OptCmp5", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp6 = { OptCmp6, "OptCmp6", 33, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp7 = { OptCmp7, "OptCmp7", 85, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp8 = { OptCmp8, "OptCmp8", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp9 = { OptCmp9, "OptCmp9", 85, 0, 0, 0, 0, 0 }; @@ -252,11 +252,11 @@ static OptFunc* OptFuncs[] = { &DOptBranchDist, &DOptBranchDist2, &DOptCmp1, - &DOptCmp10, &DOptCmp2, &DOptCmp3, &DOptCmp4, &DOptCmp5, + &DOptCmp6, &DOptCmp7, &DOptCmp8, &DOptCmp9, @@ -731,7 +731,7 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptCondBranch3, 1); C += RunOptFunc (S, &DOptCondBranchC, 1); C += RunOptFunc (S, &DOptRTSJumps1, 1); - C += RunOptFunc (S, &DOptCmp10, 1); /* After OptRTSJumps1 */ + C += RunOptFunc (S, &DOptCmp6, 1); /* After OptRTSJumps1 */ C += RunOptFunc (S, &DOptBoolCmp, 1); C += RunOptFunc (S, &DOptBoolTrans, 1); C += RunOptFunc (S, &DOptBNegA2, 1); /* After OptCondBranch's */ diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index 25499dc3c..8f487969e 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -503,6 +503,51 @@ unsigned OptCmp5 (CodeSeg* S) +unsigned OptCmp6 (CodeSeg* S) +/* Remove compare instructions before an RTS or an subroutine call that doesn't +** use the flags. +*/ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* N; + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check for a compare followed by something else. + ** Note: The test could be improved by checking the flag usage of the + ** function explicitly against the flags set by the compare instruction. + ** For current code generation this makes no difference, however. + */ + if ((E->Info & OF_CMP) != 0 && + (N = CS_GetNextEntry (S, I)) != 0 && + (N->OPC == OP65_RTS || /* Either RTS, or ... */ + (N->OPC == OP65_JSR && /* ... or JSR ... */ + N->JumpTo == 0 && /* ... to external ... */ + (N->Use & PSTATE_ALL) == 0 && /* ... with no flags used ... */ + (N->Chg & PSTATE_ALL) == PSTATE_ALL))) { /* ... but all destroyed */ + + /* Found, remove the compare */ + CS_DelEntry (S, I); + ++Changes; + } + + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} + + + unsigned OptCmp7 (CodeSeg* S) /* Search for a sequence ldx/txa/branch and remove the txa if A is not ** used later. @@ -741,40 +786,3 @@ unsigned OptCmp9 (CodeSeg* S) /* Return the number of changes made */ return Changes; } - - - -unsigned OptCmp10 (CodeSeg* S) -/* Remove compare instructions before an RTS. This is safe since no C function -** passes back something in the flags. -*/ -{ - unsigned Changes = 0; - unsigned I; - - /* Walk over the entries */ - I = 0; - while (I < CS_GetEntryCount (S)) { - - CodeEntry* N; - - /* Get next entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check for a compare followed by an RTS */ - if ((E->Info & OF_CMP) != 0 && /* Compare insn */ - (N = CS_GetNextEntry (S, I)) != 0 && /* Next entry ... */ - N->OPC == OP65_RTS) { /* ... is RTS */ - - /* Found, remove the compare */ - CS_DelEntry (S, I); - ++Changes; - } - - /* Next entry */ - ++I; - } - - /* Return the number of changes made */ - return Changes; -} diff --git a/src/cc65/coptcmp.h b/src/cc65/coptcmp.h index ff58d37df..acd146822 100644 --- a/src/cc65/coptcmp.h +++ b/src/cc65/coptcmp.h @@ -123,6 +123,11 @@ unsigned OptCmp5 (CodeSeg* S); ** jne/jeq L2 */ +unsigned OptCmp6 (CodeSeg* S); +/* Remove compare instructions before an RTS or an exit by jumping to some +** other function. +*/ + unsigned OptCmp7 (CodeSeg* S); /* Search for a sequence ldx/txa/branch and remove the txa if A is not ** used later. @@ -146,11 +151,6 @@ unsigned OptCmp9 (CodeSeg* S); ** flag instead of the carry flag and remove the asl. */ -unsigned OptCmp10 (CodeSeg* S); -/* Remove compare instructions before an RTS. This is safe since no C function -** passes back something in the flags. -*/ - /* End of coptcmp.h */ From fa81f14cbf2b7cbfee4dbda68d65666b78d2ca91 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Wed, 25 Jun 2025 20:34:41 +0200 Subject: [PATCH 609/707] Add an explicit "exit 0" to the shell scripts. This worked more or less by coincidence before since shell scripts return the exit code of the last command run if there is no explicit exit statement. --- .github/checks/lastline.sh | 1 + .github/checks/lineendings.sh | 1 + .github/checks/noexec.sh | 1 + .github/checks/sorted.sh | 1 + .github/checks/sorted_codeopt.sh | 1 + .github/checks/sorted_opcodes.sh | 2 +- .github/checks/spaces.sh | 1 + .github/checks/tabs.sh | 1 + 8 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/checks/lastline.sh b/.github/checks/lastline.sh index d243a01e1..6bb6e0dc5 100755 --- a/.github/checks/lastline.sh +++ b/.github/checks/lastline.sh @@ -23,3 +23,4 @@ if [ x"$FILES"x != xx ]; then done exit -1 fi +exit 0 diff --git a/.github/checks/lineendings.sh b/.github/checks/lineendings.sh index 5b445522f..5baac514e 100755 --- a/.github/checks/lineendings.sh +++ b/.github/checks/lineendings.sh @@ -16,3 +16,4 @@ if [ x"$FILES"x != xx ]; then done exit -1 fi +exit 0 diff --git a/.github/checks/noexec.sh b/.github/checks/noexec.sh index c76ae481d..5e53fe869 100755 --- a/.github/checks/noexec.sh +++ b/.github/checks/noexec.sh @@ -16,3 +16,4 @@ if [ x"$FILES"x != xx ]; then done exit -1 fi +exit 0 diff --git a/.github/checks/sorted.sh b/.github/checks/sorted.sh index 4f53b0484..b5451a21f 100755 --- a/.github/checks/sorted.sh +++ b/.github/checks/sorted.sh @@ -36,3 +36,4 @@ function checkarray_quoted_name for N in `grep -rl "BEGIN SORTED.SH" "$CHECK_DIR"`; do checkarray_quoted_name $N done +exit 0 diff --git a/.github/checks/sorted_codeopt.sh b/.github/checks/sorted_codeopt.sh index 20145851a..cfca028dd 100755 --- a/.github/checks/sorted_codeopt.sh +++ b/.github/checks/sorted_codeopt.sh @@ -66,3 +66,4 @@ function checkarray find "$CHECK_DIR" -name \*.\[ch\] -print | while read N; do grep -q "BEGIN DECL SORTED_CODEOPT.SH" "$N" && checkarray $N done +exit 0 diff --git a/.github/checks/sorted_opcodes.sh b/.github/checks/sorted_opcodes.sh index 3e45ea752..34156bde6 100755 --- a/.github/checks/sorted_opcodes.sh +++ b/.github/checks/sorted_opcodes.sh @@ -37,4 +37,4 @@ function checkarray_quoted_name for N in `grep -rl "BEGIN SORTED_OPCODES.SH" "$CHECK_DIR"`; do checkarray_quoted_name $N done - +exit 0 diff --git a/.github/checks/spaces.sh b/.github/checks/spaces.sh index e231f6c2d..f2eea6f3f 100755 --- a/.github/checks/spaces.sh +++ b/.github/checks/spaces.sh @@ -16,3 +16,4 @@ if [ x"$FILES"x != xx ]; then done exit -1 fi +exit 0 diff --git a/.github/checks/tabs.sh b/.github/checks/tabs.sh index 80dac3f2d..ed8d45bac 100755 --- a/.github/checks/tabs.sh +++ b/.github/checks/tabs.sh @@ -16,3 +16,4 @@ if [ x"$FILES"x != xx ]; then done exit -1 fi +exit 0 From ef1b1015385cb9df6e894ffc64b8d84150d371b4 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 20:38:58 +0200 Subject: [PATCH 610/707] fix cursor() --- asminc/cbm_kernal.inc | 16 ++++++++++++---- libsrc/c65/cursor.s | 26 ++++++++++++++++++++++++++ libsrc/mega65/cursor.s | 26 ++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 libsrc/c65/cursor.s create mode 100644 libsrc/mega65/cursor.s diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index a2fb05cb0..963ab1985 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -63,16 +63,24 @@ MOUSE_GET := $FF6B .endif -.if .def(__C65__) || .def (__MEGA65__) +.if .def (__MEGA65__) ; extended C65 jump table - VERSIONQ := $FF2F - RESET_RUN := $FF32 - CURSOR := $FF35 + +; memory before $ff3b is all $ff in mega65 ROM? +; VERSIONQ := $FF2F +; RESET_RUN := $FF32 +; CURSOR := $FF35 + SAVEFL := $FF3B GETIO := $FF41 GETLFS := $FF44 KEYLOCKS := $FF47 ADDKEY := $FF4A +.endif + +.if .def(__C65__) || .def (__MEGA65__) + CURSOR := $E030 ; in editor ROM + SPIN_SPOUT := $FF4D CLSALL := $FF50 C64MODE := $FF53 diff --git a/libsrc/c65/cursor.s b/libsrc/c65/cursor.s new file mode 100644 index 000000000..8c36a7a32 --- /dev/null +++ b/libsrc/c65/cursor.s @@ -0,0 +1,26 @@ +; +; unsigned char cursor (unsigned char onoff); +; + + .include "cbm_kernal.inc" + + .export _cursor + .import cursor + +.proc _cursor + pha + ; A != 0 to enable, 0 to disable + cmp #0 + beq disable ; C = 1 + clc +disable: + ; C = 0 to enable, 1 to disable + jsr CURSOR + + ply ; onoff into Y + ldx #0 ; High byte of result + lda cursor ; Get old value + sty cursor ; Set new value + rts +.endproc + diff --git a/libsrc/mega65/cursor.s b/libsrc/mega65/cursor.s new file mode 100644 index 000000000..8c36a7a32 --- /dev/null +++ b/libsrc/mega65/cursor.s @@ -0,0 +1,26 @@ +; +; unsigned char cursor (unsigned char onoff); +; + + .include "cbm_kernal.inc" + + .export _cursor + .import cursor + +.proc _cursor + pha + ; A != 0 to enable, 0 to disable + cmp #0 + beq disable ; C = 1 + clc +disable: + ; C = 0 to enable, 1 to disable + jsr CURSOR + + ply ; onoff into Y + ldx #0 ; High byte of result + lda cursor ; Get old value + sty cursor ; Set new value + rts +.endproc + From a7e509cd43f4ff54a11873757615f8bf68d49940 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 21:39:03 +0200 Subject: [PATCH 611/707] better handling of the cursor, use kernal function to read key, not the UART directly --- asminc/cbm_kernal.inc | 1 + libsrc/c65/cgetc.s | 32 ++++++++++++++++++++++++++++++++ libsrc/c65/cursor.s | 26 -------------------------- libsrc/c65/kbhit.s | 12 +----------- libsrc/mega65/cgetc.s | 32 ++++++++++++++++++++++++++++++++ libsrc/mega65/cursor.s | 26 -------------------------- libsrc/mega65/kbhit.s | 10 ---------- 7 files changed, 66 insertions(+), 73 deletions(-) create mode 100644 libsrc/c65/cgetc.s delete mode 100644 libsrc/c65/cursor.s create mode 100644 libsrc/mega65/cgetc.s delete mode 100644 libsrc/mega65/cursor.s diff --git a/asminc/cbm_kernal.inc b/asminc/cbm_kernal.inc index 963ab1985..f06483a47 100644 --- a/asminc/cbm_kernal.inc +++ b/asminc/cbm_kernal.inc @@ -244,4 +244,5 @@ UDTIM := $FFEA KBDREAD := $D8C1 .elseif .def(__C65__) || .def(__MEGA65__) ; CLRSCR := $E0EC ; ??? + KBDREAD := $E006 .endif diff --git a/libsrc/c65/cgetc.s b/libsrc/c65/cgetc.s new file mode 100644 index 000000000..3b2d5934d --- /dev/null +++ b/libsrc/c65/cgetc.s @@ -0,0 +1,32 @@ + + + .include "cbm_kernal.inc" + .import cursor + .export _cgetc +_cgetc: + + lda cursor + beq nocursor + + ; enable the cursor + clc + jsr CURSOR + +nocursor: + ; wait for a key + ; FIXME: is $d610 mega65 specific? +: + lda $d610 + beq :- + + jsr KBDREAD + + pha + ; disable the cursor + sec + jsr CURSOR + + pla + ldx #0 + rts + diff --git a/libsrc/c65/cursor.s b/libsrc/c65/cursor.s deleted file mode 100644 index 8c36a7a32..000000000 --- a/libsrc/c65/cursor.s +++ /dev/null @@ -1,26 +0,0 @@ -; -; unsigned char cursor (unsigned char onoff); -; - - .include "cbm_kernal.inc" - - .export _cursor - .import cursor - -.proc _cursor - pha - ; A != 0 to enable, 0 to disable - cmp #0 - beq disable ; C = 1 - clc -disable: - ; C = 0 to enable, 1 to disable - jsr CURSOR - - ply ; onoff into Y - ldx #0 ; High byte of result - lda cursor ; Get old value - sty cursor ; Set new value - rts -.endproc - diff --git a/libsrc/c65/kbhit.s b/libsrc/c65/kbhit.s index 63b34629b..683451b03 100644 --- a/libsrc/c65/kbhit.s +++ b/libsrc/c65/kbhit.s @@ -1,17 +1,7 @@ - ; FIXME: is $d610 mega65 specific? ; FIXME: this should rather use the kernal (with keyboard buffer etc) - .export _cgetc -_cgetc: - -: lda $d610 - beq :- - ldx #0 - stx $d610 - rts - .export _kbhit _kbhit: lda $d610 @@ -19,6 +9,6 @@ _kbhit: lda #1 : - ldx #0 + ldx #>$0000 rts diff --git a/libsrc/mega65/cgetc.s b/libsrc/mega65/cgetc.s new file mode 100644 index 000000000..3b2d5934d --- /dev/null +++ b/libsrc/mega65/cgetc.s @@ -0,0 +1,32 @@ + + + .include "cbm_kernal.inc" + .import cursor + .export _cgetc +_cgetc: + + lda cursor + beq nocursor + + ; enable the cursor + clc + jsr CURSOR + +nocursor: + ; wait for a key + ; FIXME: is $d610 mega65 specific? +: + lda $d610 + beq :- + + jsr KBDREAD + + pha + ; disable the cursor + sec + jsr CURSOR + + pla + ldx #0 + rts + diff --git a/libsrc/mega65/cursor.s b/libsrc/mega65/cursor.s deleted file mode 100644 index 8c36a7a32..000000000 --- a/libsrc/mega65/cursor.s +++ /dev/null @@ -1,26 +0,0 @@ -; -; unsigned char cursor (unsigned char onoff); -; - - .include "cbm_kernal.inc" - - .export _cursor - .import cursor - -.proc _cursor - pha - ; A != 0 to enable, 0 to disable - cmp #0 - beq disable ; C = 1 - clc -disable: - ; C = 0 to enable, 1 to disable - jsr CURSOR - - ply ; onoff into Y - ldx #0 ; High byte of result - lda cursor ; Get old value - sty cursor ; Set new value - rts -.endproc - diff --git a/libsrc/mega65/kbhit.s b/libsrc/mega65/kbhit.s index b88b0f48a..683451b03 100644 --- a/libsrc/mega65/kbhit.s +++ b/libsrc/mega65/kbhit.s @@ -1,17 +1,7 @@ - ; FIXME: is $d610 mega65 specific? ; FIXME: this should rather use the kernal (with keyboard buffer etc) - .export _cgetc -_cgetc: - -: lda $d610 - beq :- - ldx #0 - stx $d610 - rts - .export _kbhit _kbhit: lda $d610 From f8b1691effefb9492720b03ffd4fe7784d13a6a9 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 21:48:25 +0200 Subject: [PATCH 612/707] prepare vic3 header --- include/_vic3.h | 188 +++++++++++++++++++++++++++++++++++++++++++++++ include/c65.h | 2 +- include/mega65.h | 2 +- 3 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 include/_vic3.h diff --git a/include/_vic3.h b/include/_vic3.h new file mode 100644 index 000000000..820591656 --- /dev/null +++ b/include/_vic3.h @@ -0,0 +1,188 @@ +/*****************************************************************************/ +/* */ +/* _vic3.h */ +/* */ +/* Internal include file, do not use directly */ +/* */ +/* */ +/* */ +/* (C) 1998-2012, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef __VIC3_H +#define __VIC3_H + +/* FIXME: only VIC2 registers right now */ + +/* Define a structure with the vic register offsets. In cc65 mode, there +** are aliases for the field accessible as arrays. +*/ +#if __CC65_STD__ == __CC65_STD_CC65__ +struct __vic3 { + union { + struct { + unsigned char spr0_x; /* Sprite 0, X coordinate */ + unsigned char spr0_y; /* Sprite 0, Y coordinate */ + unsigned char spr1_x; /* Sprite 1, X coordinate */ + unsigned char spr1_y; /* Sprite 1, Y coordinate */ + unsigned char spr2_x; /* Sprite 2, X coordinate */ + unsigned char spr2_y; /* Sprite 2, Y coordinate */ + unsigned char spr3_x; /* Sprite 3, X coordinate */ + unsigned char spr3_y; /* Sprite 3, Y coordinate */ + unsigned char spr4_x; /* Sprite 4, X coordinate */ + unsigned char spr4_y; /* Sprite 4, Y coordinate */ + unsigned char spr5_x; /* Sprite 5, X coordinate */ + unsigned char spr5_y; /* Sprite 5, Y coordinate */ + unsigned char spr6_x; /* Sprite 6, X coordinate */ + unsigned char spr6_y; /* Sprite 6, Y coordinate */ + unsigned char spr7_x; /* Sprite 7, X coordinate */ + unsigned char spr7_y; /* Sprite 7, Y coordinate */ + }; + struct { + unsigned char x; /* X coordinate */ + unsigned char y; /* Y coordinate */ + } spr_pos[8]; + }; + unsigned char spr_hi_x; /* High bits of X coordinate */ + unsigned char ctrl1; /* Control register 1 */ + unsigned char rasterline; /* Current raster line */ + union { + struct { + unsigned char strobe_x; /* Light pen, X position */ + unsigned char strobe_y; /* Light pen, Y position */ + }; + struct { + unsigned char x; /* Light pen, X position */ + unsigned char y; /* Light pen, Y position */ + } strobe; + }; + unsigned char spr_ena; /* Enable sprites */ + unsigned char ctrl2; /* Control register 2 */ + unsigned char spr_exp_y; /* Expand sprites in Y dir */ + unsigned char addr; /* Address of chargen and video ram */ + unsigned char irr; /* Interrupt request register */ + unsigned char imr; /* Interrupt mask register */ + unsigned char spr_bg_prio; /* Priority to background */ + unsigned char spr_mcolor; /* Sprite multicolor bits */ + unsigned char spr_exp_x; /* Expand sprites in X dir */ + unsigned char spr_coll; /* Sprite/sprite collision reg */ + unsigned char spr_bg_coll; /* Sprite/background collision reg */ + unsigned char bordercolor; /* Border color */ + union { + struct { + unsigned char bgcolor0; /* Background color 0 */ + unsigned char bgcolor1; /* Background color 1 */ + unsigned char bgcolor2; /* Background color 2 */ + unsigned char bgcolor3; /* Background color 3 */ + }; + unsigned char bgcolor[4]; /* Background colors */ + }; + union { + struct { + unsigned char spr_mcolor0; /* Color 0 for multicolor sprites */ + unsigned char spr_mcolor1; /* Color 1 for multicolor sprites */ + }; + /* spr_color is already used ... */ + unsigned char spr_mcolors[2]; /* Color for multicolor sprites */ + }; + union { + struct { + unsigned char spr0_color; /* Color sprite 0 */ + unsigned char spr1_color; /* Color sprite 1 */ + unsigned char spr2_color; /* Color sprite 2 */ + unsigned char spr3_color; /* Color sprite 3 */ + unsigned char spr4_color; /* Color sprite 4 */ + unsigned char spr5_color; /* Color sprite 5 */ + unsigned char spr6_color; /* Color sprite 6 */ + unsigned char spr7_color; /* Color sprite 7 */ + }; + unsigned char spr_color[8]; /* Colors for the sprites */ + }; + + /* The following ones are only valid in the C128: */ + unsigned char x_kbd; /* Additional keyboard lines */ + unsigned char clock; /* Clock switch bit */ +}; +#else +struct __vic3 { + unsigned char spr0_x; /* Sprite 0, X coordinate */ + unsigned char spr0_y; /* Sprite 0, Y coordinate */ + unsigned char spr1_x; /* Sprite 1, X coordinate */ + unsigned char spr1_y; /* Sprite 1, Y coordinate */ + unsigned char spr2_x; /* Sprite 2, X coordinate */ + unsigned char spr2_y; /* Sprite 2, Y coordinate */ + unsigned char spr3_x; /* Sprite 3, X coordinate */ + unsigned char spr3_y; /* Sprite 3, Y coordinate */ + unsigned char spr4_x; /* Sprite 4, X coordinate */ + unsigned char spr4_y; /* Sprite 4, Y coordinate */ + unsigned char spr5_x; /* Sprite 5, X coordinate */ + unsigned char spr5_y; /* Sprite 5, Y coordinate */ + unsigned char spr6_x; /* Sprite 6, X coordinate */ + unsigned char spr6_y; /* Sprite 6, Y coordinate */ + unsigned char spr7_x; /* Sprite 7, X coordinate */ + unsigned char spr7_y; /* Sprite 7, Y coordinate */ + unsigned char spr_hi_x; /* High bits of X coordinate */ + unsigned char ctrl1; /* Control register 1 */ + unsigned char rasterline; /* Current raster line */ + unsigned char strobe_x; /* Light pen, X position */ + unsigned char strobe_y; /* Light pen, Y position */ + unsigned char spr_ena; /* Enable sprites */ + unsigned char ctrl2; /* Control register 2 */ + unsigned char spr_exp_y; /* Expand sprites in Y dir */ + unsigned char addr; /* Address of chargen and video ram */ + unsigned char irr; /* Interrupt request register */ + unsigned char imr; /* Interrupt mask register */ + unsigned char spr_bg_prio; /* Priority to background */ + unsigned char spr_mcolor; /* Sprite multicolor bits */ + unsigned char spr_exp_x; /* Expand sprites in X dir */ + unsigned char spr_coll; /* Sprite/sprite collision reg */ + unsigned char spr_bg_coll; /* Sprite/background collision reg */ + unsigned char bordercolor; /* Border color */ + unsigned char bgcolor0; /* Background color 0 */ + unsigned char bgcolor1; /* Background color 1 */ + unsigned char bgcolor2; /* Background color 2 */ + unsigned char bgcolor3; /* Background color 3 */ + unsigned char spr_mcolor0; /* Color 0 for multicolor sprites */ + unsigned char spr_mcolor1; /* Color 1 for multicolor sprites */ + unsigned char spr0_color; /* Color sprite 0 */ + unsigned char spr1_color; /* Color sprite 1 */ + unsigned char spr2_color; /* Color sprite 2 */ + unsigned char spr3_color; /* Color sprite 3 */ + unsigned char spr4_color; /* Color sprite 4 */ + unsigned char spr5_color; /* Color sprite 5 */ + unsigned char spr6_color; /* Color sprite 6 */ + unsigned char spr7_color; /* Color sprite 7 */ +}; +#endif + + + +/* End of _vic3.h */ +#endif + + + diff --git a/include/c65.h b/include/c65.h index 5ba485978..34270be03 100644 --- a/include/c65.h +++ b/include/c65.h @@ -100,7 +100,7 @@ /* Define hardware */ -#include <_vic2.h> +#include <_vic3.h> #define VIC (*(struct __vic2*)0xD000) #include <_sid.h> diff --git a/include/mega65.h b/include/mega65.h index 9f13d2e6c..83d48606d 100644 --- a/include/mega65.h +++ b/include/mega65.h @@ -100,7 +100,7 @@ /* Define hardware */ -#include <_vic2.h> +#include <_vic3.h> #define VIC (*(struct __vic2*)0xD000) #include <_sid.h> From 38bdb2326bddc8e8baf20596e6a487de0d675f4e Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 23:14:08 +0200 Subject: [PATCH 613/707] added a simple joystick api example, since we didn't have one. --- samples/Makefile | 31 ++++++++++++---- samples/joydemo.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 samples/joydemo.c diff --git a/samples/Makefile b/samples/Makefile index 7d506e135..6c00c97a4 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -84,10 +84,12 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*) MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*) TGI := $(wildcard $(TARGET_PATH)/$(SYS)/drv/tgi/*) + JOY := $(wildcard $(TARGET_PATH)/$(SYS)/drv/joy/*) EMD := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/emd/,$(notdir $(filter %.emd,$(EMD)))) MOU := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/mou/,$(notdir $(filter %.mou,$(MOU)))) TGI := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/tgi/,$(notdir $(filter %.tgi,$(TGI)))) + JOY := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/joy/,$(notdir $(filter %.joy,$(JOY)))) # This one comes with the VICE emulator. # See http://vice-emu.sourceforge.net/ @@ -180,6 +182,7 @@ EXELIST_apple2 = \ enumdevdir \ gunzip65 \ hello \ + joydemo \ mandelbrot \ mousedemo \ multdemo \ @@ -213,10 +216,14 @@ EXELIST_atari2600 = \ EXELIST_atari5200 = \ notavailable +EXELIST_atari7800 = \ + notavailable + EXELIST_atmos = \ ascii \ checkversion \ hello \ + joydemo \ mandelbrot \ sieve \ terminal \ @@ -231,6 +238,7 @@ EXELIST_c64 = \ enumdevdir \ gunzip65 \ hello \ + joydemo \ mandelbrot \ mousedemo \ multdemo \ @@ -254,6 +262,7 @@ EXELIST_c128 = \ enumdevdir \ gunzip65 \ hello \ + joydemo \ mandelbrot \ mousedemo \ sieve \ @@ -266,13 +275,15 @@ EXELIST_c16 = \ checkversion \ enumdevdir \ tinyshell \ - hello + hello \ + joydemo EXELIST_cbm510 = \ ascii \ checkversion \ gunzip65 \ hello \ + joydemo \ mousedemo \ terminal \ tinyshell \ @@ -297,6 +308,7 @@ EXELIST_cx16 = \ enumdevdir \ gunzip65 \ hello \ + joydemo \ mandelbrot \ mousedemo \ sieve \ @@ -308,7 +320,6 @@ EXELIST_gamate = \ EXELIST_geos-cbm = \ ascii \ - checkversion \ diodemo EXELIST_geos-apple = \ @@ -329,19 +340,22 @@ EXELIST_mega65 = \ tinyshell EXELIST_nes = \ - hello + hello \ + joydemo EXELIST_osic1p = \ notavailable EXELIST_pce = \ - hello + hello \ + joydemo EXELIST_pet = \ ascii \ checkversion \ enumdevdir \ hello \ + joydemo \ tinyshell \ sieve @@ -351,6 +365,7 @@ EXELIST_plus4 = \ enumdevdir \ gunzip65 \ hello \ + joydemo \ mandelbrot \ terminal \ tinyshell \ @@ -377,6 +392,7 @@ EXELIST_telestrat = \ checkversion \ gunzip65 \ hello \ + joydemo \ mandelbrot \ sieve \ tgidemo @@ -386,6 +402,7 @@ EXELIST_vic20 = \ checkversion \ enumdevdir \ hello \ + joydemo \ mandelbrot \ sieve \ tgidemo @@ -541,7 +558,7 @@ samples.d64: samples @$(C1541) -format "samples,00" d64 $@ >$(NULLDEV) $(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_PRG_recipe)) $(foreach file,$(OVERLAYLIST),$(D64_WRITE_PRG_recipe)) - $(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_SEQ_recipe)) + $(foreach file,$(EMD) $(MOU) $(JOY) $(TGI),$(D64_WRITE_SEQ_recipe)) # -------------------------------------------------------------------------- # Rule to make an Apple II disk with all samples. Needs the AppleCommander @@ -566,7 +583,7 @@ samples.dsk: samples cp prodos.dsk $@ $(foreach file,$(EXELIST_$(SYS)),$(DSK_WRITE_BIN_recipe)) $(foreach file,$(OVERLAYLIST),$(DSK_WRITE_REL_recipe)) - $(foreach file,$(EMD) $(MOU) $(TGI),$(DSK_WRITE_REL_recipe)) + $(foreach file,$(EMD) $(MOU) $(JOY) $(TGI),$(DSK_WRITE_REL_recipe)) # -------------------------------------------------------------------------- # Rule to make an Atari disk with all samples. Needs the dir2atr program @@ -585,7 +602,7 @@ samples.atr: samples cp "dup.sys" atr/dup.sys @$(foreach file,$(EXELIST_$(SYS)),$(ATR_WRITE_recipe)) @$(foreach file,$(OVERLAYLIST),$(ATR_WRITE_recipe)) - @$(foreach file,$(EMD) $(MOU) $(TGI),$(ATR_WRITE_recipe)) + @$(foreach file,$(EMD) $(MOU) $(JOY) $(TGI),$(ATR_WRITE_recipe)) $(DIR2ATR) -d -b MyDos4534 3200 $@ atr @$(RMDIR) atr diff --git a/samples/joydemo.c b/samples/joydemo.c new file mode 100644 index 000000000..807c16a08 --- /dev/null +++ b/samples/joydemo.c @@ -0,0 +1,91 @@ + +#include <stdlib.h> +#include <stdio.h> +#include <joystick.h> + +#ifndef DYN_DRV +# define DYN_DRV 1 +#endif + +#define USECONIO + +#ifdef USECONIO +#include <conio.h> +#define PRINTF cprintf +#define CR "\n\r" +#else +#define PRINTF printf +#define CR "\n" +#endif + +int main (void) +{ + unsigned char num_joy; + unsigned char raw_value; + unsigned char i; + unsigned char err; + unsigned char y; +#ifdef USECONIO + clrscr(); +#endif + PRINTF("Driver init..." CR); + +#if DYN_DRV + /* Load and initialize the driver */ + if ((err = joy_load_driver (joy_stddrv))) { + PRINTF ("Driver load error (code %d)." CR + "Warning: This program needs the JOY" CR + "driver on disk!" CR, err); + exit (EXIT_FAILURE); + } + PRINTF("Driver loaded OK" CR); +#else + /* Install the driver */ + joy_install (joy_static_stddrv); +#endif + + num_joy = joy_count(); + + PRINTF("Driver reported %d joysticks." CR "waiting for input..." CR, num_joy); + + /* wait for something to happen on any joystick input */ + { + unsigned char wait = 1; + while (wait) { + for (i = 0; i < num_joy; ++i) { + raw_value = joy_read(i); + if (raw_value) { + wait = 0; + break; + } + } + } + } + + /* read all joysticks and print the raw value(s) */ +#ifdef USECONIO + y = wherey(); +#endif + while (1) { +#ifdef USECONIO + gotoxy(0, y); +#endif + for (i = 0; i < num_joy; ++i) { + raw_value = joy_read(i); + PRINTF("%02x ", raw_value); + } + PRINTF(CR); + } + +#if DYN_DRV + /* Unload the driver */ + joy_unload (); +#else + /* Uninstall the driver */ + joy_uninstall (); +#endif + + /* Done */ + PRINTF ("Done" CR); + return EXIT_SUCCESS; +} From ad4d86bbf29476c191ad243b3361c3f3720d9dc4 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 23:44:07 +0200 Subject: [PATCH 614/707] add a standard joystick driver, adapted from the c64 one --- libsrc/c65/joy/c65-stdjoy.s | 111 ++++++++++++++++++++++++++++++++ libsrc/c65/joy_stat_stddrv.s | 14 ++++ libsrc/c65/joy_stddrv.s | 14 ++++ libsrc/c65/libref.s | 8 +++ libsrc/mega65/joy/m65-stdjoy.s | 111 ++++++++++++++++++++++++++++++++ libsrc/mega65/joy_stat_stddrv.s | 14 ++++ libsrc/mega65/joy_stddrv.s | 14 ++++ libsrc/mega65/libref.s | 8 +++ 8 files changed, 294 insertions(+) create mode 100644 libsrc/c65/joy/c65-stdjoy.s create mode 100644 libsrc/c65/joy_stat_stddrv.s create mode 100644 libsrc/c65/joy_stddrv.s create mode 100644 libsrc/c65/libref.s create mode 100644 libsrc/mega65/joy/m65-stdjoy.s create mode 100644 libsrc/mega65/joy_stat_stddrv.s create mode 100644 libsrc/mega65/joy_stddrv.s create mode 100644 libsrc/mega65/libref.s diff --git a/libsrc/c65/joy/c65-stdjoy.s b/libsrc/c65/joy/c65-stdjoy.s new file mode 100644 index 000000000..1723c916a --- /dev/null +++ b/libsrc/c65/joy/c65-stdjoy.s @@ -0,0 +1,111 @@ +; +; Standard joystick driver for the C65. May be used multiple times when linked +; to the statically application. +; +; Ullrich von Bassewitz, 2002-12-20 +; + + .include "zeropage.inc" + + .include "joy-kernel.inc" + .include "joy-error.inc" + .include "c65.inc" + + .macpack generic + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _c65_stdjoy_joy + +; Driver signature + + .byte $6A, $6F, $79 ; "joy" + .byte JOY_API_VERSION ; Driver API version number + +; Library reference + + .addr $0000 + +; Jump table. + + .addr INSTALL + .addr UNINSTALL + .addr COUNT + .addr READ + +; ------------------------------------------------------------------------ +; Constants + +JOY_COUNT = 2 ; Number of joysticks we support + + +; ------------------------------------------------------------------------ +; Data. + + +.code + +; ------------------------------------------------------------------------ +; INSTALL routine. Is called after the driver is loaded into memory. If +; possible, check if the hardware is present and determine the amount of +; memory available. +; Must return an JOY_ERR_xx code in a/x. +; + +INSTALL: + lda #JOY_ERR_OK + .assert JOY_ERR_OK = 0, error + tax + +; rts ; Run into UNINSTALL instead + +; ------------------------------------------------------------------------ +; UNINSTALL routine. Is called before the driver is removed from memory. +; Can do cleanup or whatever. Must not return anything. +; + +UNINSTALL: + rts + + +; ------------------------------------------------------------------------ +; COUNT: Return the total number of available joysticks in a/x. +; + +COUNT: + lda #<JOY_COUNT + ldx #>JOY_COUNT + rts + +; ------------------------------------------------------------------------ +; READ: Read a particular joystick passed in A. +; + +READ: tax ; Joystick number into X + bne joy2 + +; Read joystick 1 + +joy1: lda #$7F + sei + sta CIA1_PRA + lda CIA1_PRB + cli + jmp end + +; Read joystick 2 + +joy2: ldx #0 + lda #$E0 + ldy #$FF + sei + sta CIA1_DDRA + lda CIA1_PRA + sty CIA1_DDRA + cli +end: and #$1F + eor #$1F + rts diff --git a/libsrc/c65/joy_stat_stddrv.s b/libsrc/c65/joy_stat_stddrv.s new file mode 100644 index 000000000..3a4deffcd --- /dev/null +++ b/libsrc/c65/joy_stat_stddrv.s @@ -0,0 +1,14 @@ +; +; Address of the static standard joystick driver +; +; Oliver Schmidt, 2012-11-01 +; +; const void joy_static_stddrv[]; +; + + .export _joy_static_stddrv + .import _c65_stdjoy_joy + +.rodata + +_joy_static_stddrv := _c65_stdjoy_joy diff --git a/libsrc/c65/joy_stddrv.s b/libsrc/c65/joy_stddrv.s new file mode 100644 index 000000000..4232d9647 --- /dev/null +++ b/libsrc/c65/joy_stddrv.s @@ -0,0 +1,14 @@ +; +; Name of the standard joystick driver +; +; Ullrich von Bassewitz, 2002-12-21 +; +; const char joy_stddrv[]; +; + + .export _joy_stddrv + +.rodata + +_joy_stddrv: .asciiz "c65-stdjoy.joy" + diff --git a/libsrc/c65/libref.s b/libsrc/c65/libref.s new file mode 100644 index 000000000..e4afa7eb1 --- /dev/null +++ b/libsrc/c65/libref.s @@ -0,0 +1,8 @@ +; +; Oliver Schmidt, 2013-05-31 +; + + .export joy_libref + .import _exit + +joy_libref := _exit diff --git a/libsrc/mega65/joy/m65-stdjoy.s b/libsrc/mega65/joy/m65-stdjoy.s new file mode 100644 index 000000000..d266745d9 --- /dev/null +++ b/libsrc/mega65/joy/m65-stdjoy.s @@ -0,0 +1,111 @@ +; +; Standard joystick driver for the C64. May be used multiple times when linked +; to the statically application. +; +; Ullrich von Bassewitz, 2002-12-20 +; + + .include "zeropage.inc" + + .include "joy-kernel.inc" + .include "joy-error.inc" + .include "mega65.inc" + + .macpack generic + .macpack module + + +; ------------------------------------------------------------------------ +; Header. Includes jump table + + module_header _mega65_stdjoy_joy + +; Driver signature + + .byte $6A, $6F, $79 ; "joy" + .byte JOY_API_VERSION ; Driver API version number + +; Library reference + + .addr $0000 + +; Jump table. + + .addr INSTALL + .addr UNINSTALL + .addr COUNT + .addr READ + +; ------------------------------------------------------------------------ +; Constants + +JOY_COUNT = 2 ; Number of joysticks we support + + +; ------------------------------------------------------------------------ +; Data. + + +.code + +; ------------------------------------------------------------------------ +; INSTALL routine. Is called after the driver is loaded into memory. If +; possible, check if the hardware is present and determine the amount of +; memory available. +; Must return an JOY_ERR_xx code in a/x. +; + +INSTALL: + lda #JOY_ERR_OK + .assert JOY_ERR_OK = 0, error + tax + +; rts ; Run into UNINSTALL instead + +; ------------------------------------------------------------------------ +; UNINSTALL routine. Is called before the driver is removed from memory. +; Can do cleanup or whatever. Must not return anything. +; + +UNINSTALL: + rts + + +; ------------------------------------------------------------------------ +; COUNT: Return the total number of available joysticks in a/x. +; + +COUNT: + lda #<JOY_COUNT + ldx #>JOY_COUNT + rts + +; ------------------------------------------------------------------------ +; READ: Read a particular joystick passed in A. +; + +READ: tax ; Joystick number into X + bne joy2 + +; Read joystick 1 + +joy1: lda #$7F + sei + sta CIA1_PRA + lda CIA1_PRB + cli + jmp end + +; Read joystick 2 + +joy2: ldx #0 + lda #$E0 + ldy #$FF + sei + sta CIA1_DDRA + lda CIA1_PRA + sty CIA1_DDRA + cli +end: and #$1F + eor #$1F + rts diff --git a/libsrc/mega65/joy_stat_stddrv.s b/libsrc/mega65/joy_stat_stddrv.s new file mode 100644 index 000000000..492d84eb0 --- /dev/null +++ b/libsrc/mega65/joy_stat_stddrv.s @@ -0,0 +1,14 @@ +; +; Address of the static standard joystick driver +; +; Oliver Schmidt, 2012-11-01 +; +; const void joy_static_stddrv[]; +; + + .export _joy_static_stddrv + .import _mega65_stdjoy_joy + +.rodata + +_joy_static_stddrv := _mega65_stdjoy_joy diff --git a/libsrc/mega65/joy_stddrv.s b/libsrc/mega65/joy_stddrv.s new file mode 100644 index 000000000..97c7c7501 --- /dev/null +++ b/libsrc/mega65/joy_stddrv.s @@ -0,0 +1,14 @@ +; +; Name of the standard joystick driver +; +; Ullrich von Bassewitz, 2002-12-21 +; +; const char joy_stddrv[]; +; + + .export _joy_stddrv + +.rodata + +_joy_stddrv: .asciiz "m65-stdjoy.joy" + diff --git a/libsrc/mega65/libref.s b/libsrc/mega65/libref.s new file mode 100644 index 000000000..e4afa7eb1 --- /dev/null +++ b/libsrc/mega65/libref.s @@ -0,0 +1,8 @@ +; +; Oliver Schmidt, 2013-05-31 +; + + .export joy_libref + .import _exit + +joy_libref := _exit From 1b815d4148e084600513c7de2a359682e8285f79 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 25 Jun 2025 23:52:59 +0200 Subject: [PATCH 615/707] add joydemo to c65/mega65 samples, it works when driver is statically linked --- samples/Makefile | 10 ++++++++++ samples/joydemo.c | 7 +++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 6c00c97a4..267e253ff 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -108,6 +108,8 @@ DISK_apple2enh = samples.dsk DISK_atari = samples.atr DISK_atarixl = samples.atr DISK_plus4 = samples.d64 +DISK_c65 = samples.d81 +DISK_mega65 = samples.d81 # -------------------------------------------------------------------------- # System-dependent settings @@ -253,6 +255,7 @@ EXELIST_c65 = \ checkversion \ enumdevdir \ hello \ + joydemo \ sieve \ tinyshell @@ -336,6 +339,7 @@ EXELIST_mega65 = \ checkversion \ enumdevdir \ hello \ + joydemo \ sieve \ tinyshell @@ -560,6 +564,12 @@ samples.d64: samples $(foreach file,$(OVERLAYLIST),$(D64_WRITE_PRG_recipe)) $(foreach file,$(EMD) $(MOU) $(JOY) $(TGI),$(D64_WRITE_SEQ_recipe)) +samples.d81: samples + @$(C1541) -format "samples,00" d81 $@ >$(NULLDEV) + $(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_PRG_recipe)) + $(foreach file,$(OVERLAYLIST),$(D64_WRITE_PRG_recipe)) + $(foreach file,$(EMD) $(MOU) $(JOY) $(TGI),$(D64_WRITE_SEQ_recipe)) + # -------------------------------------------------------------------------- # Rule to make an Apple II disk with all samples. Needs the AppleCommander # program, available at https://applecommander.github.io/, and a template disk diff --git a/samples/joydemo.c b/samples/joydemo.c index 807c16a08..56e825541 100644 --- a/samples/joydemo.c +++ b/samples/joydemo.c @@ -3,6 +3,9 @@ #include <stdio.h> #include <joystick.h> +/* define 0 to link the standard driver statically */ +/* #define DYN_DRV 0 */ + #ifndef DYN_DRV # define DYN_DRV 1 #endif @@ -31,7 +34,7 @@ int main (void) PRINTF("Driver init..." CR); #if DYN_DRV - /* Load and initialize the driver */ + /* Load and initialize the standard driver driver */ if ((err = joy_load_driver (joy_stddrv))) { PRINTF ("Driver load error (code %d)." CR "Warning: This program needs the JOY" CR @@ -40,7 +43,7 @@ int main (void) } PRINTF("Driver loaded OK" CR); #else - /* Install the driver */ + /* Install the standard driver */ joy_install (joy_static_stddrv); #endif From 0290b276aeb58c8782f4bdc8c49c6efabc3ee915 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 01:21:28 +0200 Subject: [PATCH 616/707] fix sysuname for all targets, somehow this was forgotten --- libsrc/agat/sysuname.s | 37 ++++++++++++++++++++++++++++ libsrc/apple2/sysuname.s | 6 ++--- libsrc/atari/sysuname.s | 6 ++--- libsrc/atari5200/sysuname.s | 6 ++--- libsrc/atmos/sysuname.s | 16 +++--------- libsrc/c128/sysuname.s | 6 ++--- libsrc/c16/sysuname.s | 6 ++--- libsrc/c64/sysuname.s | 6 ++--- libsrc/cbm510/sysuname.s | 6 ++--- libsrc/cbm610/sysuname.s | 6 ++--- libsrc/creativision/sysuname.s | 6 ++--- libsrc/cx16/sysuname.s | 6 ++--- libsrc/geos-common/system/sysuname.s | 12 ++++----- libsrc/lynx/sysuname.s | 6 ++--- libsrc/nes/sysuname.s | 6 ++--- libsrc/pet/sysuname.s | 6 ++--- libsrc/plus4/sysuname.s | 6 ++--- libsrc/telestrat/sysuname.s | 16 +++--------- libsrc/vic20/sysuname.s | 6 ++--- samples/checkversion.c | 12 +++++++++ 20 files changed, 106 insertions(+), 77 deletions(-) create mode 100644 libsrc/agat/sysuname.s diff --git a/libsrc/agat/sysuname.s b/libsrc/agat/sysuname.s new file mode 100644 index 000000000..b2d2a334f --- /dev/null +++ b/libsrc/agat/sysuname.s @@ -0,0 +1,37 @@ +; +; Ullrich von Bassewitz, 2003-08-12 +; +; unsigned char __fastcall__ _sysuname (struct utsname* buf); +; + + .export __sysuname, utsdata + + .import utscopy + + __sysuname = utscopy + +;-------------------------------------------------------------------------- +; Data. We define a fixed utsname struct here and just copy it. + +.rodata + +utsdata: + ; sysname + .asciiz "cc65" + + ; nodename + .asciiz "" + + ; release + .byte .string (>.version) + .byte '.' + .byte .string (<.version) + .byte $00 + + ; version + .byte '0' ; unused + .byte $00 + + ; machine + .asciiz "Agat" + diff --git a/libsrc/apple2/sysuname.s b/libsrc/apple2/sysuname.s index cd41eac29..52a7ec7e1 100644 --- a/libsrc/apple2/sysuname.s +++ b/libsrc/apple2/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/atari/sysuname.s b/libsrc/atari/sysuname.s index 25a891a1b..893ebcfdc 100644 --- a/libsrc/atari/sysuname.s +++ b/libsrc/atari/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/atari5200/sysuname.s b/libsrc/atari5200/sysuname.s index 7fd9281a1..5a75edf04 100644 --- a/libsrc/atari5200/sysuname.s +++ b/libsrc/atari5200/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/atmos/sysuname.s b/libsrc/atmos/sysuname.s index 546f942ab..7e7bd2341 100644 --- a/libsrc/atmos/sysuname.s +++ b/libsrc/atmos/sysuname.s @@ -23,23 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .if ((.VERSION >> 4) & $0F) > 9 - .byte ((.VERSION >> 4) & $0F) / 10 + '0' - .byte ((.VERSION >> 4) & $0F) .MOD 10 + '0' - .else - .byte ((.VERSION >> 4) & $0F) + '0' - .endif + .byte .string (<.version) .byte $00 ; version - .if (.VERSION & $0F) > 9 - .byte (.VERSION & $0F) / 10 + '0' - .byte (.VERSION & $0F) .MOD 10 + '0' - .else - .byte (.VERSION & $0F) + '0' - .endif + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/c128/sysuname.s b/libsrc/c128/sysuname.s index 55fe5ba28..b7c7794b5 100644 --- a/libsrc/c128/sysuname.s +++ b/libsrc/c128/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/c16/sysuname.s b/libsrc/c16/sysuname.s index c44ab6acc..960509866 100644 --- a/libsrc/c16/sysuname.s +++ b/libsrc/c16/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/c64/sysuname.s b/libsrc/c64/sysuname.s index 1903986c9..1f6cfc410 100644 --- a/libsrc/c64/sysuname.s +++ b/libsrc/c64/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/cbm510/sysuname.s b/libsrc/cbm510/sysuname.s index 24d4dc03b..579908d19 100644 --- a/libsrc/cbm510/sysuname.s +++ b/libsrc/cbm510/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/cbm610/sysuname.s b/libsrc/cbm610/sysuname.s index 984cb93df..dab807a4f 100644 --- a/libsrc/cbm610/sysuname.s +++ b/libsrc/cbm610/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/creativision/sysuname.s b/libsrc/creativision/sysuname.s index 725cb2a62..43a0c7659 100644 --- a/libsrc/creativision/sysuname.s +++ b/libsrc/creativision/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/cx16/sysuname.s b/libsrc/cx16/sysuname.s index 4aefb7cf5..06f4d7662 100644 --- a/libsrc/cx16/sysuname.s +++ b/libsrc/cx16/sysuname.s @@ -24,13 +24,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/geos-common/system/sysuname.s b/libsrc/geos-common/system/sysuname.s index 8eac05941..954e5be5e 100644 --- a/libsrc/geos-common/system/sysuname.s +++ b/libsrc/geos-common/system/sysuname.s @@ -22,14 +22,14 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' - .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' - .byte $00 + .byte .string (>.version) + .byte '.' + .byte .string (<.version) + .byte $00 ; version - .byte (.VERSION & $0F) + '0' - .byte $00 + .byte '0' ; unused + .byte $00 ; machine .asciiz "GEOS" diff --git a/libsrc/lynx/sysuname.s b/libsrc/lynx/sysuname.s index 879297ea4..3c75fac08 100644 --- a/libsrc/lynx/sysuname.s +++ b/libsrc/lynx/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/nes/sysuname.s b/libsrc/nes/sysuname.s index fcab503e1..7e72df358 100644 --- a/libsrc/nes/sysuname.s +++ b/libsrc/nes/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/pet/sysuname.s b/libsrc/pet/sysuname.s index 59174d821..ddc7d644f 100644 --- a/libsrc/pet/sysuname.s +++ b/libsrc/pet/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/plus4/sysuname.s b/libsrc/plus4/sysuname.s index 332daae0d..e75e6cacc 100644 --- a/libsrc/plus4/sysuname.s +++ b/libsrc/plus4/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/telestrat/sysuname.s b/libsrc/telestrat/sysuname.s index 51af1d8fe..09aaff831 100644 --- a/libsrc/telestrat/sysuname.s +++ b/libsrc/telestrat/sysuname.s @@ -23,23 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .if ((.VERSION >> 4) & $0F) > 9 - .byte ((.VERSION >> 4) & $0F) / 10 + '0' - .byte ((.VERSION >> 4) & $0F) .MOD 10 + '0' - .else - .byte ((.VERSION >> 4) & $0F) + '0' - .endif + .byte .string (<.version) .byte $00 ; version - .if (.VERSION & $0F) > 9 - .byte (.VERSION & $0F) / 10 + '0' - .byte (.VERSION & $0F) .MOD 10 + '0' - .else - .byte (.VERSION & $0F) + '0' - .endif + .byte '0' ; unused .byte $00 ; machine diff --git a/libsrc/vic20/sysuname.s b/libsrc/vic20/sysuname.s index 18d5db9a9..43ee37896 100644 --- a/libsrc/vic20/sysuname.s +++ b/libsrc/vic20/sysuname.s @@ -23,13 +23,13 @@ utsdata: .asciiz "" ; release - .byte ((.VERSION >> 8) & $0F) + '0' + .byte .string (>.version) .byte '.' - .byte ((.VERSION >> 4) & $0F) + '0' + .byte .string (<.version) .byte $00 ; version - .byte (.VERSION & $0F) + '0' + .byte '0' ; unused .byte $00 ; machine diff --git a/samples/checkversion.c b/samples/checkversion.c index f2a9d4a49..9d88cecd3 100644 --- a/samples/checkversion.c +++ b/samples/checkversion.c @@ -9,6 +9,7 @@ #include <stdio.h> #include <stdlib.h> +#include <sys/utsname.h> #if ((__CC65__ >> 8) > 3) || ((__CC65__ & 0x000f) > 0) /* compiler version is 2.19-git or higher */ @@ -29,6 +30,17 @@ int main(void) { +#if !defined(__SIM6502__) && !defined(__SIM65C02__) && !defined(__AGAT__) + struct utsname buf; + uname (&buf); + + printf("utsname.sysname: %s\n", buf.sysname); + printf("utsname.nodename: %s\n", buf.nodename); + printf("utsname.release: %s\n", buf.release); + printf("utsname.version: %s\n", buf.version); + printf("utsname.machine: %s\n", buf.machine); +#endif + printf("__CC65__ defined as %04x\n", __CC65__); printf("compiler version is %u.%u\n", VER_MAJOR, VER_MINOR); if (__CC65__ == VERSION) { From 8bf6bb606c1a0b21fedab6ac4e332dab6df0ed96 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 01:34:32 +0200 Subject: [PATCH 617/707] make sure "make platforms" actually checks all targets --- samples/Makefile | 16 +++++++++++++--- samples/tutorial/Makefile | 3 +++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index 0a56af3c1..dc0ea8f9f 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -213,6 +213,9 @@ EXELIST_atari2600 = \ EXELIST_atari5200 = \ notavailable +EXELIST_atari7800 = \ + notavailable + EXELIST_atmos = \ ascii \ checkversion \ @@ -299,9 +302,7 @@ EXELIST_gamate = \ hello EXELIST_geos-cbm = \ - ascii \ - checkversion \ - diodemo + ascii EXELIST_geos-apple = \ ascii @@ -347,6 +348,9 @@ EXELIST_sim6502 = \ EXELIST_sim65c02 = $(EXELIST_sim6502) +EXELIST_rp6502 = \ + notavailable + EXELIST_supervision = \ notavailable @@ -413,6 +417,7 @@ TARGETS := \ atarixl \ atari2600 \ atari5200 \ + atari7800 \ atmos \ bbc \ c128 \ @@ -423,6 +428,8 @@ TARGETS := \ creativision \ cx16 \ gamate \ + geos-apple \ + geos-cbm \ kim1 \ lunix \ lynx \ @@ -431,6 +438,7 @@ TARGETS := \ pce \ pet \ plus4 \ + rp6502 \ sim6502 \ sim65c02 \ supervision \ @@ -438,12 +446,14 @@ TARGETS := \ telestrat \ vic20 + # -------------------------------------------------------------------------- # Rule to make the binaries for every platform define TARGET_recipe @echo making samples for: $(T) +@$(MAKE) --no-print-directory clean SYS:=$(T) @$(MAKE) -j2 SYS:=$(T) @$(MAKE) --no-print-directory clean SYS:=$(T) diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile index 7b3286e27..685c8dd69 100644 --- a/samples/tutorial/Makefile +++ b/samples/tutorial/Makefile @@ -43,6 +43,9 @@ EXELIST_atari2600 = \ EXELIST_atari5200 = \ notavailable +EXELIST_atari7800 = \ + notavailable + EXELIST_bbc = \ notavailable From b1a123b601a6ac42d7c0c7754101b876d072a35d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 02:10:15 +0200 Subject: [PATCH 618/707] fix c65 lib, remove includes from cbm generic lib --- libsrc/c65/cpeekrevers.s | 28 ++++++++++++++++++++++++++++ libsrc/c65/cputc.s | 1 - libsrc/cbm/cpeekrevers.s | 4 ---- 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 libsrc/c65/cpeekrevers.s diff --git a/libsrc/c65/cpeekrevers.s b/libsrc/c65/cpeekrevers.s new file mode 100644 index 000000000..4fef17340 --- /dev/null +++ b/libsrc/c65/cpeekrevers.s @@ -0,0 +1,28 @@ +; +; 2016-02-28, Groepaz +; 2017-06-15, Greg King +; +; unsigned char cpeekrevers (void); +; + + .include "c65.inc" + + .export _cpeekrevers + .importzp ptr1 + +_cpeekrevers: + lda SCREEN_PTR + 1 + clc + adc #>$0800 + sta ptr1 + 1 + lda SCREEN_PTR + sta ptr1 + + ldy CURS_X + lda (ptr1),y ; get screen code + and #$80 ; get reverse bit + asl a + tax ; ldx #>$0000 + rol a ; return boolean value + + rts diff --git a/libsrc/c65/cputc.s b/libsrc/c65/cputc.s index d9f63c1dd..1a8dd1fee 100644 --- a/libsrc/c65/cputc.s +++ b/libsrc/c65/cputc.s @@ -13,7 +13,6 @@ .include "c65.inc" - _cputcxy: pha ; Save C jsr gotoxy ; Set cursor, drop x and y diff --git a/libsrc/cbm/cpeekrevers.s b/libsrc/cbm/cpeekrevers.s index 0e500605d..e8e210167 100644 --- a/libsrc/cbm/cpeekrevers.s +++ b/libsrc/cbm/cpeekrevers.s @@ -22,10 +22,6 @@ .include "pet.inc" .elseif .def(__VIC20__) .include "vic20.inc" -.elseif .def(__C65__) - .include "c65.inc" -.elseif .def(__MEGA65__) - .include "mega65.inc" .endif From 2de056167a8e0935a8b64e7819821951343344c3 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 02:16:05 +0200 Subject: [PATCH 619/707] fix warnings --- samples/checkversion.c | 2 ++ samples/joydemo.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/samples/checkversion.c b/samples/checkversion.c index 9d88cecd3..0e2359f91 100644 --- a/samples/checkversion.c +++ b/samples/checkversion.c @@ -43,10 +43,12 @@ int main(void) printf("__CC65__ defined as %04x\n", __CC65__); printf("compiler version is %u.%u\n", VER_MAJOR, VER_MINOR); +#pragma warn (const-comparison, push, off) if (__CC65__ == VERSION) { printf("__CC65__ is defined correctly as (VER_MAJOR * 0x100) + VER_MINOR\n"); return EXIT_SUCCESS; } +#pragma warn (const-comparison, pop) printf("__CC65__ is incorrectly defined as (VER_MAJOR * 0x100) + (VER_MINOR * 0x10)\n"); return EXIT_FAILURE; } diff --git a/samples/joydemo.c b/samples/joydemo.c index 56e825541..7375f23d3 100644 --- a/samples/joydemo.c +++ b/samples/joydemo.c @@ -26,9 +26,11 @@ int main (void) unsigned char num_joy; unsigned char raw_value; unsigned char i; +#if DYN_DRV unsigned char err; - unsigned char y; +#endif #ifdef USECONIO + unsigned char y; clrscr(); #endif PRINTF("Driver init..." CR); From 5db2aed1297e7590beb35c43fa5ae40c44e2b686 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 26 Jun 2025 07:40:04 +0200 Subject: [PATCH 620/707] Allow "sp" as an alias for "c_sp" for backwards compatibility. Using it will work but generates a linker warning. Added a test to check for this warning. --- asminc/zeropage.inc | 6 ++++++ libsrc/runtime/sp-compat.s | 11 +++++++++++ test/asm/listing/ref/sp-compat.ld65err2-ref | 1 + test/asm/listing/sp-compat.s | 7 +++++++ 4 files changed, 25 insertions(+) create mode 100644 libsrc/runtime/sp-compat.s create mode 100644 test/asm/listing/ref/sp-compat.ld65err2-ref create mode 100644 test/asm/listing/sp-compat.s diff --git a/asminc/zeropage.inc b/asminc/zeropage.inc index 5285779ba..2d4b144db 100644 --- a/asminc/zeropage.inc +++ b/asminc/zeropage.inc @@ -13,6 +13,12 @@ .globalzp tmp1, tmp2, tmp3, tmp4 .globalzp regbank + ; The following symbol is supplied for compatibility reasons only, it + ; will get removed in future versions. Using it will cause a linker + ; warning. + .globalzp sp + + ; The size of the register bank regbanksize = 6 diff --git a/libsrc/runtime/sp-compat.s b/libsrc/runtime/sp-compat.s new file mode 100644 index 000000000..797fef47b --- /dev/null +++ b/libsrc/runtime/sp-compat.s @@ -0,0 +1,11 @@ +; +; Kugelfuhr, 2025-06-26 +; +; Add "sp" as an alias for "c_sp" so we don't break old code but emit a +; linker warning if it is used. Added after renaming "sp" to "c_sp". +; + +.include "zeropage.inc" +.export sp := c_sp +.assert 0, ldwarning, "Symbol 'sp' is deprecated - please use 'c_sp' instead" + diff --git a/test/asm/listing/ref/sp-compat.ld65err2-ref b/test/asm/listing/ref/sp-compat.ld65err2-ref new file mode 100644 index 000000000..fe2611088 --- /dev/null +++ b/test/asm/listing/ref/sp-compat.ld65err2-ref @@ -0,0 +1 @@ +ld65: Warning: runtime/sp-compat.s:10: Symbol 'sp' is deprecated - please use 'c_sp' instead diff --git a/test/asm/listing/sp-compat.s b/test/asm/listing/sp-compat.s new file mode 100644 index 000000000..8c22a71d3 --- /dev/null +++ b/test/asm/listing/sp-compat.s @@ -0,0 +1,7 @@ +.include "zeropage.inc" + +.proc _func + ldy #0 + lda (sp),y + rts +.endproc From 399f5aaab7ebab11f8f878641389e59224adad7d Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 26 Jun 2025 08:23:51 +0200 Subject: [PATCH 621/707] Check that there are no library modules that use the old "sp" symbol instead of "c_sp". --- .github/checks/Makefile | 3 +++ .github/checks/checksp.sh | 22 +++++++++++++++++++++ .github/workflows/build-on-pull-request.yml | 3 +++ Makefile | 4 ++++ 4 files changed, 32 insertions(+) create mode 100755 .github/checks/checksp.sh diff --git a/.github/checks/Makefile b/.github/checks/Makefile index ee373d53d..7fc51d8d4 100644 --- a/.github/checks/Makefile +++ b/.github/checks/Makefile @@ -40,4 +40,7 @@ sorted: sorted.sh sorted_codeopt.sh sorted_opcodes.sh @./sorted_codeopt.sh @./sorted_opcodes.sh +checksp: checksp.sh + @./checksp.sh + endif diff --git a/.github/checks/checksp.sh b/.github/checks/checksp.sh new file mode 100755 index 000000000..f70d92e25 --- /dev/null +++ b/.github/checks/checksp.sh @@ -0,0 +1,22 @@ +#! /bin/bash +OD65_EXE=../bin/od65 +CHECK_PATH=../../libwrk + +cd "${CHECK_PATH}" || { + echo "error: Directory ${CHECK_PATH} doesn't seem to exist" >&2 + exit 1 +} + +[ -x "${OD65_EXE}" ] || { + echo "error: This check requires the od65 executable to be built" >&2 + exit 1 +} + +EXITCODE=0 +find . -name \*.o -print | while read OBJ; do + "${OD65_EXE}" --dump-imports "${OBJ}" | grep -q "\"sp\"" && { + echo "error: Usage of symbol 'sp' found in module ${OBJ}" >&2 + EXITCODE=1 + } +done +exit ${EXITCODE} diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index af79733cf..b577e4b03 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -39,6 +39,9 @@ jobs: - name: Build the platform libraries. shell: bash run: make -j2 lib QUIET=1 + - name: check test that no modules use sp + shell: bash + run: make -j2 checksp QUIET=1 - name: Run the regression tests. shell: bash run: make -j2 test QUIET=1 diff --git a/Makefile b/Makefile index 13e965c9e..21c1b3208 100644 --- a/Makefile +++ b/Makefile @@ -53,6 +53,10 @@ checkstyle: sorted: @$(MAKE) -C .github/checks --no-print-directory $@ +# check that no modules use "sp", requires the binaries to be built first +checksp: + @$(MAKE) -C .github/checks --no-print-directory $@ + # runs regression tests, requires libtest target libraries test: @$(MAKE) -C test --no-print-directory $@ From e2a39d076d8b5f337a78c4b7871ca6355b28e1a6 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 26 Jun 2025 09:00:03 +0200 Subject: [PATCH 622/707] Renamed the assembler test. --- test/asm/listing/{sp-compat.s => 080-sp-compat.s} | 0 .../ref/{sp-compat.ld65err2-ref => 080-sp-compat.ld65err2-ref} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test/asm/listing/{sp-compat.s => 080-sp-compat.s} (100%) rename test/asm/listing/ref/{sp-compat.ld65err2-ref => 080-sp-compat.ld65err2-ref} (100%) diff --git a/test/asm/listing/sp-compat.s b/test/asm/listing/080-sp-compat.s similarity index 100% rename from test/asm/listing/sp-compat.s rename to test/asm/listing/080-sp-compat.s diff --git a/test/asm/listing/ref/sp-compat.ld65err2-ref b/test/asm/listing/ref/080-sp-compat.ld65err2-ref similarity index 100% rename from test/asm/listing/ref/sp-compat.ld65err2-ref rename to test/asm/listing/ref/080-sp-compat.ld65err2-ref From d5e7c94eb2549f4475221d5622ca17df3d59ea59 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 26 Jun 2025 10:10:11 +0200 Subject: [PATCH 623/707] Introduce an optimization for (header) files containing include guards: If such an include guard exists, the file is not read and parsed multiple times (as before) but duplicate inclusion is detected before opening the file and the additional overhead is avoided. --- src/cc65/input.c | 74 +++++------ src/cc65/input.h | 22 +++ src/cc65/preproc.c | 325 ++++++++++++++++++++++++++++----------------- src/cc65/preproc.h | 33 +++-- 4 files changed, 278 insertions(+), 176 deletions(-) diff --git a/src/cc65/input.c b/src/cc65/input.c index fcf7f32f3..4faf2aa87 100644 --- a/src/cc65/input.c +++ b/src/cc65/input.c @@ -40,6 +40,7 @@ /* common */ #include "check.h" #include "coll.h" +#include "debugflag.h" #include "filestat.h" #include "fname.h" #include "print.h" @@ -77,17 +78,6 @@ char NextC = '\0'; /* Maximum count of nested includes */ #define MAX_INC_NESTING 16 -/* Struct that describes an input file */ -typedef struct IFile IFile; -struct IFile { - unsigned Index; /* File index */ - unsigned Usage; /* Usage counter */ - unsigned long Size; /* File size */ - unsigned long MTime; /* Time of last modification */ - InputType Type; /* Type of input file */ - char Name[1]; /* Name of file (dynamically allocated) */ -}; - /* Struct that describes an active input file */ typedef struct AFile AFile; struct AFile { @@ -132,11 +122,13 @@ static IFile* NewIFile (const char* Name, InputType Type) IFile* IF = (IFile*) xmalloc (sizeof (IFile) + Len); /* Initialize the fields */ - IF->Index = CollCount (&IFiles) + 1; - IF->Usage = 0; - IF->Size = 0; - IF->MTime = 0; - IF->Type = Type; + IF->Index = CollCount (&IFiles) + 1; + IF->Usage = 0; + IF->Size = 0; + IF->MTime = 0; + IF->Type = Type; + IF->GFlags = IG_NONE; + SB_Init (&IF->GuardMacro); memcpy (IF->Name, Name, Len+1); /* Insert the new structure into the IFile collection */ @@ -280,7 +272,7 @@ void OpenMainFile (const char* Name) SetPPIfStack (&MainFile->IfStack); /* Begin PP for this file */ - PreprocessBegin (); + PreprocessBegin (IF); /* Allocate the input line buffer */ Line = NewStrBuf (); @@ -318,11 +310,21 @@ void OpenIncludeFile (const char* Name, InputType IT) } /* Search the list of all input files for this file. If we don't find - ** it, create a new IFile object. + ** it, create a new IFile object. If we do already know the file and it + ** has an include guard, check for the include guard before opening the + ** file. */ IF = FindFile (N); if (IF == 0) { IF = NewIFile (N, IT); + } else if ((IF->GFlags & IG_ISGUARDED) != 0 && + IsMacro (SB_GetConstBuf (&IF->GuardMacro))) { + if (Debug) { + printf ("Include guard %s found for \"%s\" - won't include it again\n", + SB_GetConstBuf (&IF->GuardMacro), + Name); + } + return; } /* We don't need N any longer, since we may now use IF->Name */ @@ -346,7 +348,7 @@ void OpenIncludeFile (const char* Name, InputType IT) SetPPIfStack (&AF->IfStack); /* Begin PP for this file */ - PreprocessBegin (); + PreprocessBegin (IF); } @@ -356,27 +358,24 @@ void CloseIncludeFile (void) ** NULL if this was the main file. */ { - AFile* Input; + /* Get the currently active input file and remove it from set of active + ** files. CollPop will FAIL if the collection is empty so no need to + ** check this here. + */ + AFile* Input = CollPop (&AFiles); - /* Get the number of active input files */ - unsigned AFileCount = CollCount (&AFiles); + /* Determine the file that is active after closing this one. We never + ** actually close the main file, since it is needed for errors found after + ** compilation is completed. + */ + AFile* NextInput = (CollCount (&AFiles) > 0)? CollLast (&AFiles) : Input; - /* Must have an input file when called */ - PRECONDITION (AFileCount > 0); - - /* End preprocessor in this file */ - PreprocessEnd (); - - /* Get the current active input file */ - Input = CollLast (&AFiles); + /* End preprocessing for the current input file */ + PreprocessEnd (NextInput->Input); /* Close the current input file (we're just reading so no error check) */ fclose (Input->F); - /* Delete the last active file from the active file collection */ - --AFileCount; - CollDelete (&AFiles, AFileCount); - /* If we had added an extra search path for this AFile, remove it */ if (Input->SearchPath) { PopSearchPath (UsrIncSearchPath); @@ -385,10 +384,9 @@ void CloseIncludeFile (void) /* Delete the active file structure */ FreeAFile (Input); - /* Use previous file with PP if it is not the main file */ - if (AFileCount > 0) { - Input = CollLast (&AFiles); - SetPPIfStack (&Input->IfStack); + /* If we've switched files, use the if stack from the previous file */ + if (Input != NextInput) { + SetPPIfStack (&NextInput->IfStack); } } diff --git a/src/cc65/input.h b/src/cc65/input.h index 9a5a76949..5d7d051e8 100644 --- a/src/cc65/input.h +++ b/src/cc65/input.h @@ -65,6 +65,28 @@ typedef enum { IT_USRINC = 0x04, /* User include file (using "") */ } InputType; +/* A bitmapped set of flags for include guard processing in the preprocessor */ +typedef enum { + IG_NONE = 0x00, + IG_NEWFILE = 0x01, /* File processing started */ + IG_ISGUARDED = 0x02, /* File contains an include guard */ + IG_GUARDCLOSED = 0x04, /* Include guard was closed */ + IG_COMPLETE = IG_ISGUARDED | IG_GUARDCLOSED, +} GuardFlags; + +/* Struct that describes an input file */ +typedef struct IFile IFile; +struct IFile { + unsigned Index; /* File index */ + unsigned Usage; /* Usage counter */ + unsigned long Size; /* File size */ + unsigned long MTime; /* Time of last modification */ + InputType Type; /* Type of input file */ + GuardFlags GFlags; /* Flags for include guard processing */ + StrBuf GuardMacro; /* Include guard macro name */ + char Name[1]; /* Name of file (dynamically allocated) */ +}; + /* The current input line */ extern StrBuf* Line; diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index 65db5ea57..bc21a69d1 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -93,6 +93,10 @@ #define IFCOND_SKIP 0x01U #define IFCOND_ELSE 0x02U #define IFCOND_NEEDTERM 0x04U +#define IFCOND_ISGUARD 0x08U + +/* Current input file */ +static IFile* CurInput = 0; /* Current PP if stack */ static PPIfStack* PPStack; @@ -2701,7 +2705,7 @@ Error_Handler: -static int PushIf (int Skip, int Invert, int Cond) +static int PushIf (int Skip, int Invert, int Cond, unsigned Flags) /* Push a new if level onto the if stack */ { /* Check for an overflow of the if stack */ @@ -2713,10 +2717,10 @@ static int PushIf (int Skip, int Invert, int Cond) /* Push the #if condition */ ++PPStack->Index; if (Skip) { - PPStack->Stack[PPStack->Index] = IFCOND_SKIP | IFCOND_NEEDTERM; + PPStack->Stack[PPStack->Index] = IFCOND_SKIP | IFCOND_NEEDTERM | Flags; return 1; } else { - PPStack->Stack[PPStack->Index] = IFCOND_NONE | IFCOND_NEEDTERM; + PPStack->Stack[PPStack->Index] = IFCOND_NONE | IFCOND_NEEDTERM | Flags; return (Invert ^ Cond); } } @@ -2794,29 +2798,40 @@ static int DoIf (int Skip) } /* Set the #if condition according to the expression result */ - return PushIf (Skip, 1, Expr.IVal != 0); + return PushIf (Skip, 1, Expr.IVal != 0, IFCOND_NONE); } -static int DoIfDef (int skip, int flag) -/* Process #ifdef if flag == 1, or #ifndef if flag == 0. */ +static int DoIfDef (int Skip, int Flag) +/* Process #ifdef if Flag == 1, or #ifndef if Flag == 0. */ { - int Value = 0; + int IsDef = 0; + unsigned GuardFlag = IFCOND_NONE; - if (!skip) { + if (!Skip) { ident Ident; SkipWhitespace (0); if (MacName (Ident)) { CheckForBadIdent (Ident, IS_Get (&Standard), 0); - Value = IsMacro (Ident); + IsDef = IsMacro (Ident); /* Check for extra tokens */ - CheckExtraTokens (flag ? "ifdef" : "ifndef"); + CheckExtraTokens (Flag ? "ifdef" : "ifndef"); + /* Check if this is an include guard. This is the case if we have + ** a #ifndef directive at the start of a new file and the macro + ** is not defined. If so, remember it. + */ + if (Flag == 0 && (CurInput->GFlags & IG_NEWFILE) != 0 && !IsDef) { + CurInput->GFlags |= IG_ISGUARDED; + SB_CopyStr (&CurInput->GuardMacro, Ident); + SB_Terminate (&CurInput->GuardMacro); + GuardFlag = IFCOND_ISGUARD; + } } } - return PushIf (skip, flag, Value); + return PushIf (Skip, Flag, IsDef, GuardFlag); } @@ -3070,18 +3085,31 @@ static int ParseDirectives (unsigned ModeFlags) int PPSkip = 0; ident Directive; - /* Skip white space at the beginning of the first line */ + /* Skip white space at the beginning of the line */ int Whitespace = SkipWhitespace (0); /* Check for stuff to skip */ while (CurC == '\0' || CurC == '#' || PPSkip) { + /* If a #ifndef that was assumed to be an include guard was closed + ** recently, we may not have anything else following in the file + ** besides whitespace otherwise the assumption was false and we don't + ** actually have an include guard. + */ + if (CurC != '\0' && (CurInput->GFlags & IG_COMPLETE) == IG_COMPLETE) { + CurInput->GFlags &= ~IG_ISGUARDED; + } + /* Check for preprocessor lines lines */ if (CurC == '#') { + unsigned IfCond; + /* Skip the hash and following white space */ NextChar (); SkipWhitespace (0); + if (CurC == '\0') { /* Ignore the empty preprocessor directive */ + CurInput->GFlags &= ~IG_NEWFILE; continue; } if (!IsSym (Directive)) { @@ -3089,145 +3117,175 @@ static int ParseDirectives (unsigned ModeFlags) PPError ("Preprocessor directive expected"); } ClearLine (); - } else { - switch (FindPPDirectiveType (Directive)) { + CurInput->GFlags &= ~IG_NEWFILE; + continue; + } + switch (FindPPDirectiveType (Directive)) { - case PPD_DEFINE: - if (!PPSkip) { - DoDefine (); - } - break; + case PPD_DEFINE: + CurInput->GFlags &= ~IG_NEWFILE; + if (!PPSkip) { + DoDefine (); + } + break; - case PPD_ELIF: - if (PPStack->Index >= 0) { - if ((PPStack->Stack[PPStack->Index] & IFCOND_ELSE) == 0) { - /* Handle as #else/#if combination */ - if ((PPStack->Stack[PPStack->Index] & IFCOND_SKIP) == 0) { - PPSkip = !PPSkip; - } - PPStack->Stack[PPStack->Index] |= IFCOND_ELSE; - PPSkip = DoIf (PPSkip); + case PPD_ELIF: + CurInput->GFlags &= ~IG_NEWFILE; + if (PPStack->Index >= 0) { + unsigned char PPCond = PPStack->Stack[PPStack->Index]; + if ((PPCond & IFCOND_ELSE) == 0) { + /* Handle as #else/#if combination */ + if ((PPCond & IFCOND_SKIP) == 0) { + PPSkip = !PPSkip; + } + PPStack->Stack[PPStack->Index] |= IFCOND_ELSE; + PPSkip = DoIf (PPSkip); - /* #elif doesn't need a terminator */ - PPStack->Stack[PPStack->Index] &= ~IFCOND_NEEDTERM; - } else { - PPError ("Duplicate #else/#elif"); + /* #elif doesn't need a terminator */ + PPStack->Stack[PPStack->Index] &= ~IFCOND_NEEDTERM; + + /* An include guard cannot have a #elif */ + if (PPCond & IFCOND_ISGUARD) { + CurInput->GFlags &= ~IG_ISGUARDED; } } else { - PPError ("Unexpected #elif"); + PPError ("Duplicate #else/#elif"); } - break; + } else { + PPError ("Unexpected #elif"); + } + break; - case PPD_ELSE: - if (PPStack->Index >= 0) { - if ((PPStack->Stack[PPStack->Index] & IFCOND_ELSE) == 0) { - if ((PPStack->Stack[PPStack->Index] & IFCOND_SKIP) == 0) { - PPSkip = !PPSkip; - } - PPStack->Stack[PPStack->Index] |= IFCOND_ELSE; - - /* Check for extra tokens */ - CheckExtraTokens ("else"); - } else { - PPError ("Duplicate #else"); + case PPD_ELSE: + CurInput->GFlags &= ~IG_NEWFILE; + if (PPStack->Index >= 0) { + unsigned char PPCond = PPStack->Stack[PPStack->Index]; + if ((PPCond & IFCOND_ELSE) == 0) { + if ((PPCond & IFCOND_SKIP) == 0) { + PPSkip = !PPSkip; } - } else { - PPError ("Unexpected '#else'"); - } - break; + PPStack->Stack[PPStack->Index] |= IFCOND_ELSE; - case PPD_ENDIF: - if (PPStack->Index >= 0) { - /* Remove any clauses on top of stack that do not - ** need a terminating #endif. - */ - while (PPStack->Index >= 0 && - (PPStack->Stack[PPStack->Index] & IFCOND_NEEDTERM) == 0) { - --PPStack->Index; + /* An include guard cannot have a #else */ + if (PPCond & IFCOND_ISGUARD) { + CurInput->GFlags &= ~IG_ISGUARDED; } - /* Stack may not be empty here or something is wrong */ - CHECK (PPStack->Index >= 0); - - /* Remove the clause that needs a terminator */ - PPSkip = (PPStack->Stack[PPStack->Index--] & IFCOND_SKIP) != 0; - /* Check for extra tokens */ - CheckExtraTokens ("endif"); + CheckExtraTokens ("else"); } else { - PPError ("Unexpected '#endif'"); + PPError ("Duplicate #else"); } - break; + } else { + PPError ("Unexpected '#else'"); + } + break; - case PPD_ERROR: - if (!PPSkip) { - DoError (); + case PPD_ENDIF: + CurInput->GFlags &= ~IG_NEWFILE; + if (PPStack->Index >= 0) { + /* Remove any clauses on top of stack that do not + ** need a terminating #endif. + */ + while (PPStack->Index >= 0 && + (PPStack->Stack[PPStack->Index] & IFCOND_NEEDTERM) == 0) { + --PPStack->Index; } - break; - case PPD_IF: - PPSkip = DoIf (PPSkip); - break; + /* Stack may not be empty here or something is wrong */ + CHECK (PPStack->Index >= 0); - case PPD_IFDEF: - PPSkip = DoIfDef (PPSkip, 1); - break; - - case PPD_IFNDEF: - PPSkip = DoIfDef (PPSkip, 0); - break; - - case PPD_INCLUDE: - if (!PPSkip) { - DoInclude (); + /* Remove the clause that needs a terminator */ + IfCond = PPStack->Stack[PPStack->Index--]; + PPSkip = (IfCond & IFCOND_SKIP) != 0; + if (IfCond & IFCOND_ISGUARD) { + CurInput->GFlags |= IG_GUARDCLOSED; } - break; - case PPD_LINE: - if (!PPSkip) { - DoLine (); - } - break; + /* Check for extra tokens */ + CheckExtraTokens ("endif"); + } else { + PPError ("Unexpected '#endif'"); + } + break; - case PPD_PRAGMA: - if (!PPSkip) { - if ((ModeFlags & MSM_IN_ARG_LIST) == 0) { - DoPragma (); - return Whitespace; - } else { - PPError ("Embedded #pragma directive within macro arguments is unsupported"); - } - } - break; + case PPD_ERROR: + CurInput->GFlags &= ~IG_NEWFILE; + if (!PPSkip) { + DoError (); + } + break; - case PPD_UNDEF: - if (!PPSkip) { - DoUndef (); - } - break; + case PPD_IF: + CurInput->GFlags &= ~IG_NEWFILE; + PPSkip = DoIf (PPSkip); + break; - case PPD_WARNING: - /* #warning is a non standard extension */ - if (IS_Get (&Standard) > STD_C99) { - if (!PPSkip) { - DoWarning (); - } + case PPD_IFDEF: + CurInput->GFlags &= ~IG_NEWFILE; + PPSkip = DoIfDef (PPSkip, 1); + break; + + case PPD_IFNDEF: + PPSkip = DoIfDef (PPSkip, 0); + CurInput->GFlags &= ~IG_NEWFILE; + break; + + case PPD_INCLUDE: + CurInput->GFlags &= ~IG_NEWFILE; + if (!PPSkip) { + DoInclude (); + } + break; + + case PPD_LINE: + CurInput->GFlags &= ~IG_NEWFILE; + if (!PPSkip) { + DoLine (); + } + break; + + case PPD_PRAGMA: + CurInput->GFlags &= ~IG_NEWFILE; + if (!PPSkip) { + if ((ModeFlags & MSM_IN_ARG_LIST) == 0) { + DoPragma (); + return Whitespace; } else { - if (!PPSkip) { - PPError ("Preprocessor directive expected"); - } - ClearLine (); + PPError ("Embedded #pragma directive within macro arguments is unsupported"); } - break; + } + break; - default: + case PPD_UNDEF: + CurInput->GFlags &= ~IG_NEWFILE; + if (!PPSkip) { + DoUndef (); + } + break; + + case PPD_WARNING: + CurInput->GFlags &= ~IG_NEWFILE; + /* #warning is a non standard extension */ + if (IS_Get (&Standard) > STD_C99) { + if (!PPSkip) { + DoWarning (); + } + } else { if (!PPSkip) { PPError ("Preprocessor directive expected"); } ClearLine (); - } - } + } + break; + default: + CurInput->GFlags &= ~IG_NEWFILE; + if (!PPSkip) { + PPError ("Preprocessor directive expected"); + } + ClearLine (); + } } if (NextLine () == 0) { break; @@ -3236,6 +3294,15 @@ static int ParseDirectives (unsigned ModeFlags) Whitespace = SkipWhitespace (0) || Whitespace; } + /* If a #ifndef that was assumed to be an include guard was closed + ** recently, we may not have anything else following in the file + ** besides whitespace otherwise the assumption was false and we don't + ** actually have an include guard. + */ + if (CurC != '\0' && (CurInput->GFlags & IG_COMPLETE) == IG_COMPLETE) { + CurInput->GFlags &= ~IG_ISGUARDED; + } + return Whitespace; } @@ -3346,6 +3413,7 @@ void Preprocess (void) OLine = PLine; ParseDirectives (MSM_MULTILINE); OLine = 0; + CurInput->GFlags &= ~IG_NEWFILE; /* Add the source info to preprocessor output if needed */ AddPreLine (PLine); @@ -3414,9 +3482,13 @@ void ContinueLine (void) -void PreprocessBegin (void) -/* Initialize preprocessor with current file */ +void PreprocessBegin (IFile* Input) +/* Initialize the preprocessor for a new input file */ { + /* Remember the new input file and flag it as new */ + CurInput = Input; + CurInput->GFlags |= IG_NEWFILE; + /* Reset #if depth */ PPStack->Index = -1; @@ -3429,9 +3501,14 @@ void PreprocessBegin (void) -void PreprocessEnd (void) -/* Preprocessor done with current file */ +void PreprocessEnd (IFile* Input) +/* Preprocessor done with current file. The parameter is the file we're +** switching back to. +*/ { + /* Switch back to the old input file */ + CurInput = Input; + /* Check for missing #endif */ while (PPStack->Index >= 0) { if ((PPStack->Stack[PPStack->Index] & IFCOND_NEEDTERM) != 0) { diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index e2a1b073c..44e35f30e 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -54,6 +54,9 @@ struct PPIfStack { int Index; }; +/* Forward */ +struct IFile; + /*****************************************************************************/ @@ -62,29 +65,31 @@ struct PPIfStack { +void HandleSpecialMacro (Macro* M, const char* Name); +/* Handle special "magic" macros that may change */ + void Preprocess (void); /* Preprocess a line */ -void SetPPIfStack (PPIfStack* Stack); -/* Specify which PP #if stack to use */ - -void ContinueLine (void); -/* Continue the current line ended with a '\\' */ - -void PreprocessBegin (void); -/* Initialize preprocessor with current file */ - -void PreprocessEnd (void); -/* Preprocessor done with current file */ - void InitPreprocess (void); /* Init preprocessor */ void DonePreprocess (void); /* Done with preprocessor */ -void HandleSpecialMacro (Macro* M, const char* Name); -/* Handle special "magic" macros that may change */ +void SetPPIfStack (PPIfStack* Stack); +/* Specify which PP #if stack to use */ + +void ContinueLine (void); +/* Continue the current line ended with a '\\' */ + +void PreprocessBegin (struct IFile* Input); +/* Initialize the preprocessor for a new input file */ + +void PreprocessEnd (struct IFile* Input); +/* Preprocessor done with current file. The parameter is the file we're +** switching back to. +*/ From bc9ebfb077f30a7b4e15e0613266b2fe325ec8e5 Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 16:05:12 +0200 Subject: [PATCH 624/707] Update ppubuf.s - fix ppu ringbuffer size as suggested in #1703 --- libsrc/nes/ppubuf.s | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libsrc/nes/ppubuf.s b/libsrc/nes/ppubuf.s index 0de6d1980..f3efa4451 100644 --- a/libsrc/nes/ppubuf.s +++ b/libsrc/nes/ppubuf.s @@ -32,7 +32,9 @@ .proc ppubuf_wait - lda #$ff ; (($0100/3)*1) +; $45 is the largest number that didn't cause glitches, $44 gives a bit more +; breathing room. see issue #1703 + lda #$44 @wait: cmp ringcount beq @wait rts From 4f5fc898d7816bd0b0e9555d8c3e3925f3aea382 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 18:40:32 +0200 Subject: [PATCH 625/707] someone accidently checked this in, i guess --- test/asm/listing/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/asm/listing/Makefile b/test/asm/listing/Makefile index 4321d3b95..9dc871dad 100644 --- a/test/asm/listing/Makefile +++ b/test/asm/listing/Makefile @@ -27,7 +27,7 @@ else endif ifdef QUIET -# .SILENT: + .SILENT: endif CA65 := $(if $(wildcard ../../../bin/ca65*),..$S..$S..$Sbin$Sca65,ca65) From 75aa45d41e745c569d6847c994c9a062b0a90739 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 18:42:01 +0200 Subject: [PATCH 626/707] when -s was used, implicitly use QUIET=1. also explicitly propagate QUIET to submakefile(s) --- test/Makefile | 44 ++++++++++++++++++++++++++------------------ test/asm/Makefile | 32 ++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 30 deletions(-) diff --git a/test/Makefile b/test/Makefile index 94bc7e5ea..c6cff47a4 100644 --- a/test/Makefile +++ b/test/Makefile @@ -16,6 +16,14 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET := 1 +endif + +ifneq ($(QUIET),1) + QUIET := 0 +endif + WORKDIR = ../testwrk .PHONY: test continue mostlyclean clean success_message @@ -25,15 +33,15 @@ test: @$(MAKE) continue continue: - @$(MAKE) -C asm all - @$(MAKE) -C dasm all - @$(MAKE) -C val all - @$(MAKE) -C ref all - @$(MAKE) -C err all - @$(MAKE) -C standard all - @$(MAKE) -C standard_err all - @$(MAKE) -C misc all - @$(MAKE) -C todo all + @$(MAKE) -C asm all QUIET=$(QUIET) + @$(MAKE) -C dasm all QUIET=$(QUIET) + @$(MAKE) -C val all QUIET=$(QUIET) + @$(MAKE) -C ref all QUIET=$(QUIET) + @$(MAKE) -C err all QUIET=$(QUIET) + @$(MAKE) -C standard all QUIET=$(QUIET) + @$(MAKE) -C standard_err all QUIET=$(QUIET) + @$(MAKE) -C misc all QUIET=$(QUIET) + @$(MAKE) -C todo all QUIET=$(QUIET) @$(MAKE) success_message success_message: @@ -42,15 +50,15 @@ success_message: $(info ###################################) mostlyclean: - @$(MAKE) -C asm clean - @$(MAKE) -C dasm clean - @$(MAKE) -C val clean - @$(MAKE) -C ref clean - @$(MAKE) -C err clean - @$(MAKE) -C standard clean - @$(MAKE) -C standard_err clean - @$(MAKE) -C misc clean - @$(MAKE) -C todo clean + @$(MAKE) -C asm clean QUIET=$(QUIET) + @$(MAKE) -C dasm clean QUIET=$(QUIET) + @$(MAKE) -C val clean QUIET=$(QUIET) + @$(MAKE) -C ref clean QUIET=$(QUIET) + @$(MAKE) -C err clean QUIET=$(QUIET) + @$(MAKE) -C standard clean QUIET=$(QUIET) + @$(MAKE) -C standard_err clean QUIET=$(QUIET) + @$(MAKE) -C misc clean QUIET=$(QUIET) + @$(MAKE) -C todo clean QUIET=$(QUIET) clean: mostlyclean @$(call RMDIR,$(WORKDIR)) diff --git a/test/asm/Makefile b/test/asm/Makefile index 2d5ba764e..bfae97222 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -16,6 +16,14 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET := 1 +endif + +ifneq ($(QUIET),1) + QUIET := 0 +endif + WORKDIR = ../testwrk/asm .PHONY: all continue mostlyclean clean @@ -23,20 +31,20 @@ WORKDIR = ../testwrk/asm all: mostlyclean continue 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 + @$(MAKE) --no-print-directory -C cpudetect all QUIET=$(QUIET) + @$(MAKE) --no-print-directory -C opcodes all QUIET=$(QUIET) + @$(MAKE) --no-print-directory -C listing all QUIET=$(QUIET) + @$(MAKE) --no-print-directory -C val all QUIET=$(QUIET) + @$(MAKE) --no-print-directory -C err all QUIET=$(QUIET) + @$(MAKE) --no-print-directory -C misc all QUIET=$(QUIET) 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 + @$(MAKE) --no-print-directory -C cpudetect clean + @$(MAKE) --no-print-directory -C opcodes clean + @$(MAKE) --no-print-directory -C listing clean + @$(MAKE) --no-print-directory -C val clean + @$(MAKE) --no-print-directory -C err clean + @$(MAKE) --no-print-directory -C misc clean clean: mostlyclean @$(call RMDIR,$(WORKDIR)) From 73869a6f389c20b2b8e04998fcaee2f291cf0129 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 19:45:52 +0200 Subject: [PATCH 627/707] make propagating QUIET=1 down actually work, also set --no-print-directory depending on QUIET --- test/Makefile | 43 ++++++++++++++++++++++--------------------- test/asm/Makefile | 29 +++++++++++++++-------------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/test/Makefile b/test/Makefile index c6cff47a4..b647dbe33 100644 --- a/test/Makefile +++ b/test/Makefile @@ -17,11 +17,12 @@ else endif ifeq ($(SILENT),s) - QUIET := 1 + QUIET = 1 endif -ifneq ($(QUIET),1) - QUIET := 0 +ifdef QUIET + PQ = "QUIET=1" + PD = --no-print-directory endif WORKDIR = ../testwrk @@ -33,15 +34,15 @@ test: @$(MAKE) continue continue: - @$(MAKE) -C asm all QUIET=$(QUIET) - @$(MAKE) -C dasm all QUIET=$(QUIET) - @$(MAKE) -C val all QUIET=$(QUIET) - @$(MAKE) -C ref all QUIET=$(QUIET) - @$(MAKE) -C err all QUIET=$(QUIET) - @$(MAKE) -C standard all QUIET=$(QUIET) - @$(MAKE) -C standard_err all QUIET=$(QUIET) - @$(MAKE) -C misc all QUIET=$(QUIET) - @$(MAKE) -C todo all QUIET=$(QUIET) + @$(MAKE) $(PD) -C asm all $(PQ) + @$(MAKE) $(PD) -C dasm all $(PQ) + @$(MAKE) $(PD) -C val all $(PQ) + @$(MAKE) $(PD) -C ref all $(PQ) + @$(MAKE) $(PD) -C err all $(PQ) + @$(MAKE) $(PD) -C standard all $(PQ) + @$(MAKE) $(PD) -C standard_err all $(PQ) + @$(MAKE) $(PD) -C misc all $(PQ) + @$(MAKE) $(PD) -C todo all $(PQ) @$(MAKE) success_message success_message: @@ -50,15 +51,15 @@ success_message: $(info ###################################) mostlyclean: - @$(MAKE) -C asm clean QUIET=$(QUIET) - @$(MAKE) -C dasm clean QUIET=$(QUIET) - @$(MAKE) -C val clean QUIET=$(QUIET) - @$(MAKE) -C ref clean QUIET=$(QUIET) - @$(MAKE) -C err clean QUIET=$(QUIET) - @$(MAKE) -C standard clean QUIET=$(QUIET) - @$(MAKE) -C standard_err clean QUIET=$(QUIET) - @$(MAKE) -C misc clean QUIET=$(QUIET) - @$(MAKE) -C todo clean QUIET=$(QUIET) + @$(MAKE) $(PD) -C asm clean $(PQ) + @$(MAKE) $(PD) -C dasm clean $(PQ) + @$(MAKE) $(PD) -C val clean $(PQ) + @$(MAKE) $(PD) -C ref clean $(PQ) + @$(MAKE) $(PD) -C err clean $(PQ) + @$(MAKE) $(PD) -C standard clean $(PQ) + @$(MAKE) $(PD) -C standard_err clean $(PQ) + @$(MAKE) $(PD) -C misc clean $(PQ) + @$(MAKE) $(PD) -C todo clean $(PQ) clean: mostlyclean @$(call RMDIR,$(WORKDIR)) diff --git a/test/asm/Makefile b/test/asm/Makefile index bfae97222..8d959ecae 100644 --- a/test/asm/Makefile +++ b/test/asm/Makefile @@ -20,8 +20,9 @@ ifeq ($(SILENT),s) QUIET := 1 endif -ifneq ($(QUIET),1) - QUIET := 0 +ifdef QUIET + PQ = "QUIET=1" + PD = --no-print-directory endif WORKDIR = ../testwrk/asm @@ -31,20 +32,20 @@ WORKDIR = ../testwrk/asm all: mostlyclean continue continue: mostlyclean - @$(MAKE) --no-print-directory -C cpudetect all QUIET=$(QUIET) - @$(MAKE) --no-print-directory -C opcodes all QUIET=$(QUIET) - @$(MAKE) --no-print-directory -C listing all QUIET=$(QUIET) - @$(MAKE) --no-print-directory -C val all QUIET=$(QUIET) - @$(MAKE) --no-print-directory -C err all QUIET=$(QUIET) - @$(MAKE) --no-print-directory -C misc all QUIET=$(QUIET) + @$(MAKE) $(PD) -C cpudetect all $(PQ) + @$(MAKE) $(PD) -C opcodes all $(PQ) + @$(MAKE) $(PD) -C listing all $(PQ) + @$(MAKE) $(PD) -C val all $(PQ) + @$(MAKE) $(PD) -C err all $(PQ) + @$(MAKE) $(PD) -C misc all $(PQ) mostlyclean: - @$(MAKE) --no-print-directory -C cpudetect clean - @$(MAKE) --no-print-directory -C opcodes clean - @$(MAKE) --no-print-directory -C listing clean - @$(MAKE) --no-print-directory -C val clean - @$(MAKE) --no-print-directory -C err clean - @$(MAKE) --no-print-directory -C misc clean + @$(MAKE) $(PD) -C cpudetect clean $(PQ) + @$(MAKE) $(PD) -C opcodes clean $(PQ) + @$(MAKE) $(PD) -C listing clean $(PQ) + @$(MAKE) $(PD) -C val clean $(PQ) + @$(MAKE) $(PD) -C err clean $(PQ) + @$(MAKE) $(PD) -C misc clean $(PQ) clean: mostlyclean @$(call RMDIR,$(WORKDIR)) From 7a85575158ffc4e4325335a92cd3ae9192747b92 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 19:48:16 +0200 Subject: [PATCH 628/707] fix handling of QUIET in the "test" directory --- test/asm/cpudetect/Makefile | 10 +++++--- test/asm/err/Makefile | 2 ++ test/asm/listing/Makefile | 47 ++++++++++++++++++++++--------------- test/asm/misc/Makefile | 1 + test/asm/opcodes/Makefile | 3 +++ test/asm/val/Makefile | 4 ++-- test/dasm/Makefile | 5 ++++ test/err/Makefile | 5 +++- test/misc/Makefile | 39 +++++++++++++++--------------- test/ref/Makefile | 2 ++ test/standard/Makefile | 1 + test/standard_err/Makefile | 5 +++- test/todo/Makefile | 2 ++ test/val/Makefile | 9 +++---- 14 files changed, 86 insertions(+), 49 deletions(-) diff --git a/test/asm/cpudetect/Makefile b/test/asm/cpudetect/Makefile index fde19b17b..a77e5b576 100644 --- a/test/asm/cpudetect/Makefile +++ b/test/asm/cpudetect/Makefile @@ -20,8 +20,12 @@ else RMDIR = $(RM) -r $1 endif + ifdef QUIET .SILENT: + NULLOUT = >$(NULLDEV) + NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif CA65 := $(if $(wildcard ../../../bin/ca65*),../../../bin/ca65,ca65) @@ -52,8 +56,8 @@ define CPUDETECT_template $(WORKDIR)/$1-cpudetect.bin: cpudetect.s $1-cpudetect.ref $(ISEQUAL) $(if $(QUIET),echo asm/$1-cpudetect.bin) - $(CA65) -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$< - $(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib + $(CA65) -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$< $(CATERR) + $(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib $(CATERR) $(ISEQUAL) $1-cpudetect.ref $$@ endef # CPUDETECT_template @@ -61,7 +65,7 @@ endef # CPUDETECT_template $(foreach cpu,$(CPUDETECT_CPUS),$(eval $(call CPUDETECT_template,$(cpu)))) $(WORKDIR)/%.o: %.s | $(WORKDIR) - $(CA65) -l $(@:.o=.lst) -o $@ $< + $(CA65) -l $(@:.o=.lst) -o $@ $< $(NULLOUT) $(CATERR) clean: @$(call RMDIR,$(WORKDIR)) diff --git a/test/asm/err/Makefile b/test/asm/err/Makefile index c1a8285e4..5c329138b 100644 --- a/test/asm/err/Makefile +++ b/test/asm/err/Makefile @@ -26,7 +26,9 @@ endif ifdef QUIET .SILENT: + NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif CA65 := $(if $(wildcard ../../../bin/ca65*),..$S..$S..$Sbin$Sca65,ca65) diff --git a/test/asm/listing/Makefile b/test/asm/listing/Makefile index 9dc871dad..9d815985d 100644 --- a/test/asm/listing/Makefile +++ b/test/asm/listing/Makefile @@ -17,6 +17,7 @@ ifdef CMD_EXE RMDIR = -rmdir /q /s $(subst /,\,$1) TRUE = exit 0 CAT = type $(subst /,\,$1) + NULLDEV = nul: else S = / EXE = @@ -24,10 +25,14 @@ else RMDIR = $(RM) -r $1 TRUE = true CAT = cat $1 + NULLDEV = /dev/null endif ifdef QUIET .SILENT: + NULLOUT = >$(NULLDEV) + NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif CA65 := $(if $(wildcard ../../../bin/ca65*),..$S..$S..$Sbin$Sca65,ca65) @@ -82,48 +87,52 @@ endif endif ifneq ($(wildcard ref/$1.err-ref),) - $(ISEQUAL) ref/$1.err-ref $$(@:.bin=.err) + $(ISEQUAL) ref/$1.err-ref $$(@:.bin=.err) $(NULLERR) else - $(ISEQUAL) --empty $$(@:.bin=.err) + $(ISEQUAL) --empty $$(@:.bin=.err) $(NULLERR) endif ifneq ($(wildcard ref/$1.err2-ref),) - $(ISEQUAL) ref/$1.err2-ref $$(@:.bin=.err2) + $(ISEQUAL) ref/$1.err2-ref $$(@:.bin=.err2) $(NULLERR) else - $(ISEQUAL) --empty $$(@:.bin=.err2) + $(ISEQUAL) --empty $$(@:.bin=.err2) $(NULLERR) endif ifneq ($(wildcard ref/$1.bin-ref),) - $(ISEQUAL) --binary ref/$1.bin-ref $$@ + $(ISEQUAL) --binary ref/$1.bin-ref $$@ $(NULLERR) endif # rem $(indfo $(CAT) $(subst /,$$S,$$$(@:.bin=.ld65-err))) ifneq ($(wildcard ref/$1.ld65err-ref),) +ifndef QUIET @echo $(CAT) $$(@:.bin=.ld65-err) # FIXME: somehow this refuses to work in cmd.exe ifndef CMD_EXE $(call CAT,$$(@:.bin=.ld65-err)) -diff -u ref/$1.ld65err-ref $$(@:.bin=.ld65-err) endif - $(ISEQUAL) --wildcards ref/$1.ld65err-ref $$(@:.bin=.ld65-err) +endif + $(ISEQUAL) --wildcards ref/$1.ld65err-ref $$(@:.bin=.ld65-err) $(NULLERR) else ifneq ($(wildcard $(WORKDIR)/$1.ld65-err),) - $(ISEQUAL) --empty $$(@:.bin=.ld65-err) + $(ISEQUAL) --empty $$(@:.bin=.ld65-err) $(NULLERR) endif endif ifneq ($(wildcard ref/$1.ld65err2-ref),) +ifndef QUIET @echo $(CAT) $$(@:.bin=.ld65-err2) # FIXME: somehow this refuses to work in cmd.exe ifndef CMD_EXE $(call CAT,$$(@:.bin=.ld65-err2)) -diff -u ref/$1.ld65err2-ref $$(@:.bin=.ld65-err2) endif - $(ISEQUAL) --wildcards ref/$1.ld65err2-ref $$(@:.bin=.ld65-err2) +endif + $(ISEQUAL) --wildcards ref/$1.ld65err2-ref $$(@:.bin=.ld65-err2) $(NULLERR) else ifneq ($(wildcard $(WORKDIR)/$1.ld65-err2),) - $(ISEQUAL) --empty $$(@:.bin=.ld65-err2) + $(ISEQUAL) --empty $$(@:.bin=.ld65-err2) $(NULLERR) endif endif @@ -149,37 +158,37 @@ endif endif ifneq ($(wildcard ref/$1.err-ref),) - $(ISEQUAL) ref/$1.err-ref $$(@:.bin=.list-err) + $(ISEQUAL) ref/$1.err-ref $$(@:.bin=.list-err) $(NULLERR) else - $(ISEQUAL) --empty $$(@:.bin=.list-err) + $(ISEQUAL) --empty $$(@:.bin=.list-err) $(NULLERR) endif ifneq ($(wildcard ref/$1.ld65err-ref),) - $(ISEQUAL) --wildcards ref/$1.ld65err-ref $$(@:.bin=.list-ld65-err) + $(ISEQUAL) --wildcards ref/$1.ld65err-ref $$(@:.bin=.list-ld65-err) $(NULLERR) else ifneq ($(wildcard $(WORKDIR)/$1.list-ld65-err),) - $(ISEQUAL) --empty $$(@:.bin=.list-ld65-err) + $(ISEQUAL) --empty $$(@:.bin=.list-ld65-err) $(NULLERR) endif endif ifneq ($(wildcard ref/$1.err2-ref),) - $(ISEQUAL) ref/$1.err2-ref $$(@:.bin=.list-err2) + $(ISEQUAL) ref/$1.err2-ref $$(@:.bin=.list-err2) $(NULLERR) else - $(ISEQUAL) --empty $$(@:.bin=.list-err2) + $(ISEQUAL) --empty $$(@:.bin=.list-err2) $(NULLERR) endif ifneq ($(wildcard ref/$1.ld65err2-ref),) - $(ISEQUAL) --wildcards ref/$1.ld65err2-ref $$(@:.bin=.list-ld65-err2) + $(ISEQUAL) --wildcards ref/$1.ld65err2-ref $$(@:.bin=.list-ld65-err2) $(NULLERR) else ifneq ($(wildcard $(WORKDIR)/$1.list-ld65-err2),) - $(ISEQUAL) --empty $$(@:.bin=.list-ld65-err2) + $(ISEQUAL) --empty $$(@:.bin=.list-ld65-err2) $(NULLERR) endif endif # check if the result bin is the same as without listing file ifeq ($(wildcard control/$1.err),) ifeq ($(wildcard control/$1.err2),) - $(ISEQUAL) $$@ $$(@:.bin=.list-bin) + $(ISEQUAL) $$@ $$(@:.bin=.list-bin) $(NULLERR) endif endif @@ -187,7 +196,7 @@ ifneq ($(wildcard ref/$1.list-ref),) # we have a reference file, compare that, too # remove first line which contains a version number - $(ISEQUAL) --skip=1 ref/$1.list-ref $$(@:.bin=.list-lst) + $(ISEQUAL) --skip=1 ref/$1.list-ref $$(@:.bin=.list-lst) $(NULLERR) endif endef # LISTING_template diff --git a/test/asm/misc/Makefile b/test/asm/misc/Makefile index 1b2305cda..4f24aa041 100644 --- a/test/asm/misc/Makefile +++ b/test/asm/misc/Makefile @@ -30,6 +30,7 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif SIM65FLAGS = -x 200000000 diff --git a/test/asm/opcodes/Makefile b/test/asm/opcodes/Makefile index 70dd41c06..c0918499c 100644 --- a/test/asm/opcodes/Makefile +++ b/test/asm/opcodes/Makefile @@ -22,6 +22,9 @@ endif ifdef QUIET .SILENT: + NULLOUT = >$(NULLDEV) + NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif CA65 := $(if $(wildcard ../../../bin/ca65*),../../../bin/ca65,ca65) diff --git a/test/asm/val/Makefile b/test/asm/val/Makefile index 08c000f95..fe27f97d1 100644 --- a/test/asm/val/Makefile +++ b/test/asm/val/Makefile @@ -51,8 +51,8 @@ define PRG_template $(WORKDIR)/%.$1.prg: %.s | $(WORKDIR) $(if $(QUIET),echo asm/val/$$*.$1.prg) - $(CA65) -t sim$1 -o $$(@:.prg=.o) $$< $(NULLERR) - $(LD65) -C sim6502-asmtest.cfg -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLERR) + $(CA65) -t sim$1 -o $$(@:.prg=.o) $$< $(NULLOUT) $(NULLERR) + $(LD65) -C sim6502-asmtest.cfg -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLOUT) $(NULLERR) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) endef # PRG_template diff --git a/test/dasm/Makefile b/test/dasm/Makefile index 29e97b9c1..9c19f575c 100644 --- a/test/dasm/Makefile +++ b/test/dasm/Makefile @@ -14,14 +14,19 @@ ifdef CMD_EXE EXE = .exe MKDIR = mkdir $(subst /,\,$1) RMDIR = -rmdir /q /s $(subst /,\,$1) + NULLDEV = nul: else EXE = MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 + NULLDEV = /dev/null endif ifdef QUIET .SILENT: + NULLOUT = >$(NULLDEV) + NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) diff --git a/test/err/Makefile b/test/err/Makefile index a0cdc22ae..72b11cd1f 100644 --- a/test/err/Makefile +++ b/test/err/Makefile @@ -26,9 +26,12 @@ endif ifdef QUIET .SILENT: + NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif + CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) WORKDIR = ../../testwrk/err @@ -45,7 +48,7 @@ $(WORKDIR): $(WORKDIR)/%.s: %.c | $(WORKDIR) $(if $(QUIET),echo err/$*.s) - $(NOT) $(CC65) -o $@ $< $(NULLERR) + $(NOT) $(CC65) -o $@ $< $(NULLOUT) $(CATERR) clean: @$(call RMDIR,$(WORKDIR)) diff --git a/test/misc/Makefile b/test/misc/Makefile index 989e8f83a..fb3730f5c 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -30,6 +30,7 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif SIM65FLAGS = -x 200000000 @@ -68,7 +69,7 @@ define PRG_template $(WORKDIR)/bug1209-ind-goto-rev.$1.$2.prg: bug1209-ind-goto-rev.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." $(if $(QUIET),echo misc/bug1209-ind-goto-rev.$1.$2.prg) - $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) + $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) $(CATERR) $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) $(NOT) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) @@ -76,7 +77,7 @@ $(WORKDIR)/bug1209-ind-goto-rev.$1.$2.prg: bug1209-ind-goto-rev.c | $(WORKDIR) $(WORKDIR)/bug1209-ind-goto-rev-2.$1.$2.prg: bug1209-ind-goto-rev-2.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." $(if $(QUIET),echo misc/bug1209-ind-goto-rev-2.$1.$2.prg) - $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) + $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) $(CATERR) $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) $(NOT) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) @@ -84,7 +85,7 @@ $(WORKDIR)/bug1209-ind-goto-rev-2.$1.$2.prg: bug1209-ind-goto-rev-2.c | $(WORKDI $(WORKDIR)/bug1209-ind-goto-rev-3.$1.$2.prg: bug1209-ind-goto-rev-3.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." $(if $(QUIET),echo misc/bug1209-ind-goto-rev-3.$1.$2.prg) - $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) + $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) $(CATERR) $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) $(NOT) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) @@ -92,40 +93,40 @@ $(WORKDIR)/bug1209-ind-goto-rev-3.$1.$2.prg: bug1209-ind-goto-rev-3.c | $(WORKDI $(WORKDIR)/pptest2.$1.$2.prg: pptest2.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." $(if $(QUIET),echo misc/pptest2.$1.$2.prg) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLOUT) $(CATERR) # should compile, but compiler exits with internal error $(WORKDIR)/bug1211-ice-move-refs-2.$1.$2.prg: bug1211-ice-move-refs-2.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." $(if $(QUIET),echo misc/bug1211-ice-move-refs-2.$1.$2.prg) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLOUT) $(CATERR) # this one requires --std=c89, it fails with --std=c99 $(WORKDIR)/bug1265.$1.$2.prg: bug1265.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1265.$1.$2.prg) - $(CC65) --standard c89 -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) + $(CC65) --standard c89 -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) $(CATERR) $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) # should not compile, but gives different diagnostics in C99 mode than in others -$(WORKDIR)/bug2515.$1.$2.prg: bug2515.c | $(WORKDIR) +$(WORKDIR)/bug2515.$1.$2.prg: bug2515.c $(ISEQUAL) | $(WORKDIR) $(if $(QUIET),echo misc/bug2515.$1.$2.prg) - $(NOT) $(CC65) --standard c99 -t sim$2 -$1 -o $$(@:.prg=.s) $$< 2>$(WORKDIR)/bug2515.$1.$2.out + $(NOT) $(CC65) --standard c99 -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) 2>$(WORKDIR)/bug2515.$1.$2.out $(ISEQUAL) $(WORKDIR)/bug2515.$1.$2.out bug2515.c99.ref - $(NOT) $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< 2>$(WORKDIR)/bug2515.$1.$2.out + $(NOT) $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) 2>$(WORKDIR)/bug2515.$1.$2.out $(ISEQUAL) $(WORKDIR)/bug2515.$1.$2.out bug2515.ref # should not issue any warnings in C99 mode -$(WORKDIR)/bug2637.$1.$2.prg: bug2637.c | $(WORKDIR) +$(WORKDIR)/bug2637.$1.$2.prg: bug2637.c $(ISEQUAL) | $(WORKDIR) $(if $(QUIET),echo misc/bug2637.$1.$2.prg) - $(CC65) --standard c99 -t sim$2 -$1 -o $$(@:.prg=.s) $$< 2>$(WORKDIR)/bug2637.$1.$2.out + $(CC65) --standard c99 -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) 2>$(WORKDIR)/bug2637.$1.$2.out $(ISEQUAL) $(WORKDIR)/bug2637.$1.$2.out bug2637.ref # this one requires -Werror $(WORKDIR)/bug1768.$1.$2.prg: bug1768.c | $(WORKDIR) $(if $(QUIET),echo misc/bug1768.$1.$2.prg) - $(CC65) -Werror -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) + $(CC65) -Werror -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) $(CATERR) $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) @@ -133,7 +134,7 @@ $(WORKDIR)/bug1768.$1.$2.prg: bug1768.c | $(WORKDIR) # should compile, but then hangs in an endless loop $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) $(if $(QUIET),echo misc/endless.$1.$2.prg) - $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) + $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) $(CATERR) $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) $(NOT) $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) $(NULLERR) @@ -142,12 +143,12 @@ $(WORKDIR)/endless.$1.$2.prg: endless.c | $(WORKDIR) # in a useful way $(WORKDIR)/bug2655.$1.$2.prg: bug2655.c $(ISEQUAL) | $(WORKDIR) $(if $(QUIET),echo misc/bug2655.$1.$2.prg) - $(CC65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/bug2655.$1.$2.out + $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLOUT) 2>$(WORKDIR)/bug2655.$1.$2.out $(ISEQUAL) $(WORKDIR)/bug2655.$1.$2.out bug2655.ref $(WORKDIR)/limits.$1.$2.prg: limits.c $(ISEQUAL) | $(WORKDIR) $(if $(QUIET),echo misc/limits.$1.$2.prg) - $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLERR) + $(CC65) -t sim$2 -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) $(CATERR) $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/limits.$1.$2.out @@ -155,24 +156,24 @@ $(WORKDIR)/limits.$1.$2.prg: limits.c $(ISEQUAL) | $(WORKDIR) $(WORKDIR)/goto.$1.$2.prg: goto.c $(ISEQUAL) | $(WORKDIR) $(if $(QUIET),echo misc/goto.$1.$2.prg) - $(CC65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.$2.out + $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLOUT) 2>$(WORKDIR)/goto.$1.$2.out $(ISEQUAL) $(WORKDIR)/goto.$1.$2.out goto.ref # this one requires failure with --std=c89, it fails with --std=cc65 due to # stricter checks $(WORKDIR)/bug2304-implicit-func.$1.$2.prg: bug2304-implicit-func.c | $(WORKDIR) $(if $(QUIET),echo misc/bug2304-implicit-func.$1.$2.prg) - $(NOT) $(CC65) --standard c89 -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CC65) --standard c89 -t sim$2 -$1 -o $$@ $$< $(NULLOUT) $(CATERR) # should not compile until 3-byte struct by value tests are re-enabled $(WORKDIR)/struct-by-value.$1.$2.prg: struct-by-value.c | $(WORKDIR) $(if $(QUIET),echo misc/struct-by-value.$1.$2.prg) - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLOUT) $(CATERR) # the rest are tests that fail currently for one reason or another $(WORKDIR)/sitest.$1.$2.prg: sitest.c | $(WORKDIR) @echo "FIXME: " $$@ "currently does not compile." - $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR) + $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLOUT) $(CATERR) # $(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT) endef # PRG_template diff --git a/test/ref/Makefile b/test/ref/Makefile index 2dadf5bcc..4ac8f02a4 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -29,7 +29,9 @@ endif ifdef QUIET .SILENT: + NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif SIM65FLAGS = -x 200000000 diff --git a/test/standard/Makefile b/test/standard/Makefile index e359fa975..c58fdc070 100644 --- a/test/standard/Makefile +++ b/test/standard/Makefile @@ -26,6 +26,7 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif SIM65FLAGS = -x 4000000000 -c diff --git a/test/standard_err/Makefile b/test/standard_err/Makefile index f554d33eb..53d4efafd 100644 --- a/test/standard_err/Makefile +++ b/test/standard_err/Makefile @@ -26,9 +26,12 @@ endif ifdef QUIET .SILENT: + NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif + CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) WORKDIR = ../../testwrk/standard_err @@ -49,7 +52,7 @@ define PRG_template $(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) $(if $(QUIET),echo standard_err/$$*.$1.$2.prg) - $(NOT) $(CC65) -t sim$2 $$(CC65FLAGS) -Osir --add-source --standard $1 -o $$(@:.prg=.s) $$< $(NULLERR) + $(NOT) $(CC65) -t sim$2 $$(CC65FLAGS) -Osir --add-source --standard $1 -o $$(@:.prg=.s) $$< $(NULLOUT) $(CATERR) endef # PRG_template diff --git a/test/todo/Makefile b/test/todo/Makefile index ec14cf8d4..338ffb978 100644 --- a/test/todo/Makefile +++ b/test/todo/Makefile @@ -28,8 +28,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif + SIM65FLAGS = -x 200000000 CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) diff --git a/test/val/Makefile b/test/val/Makefile index 68882971d..58c08d4f8 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -28,6 +28,7 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) + CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif SIM65FLAGS = -x 4000000000 -c @@ -56,10 +57,10 @@ define PRG_template $(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) $(if $(QUIET),echo val/$$*.$1.$2.prg) - $(CC65) -t sim$2 $$(CC65FLAGS) --add-source -$1 -o $$(@:.prg=.s) $$< $(NULLERR) - $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR) - $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR) - $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/$$@.out $(CATRES) + $(CC65) -t sim$2 $$(CC65FLAGS) --add-source -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) $(CATERR) + $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLOUT) $(CATERR) + $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLOUT) $(CATERR) + $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/$$@.out 2> $(WORKDIR)/$$@.out $(CATRES) endef # PRG_template From afe395e9705e06f9fe6f56abeed9f9f3a4d021f3 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 20:15:28 +0200 Subject: [PATCH 629/707] fix -s vs QUIET in testtarget --- targettest/Makefile | 16 ++++++++++++++-- targettest/accelerator/Makefile | 16 ++++++++++++++++ targettest/atari/Makefile | 17 +++++++++++++++++ targettest/cbm/Makefile | 11 +++++++++++ targettest/gamate/Makefile | 11 +++++++++++ targettest/pce/Makefile | 11 +++++++++++ 6 files changed, 80 insertions(+), 2 deletions(-) diff --git a/targettest/Makefile b/targettest/Makefile index 56b5df446..edddca0f2 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -47,6 +47,16 @@ else LD := $(if $(wildcard ../bin/ld65*),../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: + PQ = "QUIET=1" + PD = --no-print-directory +endif + ifneq ($(filter disk testcode.%,$(MAKECMDGOALS)),) ifdef CC65_HOME TARGET_PATH = $(CC65_HOME)/target @@ -120,10 +130,12 @@ DISK_atarixl = testcode.atr %: %.s .c.o: + $(if $(QUIET),echo targettest/$*.c) $(CC) $(CFLAGS) -Ors --codesize 500 -T -g -t $(SYS) $< $(AS) $(<:.c=.s) .s.o: + $(if $(QUIET),echo targettest/$*.s) $(AS) $(ASFLAGS) -t $(SYS) $< .PRECIOUS: %.o @@ -721,7 +733,7 @@ endif define SUBDIR_recipe -@+$(MAKE) -C $(dir) --no-print-directory $@ +@+$(MAKE) -C $(dir) $(PD) $@ $(PQ) endef # SUBDIR_recipe @@ -783,7 +795,7 @@ define TARGET_recipe @echo making targettest for: $(T) @$(MAKE) -j2 SYS:=$(T) -@$(MAKE) --no-print-directory clean SYS:=$(T) +@$(MAKE) $(PD) clean SYS:=$(T) endef # TARGET_recipe diff --git a/targettest/accelerator/Makefile b/targettest/accelerator/Makefile index 6e710d010..0a6a9bb02 100644 --- a/targettest/accelerator/Makefile +++ b/targettest/accelerator/Makefile @@ -36,6 +36,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_c64 = \ c64-scpu-test.prg \ c64dtv-test.prg \ @@ -64,27 +72,35 @@ else endif c64-scpu-test.prg: c64-c128-scpu-test.c + $(if $(QUIET),echo $@) $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg c128-scpu-test.prg: c64-c128-scpu-test.c + $(if $(QUIET),echo $@) $(CL) -t c128 c64-c128-scpu-test.c -o c128-scpu-test.prg c64dtv-test.prg: c64dtv-test.c + $(if $(QUIET),echo $@) $(CL) -t c64 c64dtv-test.c -o c64dtv-test.prg c64-test.prg: c64-c128-test.c + $(if $(QUIET),echo $@) $(CL) -t c64 c64-c128-test.c -o c64-test.prg c128-test.prg: c64-c128-test.c + $(if $(QUIET),echo $@) $(CL) -t c128 c64-c128-test.c -o c128-test.prg chameleon-test.prg: chameleon-test.c + $(if $(QUIET),echo $@) $(CL) -t c64 chameleon-test.c -o chameleon-test.prg c65-test.prg: c65-test.c + $(if $(QUIET),echo $@) $(CL) -t c64 c65-test.c -o c65-test.prg turbomaster-test.prg: turbomaster-test.c + $(if $(QUIET),echo $@) $(CL) -t c64 turbomaster-test.c -o turbomaster-test.prg clean: diff --git a/targettest/atari/Makefile b/targettest/atari/Makefile index 0e376e9bc..ef8d1883c 100644 --- a/targettest/atari/Makefile +++ b/targettest/atari/Makefile @@ -37,6 +37,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_atari = \ charmapping.xex \ defdev.xex \ @@ -64,24 +72,33 @@ else endif charmapping.xex: charmapping.c + $(if $(QUIET),echo $@) $(CL) -t atari -o charmapping.xex charmapping.c defdev.xex: defdev.c + $(if $(QUIET),echo $@) $(CL) -t atari -o defdev.xex defdev.c displaylist.xex: displaylist.c + $(if $(QUIET),echo $@) $(CL) -t atari -o displaylist.xex displaylist.c mem.xex: mem.c ../getsp.s + $(if $(QUIET),echo $@) $(CL) -t atari -o mem.xex mem.c ../getsp.s multi.xex: multi-xex.s multi-xex.cfg + $(if $(QUIET),echo $@) $(CL) -t atari -C multi-xex.cfg multi-xex.s -o multi.xex ostype.xex: ostype.c + $(if $(QUIET),echo $@) $(CL) -t atari -o ostype.xex ostype.c scrcode.com: scrcode.s + $(if $(QUIET),echo $@) # ca65 -t atari -o scrcode.o scrcode.s # ld65 -C atari-asm.cfg -o scrcode.com scrcode.o $(CL) -t atari -C atari-asm.cfg -o scrcode.com scrcode.s sys.xex: sys.c + $(if $(QUIET),echo $@) $(CL) -t atari -o sys.xex sys.c sound.xex: sound.c + $(if $(QUIET),echo $@) $(CL) -t atari -o sound.xex sound.c clean: @$(DEL) charmapping.xex 2>$(NULLDEV) diff --git a/targettest/cbm/Makefile b/targettest/cbm/Makefile index ebe00198f..96acf49a0 100644 --- a/targettest/cbm/Makefile +++ b/targettest/cbm/Makefile @@ -40,6 +40,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_c64 = \ petscii.prg \ cbmdir-test.prg \ @@ -73,12 +81,14 @@ endif ifeq ($(SYS),c64) petscii.prg: petscii.c + $(if $(QUIET),echo $@) $(CL) -t $(SYS) -O -o petscii.prg petscii.c else petscii.prg: endif cbmdir-test.prg: cbmdir-test.c + $(if $(QUIET),echo $@) ifeq ($(SYS),vic20) $(CL) -t $(SYS) -C vic20-32k.cfg -Oris -o $@ $< else @@ -86,6 +96,7 @@ else endif cbmread.prg: cbmread.c + $(if $(QUIET),echo $@) ifeq ($(SYS),vic20) $(CL) -t $(SYS) -C vic20-32k.cfg -Oris -o $@ $< else diff --git a/targettest/gamate/Makefile b/targettest/gamate/Makefile index f03c2b064..3e3d1f9d8 100644 --- a/targettest/gamate/Makefile +++ b/targettest/gamate/Makefile @@ -37,6 +37,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_gamate = \ audiotest.bin lcdtest.bin ctest.bin @@ -56,10 +64,13 @@ else endif audiotest.bin: audiotest.s + $(if $(QUIET),echo $@) $(CL) -l audiotest.lst -t gamate -o audiotest.bin audiotest.s lcdtest.bin: lcdtest.s + $(if $(QUIET),echo $@) $(CL) -l lcdtest.lst -t gamate -o lcdtest.bin lcdtest.s ctest.bin: ctest.c + $(if $(QUIET),echo $@) $(CL) -l ctest.lst -t gamate -o ctest.bin ctest.c clean: diff --git a/targettest/pce/Makefile b/targettest/pce/Makefile index 549720a40..2a0be84d5 100644 --- a/targettest/pce/Makefile +++ b/targettest/pce/Makefile @@ -37,6 +37,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + .PHONY: all clean test # Size of cartridge to generate. @@ -71,8 +79,11 @@ else endif %.bin: %.c + $(if $(QUIET),echo $@) $(CL) -t pce $< -Wl -D__CARTSIZE__=${CARTSIZE} -m $*.map -o $@ +ifndef QUIET @echo "use 'make conio.pce' to produce a .pce file using dd" +endif %.pce: %.bin dd if=$< bs=8K skip=${COUNT} > $@ From 70f9723a893a1b51c66ac427c225c97ea0bd5720 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 20:42:15 +0200 Subject: [PATCH 630/707] dumb down for cmd.exe --- test/asm/cpudetect/Makefile | 2 ++ test/asm/err/Makefile | 2 ++ test/asm/listing/Makefile | 2 ++ test/asm/misc/Makefile | 2 ++ test/asm/opcodes/Makefile | 2 ++ test/dasm/Makefile | 2 ++ test/err/Makefile | 2 ++ test/misc/Makefile | 2 ++ test/ref/Makefile | 2 ++ test/standard/Makefile | 2 ++ test/standard_err/Makefile | 2 ++ test/todo/Makefile | 2 ++ test/val/Makefile | 2 ++ 13 files changed, 26 insertions(+) diff --git a/test/asm/cpudetect/Makefile b/test/asm/cpudetect/Makefile index a77e5b576..d0077bfd9 100644 --- a/test/asm/cpudetect/Makefile +++ b/test/asm/cpudetect/Makefile @@ -25,8 +25,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif CA65 := $(if $(wildcard ../../../bin/ca65*),../../../bin/ca65,ca65) LD65 := $(if $(wildcard ../../../bin/ld65*),../../../bin/ld65,ld65) diff --git a/test/asm/err/Makefile b/test/asm/err/Makefile index 5c329138b..8b93cd80d 100644 --- a/test/asm/err/Makefile +++ b/test/asm/err/Makefile @@ -28,8 +28,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif CA65 := $(if $(wildcard ../../../bin/ca65*),..$S..$S..$Sbin$Sca65,ca65) diff --git a/test/asm/listing/Makefile b/test/asm/listing/Makefile index 9d815985d..dc2c43d73 100644 --- a/test/asm/listing/Makefile +++ b/test/asm/listing/Makefile @@ -32,8 +32,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif CA65 := $(if $(wildcard ../../../bin/ca65*),..$S..$S..$Sbin$Sca65,ca65) LD65 := $(if $(wildcard ../../../bin/ld65*),..$S..$S..$Sbin$Sld65,ld65) diff --git a/test/asm/misc/Makefile b/test/asm/misc/Makefile index 4f24aa041..3072fa24e 100644 --- a/test/asm/misc/Makefile +++ b/test/asm/misc/Makefile @@ -30,8 +30,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif SIM65FLAGS = -x 200000000 diff --git a/test/asm/opcodes/Makefile b/test/asm/opcodes/Makefile index c0918499c..2fe046bd9 100644 --- a/test/asm/opcodes/Makefile +++ b/test/asm/opcodes/Makefile @@ -24,8 +24,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif CA65 := $(if $(wildcard ../../../bin/ca65*),../../../bin/ca65,ca65) LD65 := $(if $(wildcard ../../../bin/ld65*),../../../bin/ld65,ld65) diff --git a/test/dasm/Makefile b/test/dasm/Makefile index 9c19f575c..196975857 100644 --- a/test/dasm/Makefile +++ b/test/dasm/Makefile @@ -26,8 +26,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif CL65 := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65) CA65 := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65) diff --git a/test/err/Makefile b/test/err/Makefile index 72b11cd1f..5bd198477 100644 --- a/test/err/Makefile +++ b/test/err/Makefile @@ -28,8 +28,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) diff --git a/test/misc/Makefile b/test/misc/Makefile index fb3730f5c..8eb360e52 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -30,8 +30,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif SIM65FLAGS = -x 200000000 diff --git a/test/ref/Makefile b/test/ref/Makefile index 4ac8f02a4..1a5611083 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -31,8 +31,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif SIM65FLAGS = -x 200000000 diff --git a/test/standard/Makefile b/test/standard/Makefile index c58fdc070..f09024b58 100644 --- a/test/standard/Makefile +++ b/test/standard/Makefile @@ -26,8 +26,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif SIM65FLAGS = -x 4000000000 -c diff --git a/test/standard_err/Makefile b/test/standard_err/Makefile index 53d4efafd..702ad3f95 100644 --- a/test/standard_err/Makefile +++ b/test/standard_err/Makefile @@ -28,8 +28,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) diff --git a/test/todo/Makefile b/test/todo/Makefile index 338ffb978..7a0cbfa54 100644 --- a/test/todo/Makefile +++ b/test/todo/Makefile @@ -28,8 +28,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif SIM65FLAGS = -x 200000000 diff --git a/test/val/Makefile b/test/val/Makefile index 58c08d4f8..fe895e217 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -28,8 +28,10 @@ ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) NULLERR = 2>$(NULLDEV) +ifndef CMD_EXE CATERR = 2> $(WORKDIR)/$$@.errlog || (cat $(WORKDIR)/$$@.errlog && false) endif +endif SIM65FLAGS = -x 4000000000 -c From 46770bbb63511a3fad82ab8cd398a56d4d8756c0 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 20:53:10 +0200 Subject: [PATCH 631/707] another for cmd.exe --- test/val/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/val/Makefile b/test/val/Makefile index fe895e217..34ddff067 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -21,7 +21,7 @@ else NULLDEV = /dev/null MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 - CATRES = || (cat $(WORKDIR)/$$@.out && false) + CATRES = $$@ > $(WORKDIR)/$$@.out 2> $(WORKDIR)/$$@.out || (cat $(WORKDIR)/$$@.out && false) endif ifdef QUIET @@ -62,7 +62,7 @@ $(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) $(CC65) -t sim$2 $$(CC65FLAGS) --add-source -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) $(CATERR) $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLOUT) $(CATERR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLOUT) $(CATERR) - $(SIM65) $(SIM65FLAGS) $$@ > $(WORKDIR)/$$@.out 2> $(WORKDIR)/$$@.out $(CATRES) + $(SIM65) $(SIM65FLAGS) $(CATRES) endef # PRG_template From cc6813428c83418f293a48f5a962aacf250ce844 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 21:00:20 +0200 Subject: [PATCH 632/707] fix the fix --- test/val/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/val/Makefile b/test/val/Makefile index 34ddff067..1f6f0ba4c 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -21,7 +21,7 @@ else NULLDEV = /dev/null MKDIR = mkdir -p $1 RMDIR = $(RM) -r $1 - CATRES = $$@ > $(WORKDIR)/$$@.out 2> $(WORKDIR)/$$@.out || (cat $(WORKDIR)/$$@.out && false) + CATRES = > $(WORKDIR)/$$@.out 2> $(WORKDIR)/$$@.out || (cat $(WORKDIR)/$$@.out && false) endif ifdef QUIET @@ -62,7 +62,7 @@ $(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR) $(CC65) -t sim$2 $$(CC65FLAGS) --add-source -$1 -o $$(@:.prg=.s) $$< $(NULLOUT) $(CATERR) $(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLOUT) $(CATERR) $(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLOUT) $(CATERR) - $(SIM65) $(SIM65FLAGS) $(CATRES) + $(SIM65) $(SIM65FLAGS) $$@ $(CATRES) endef # PRG_template From a028ac4140127cfec5f546f6cfc151f25cbaaf98 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira <colin@colino.net> Date: Thu, 26 Jun 2025 13:08:04 +0200 Subject: [PATCH 633/707] Apple2: Fix permanently disabled IRQ Regression introduced in 990d65e: Pushing status, initializing IRQ handler (which enables IRQ) then pulling status re-disables IRQ. --- libsrc/apple2/crt0.s | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libsrc/apple2/crt0.s b/libsrc/apple2/crt0.s index 47ac70a7e..44450b4b9 100644 --- a/libsrc/apple2/crt0.s +++ b/libsrc/apple2/crt0.s @@ -56,9 +56,10 @@ init: ldx #zpspace-1 bpl :- ; Check for ProDOS. - ldy $BF00 ; MLI call entry point - cpy #$4C ; Is MLI present? (JMP opcode) - php ; Remember whether we're running ProDOS + lda $BF00 ; MLI call entry point + sec + sbc #$4C ; Is MLI present? (JMP opcode) + pha ; Backup the result for later bne basic ; Check the ProDOS system bit map. @@ -100,8 +101,8 @@ basic: lda HIMEM bit $C081 bit $C081 - plp ; Are we running ProDOS? - beq :+ ; Yes, no need to patch vectors + pla ; If not running ProDOS, we need to patch 6502 vectors. + beq :+ lda #<reset_6502 ldx #>reset_6502 From fed7276a631e20a39e44f031ebed12663e9b8f81 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 22:16:08 +0200 Subject: [PATCH 634/707] make makefiles in samples behave the same as the others --- samples/Makefile | 27 +++++++++++++++++++++++---- samples/apple2/Makefile | 13 +++++++++++++ samples/atari2600/Makefile | 9 +++++++++ samples/atari5200/Makefile | 9 +++++++++ samples/cbm/Makefile | 13 +++++++++++++ samples/disasm/Makefile | 9 +++++++++ samples/gamate/Makefile | 9 +++++++++ samples/geos/Makefile | 27 +++++++++++++++++++++++++-- samples/geos/grc/Makefile | 10 ++++++++++ samples/kim1/Makefile | 19 +++++++++++++++++++ samples/lynx/Makefile | 9 +++++++++ samples/sim65/Makefile | 9 +++++++++ samples/supervision/Makefile | 9 +++++++++ samples/sym1/Makefile | 14 ++++++++++++++ samples/tutorial/Makefile | 11 +++++++++++ 15 files changed, 191 insertions(+), 6 deletions(-) diff --git a/samples/Makefile b/samples/Makefile index dc0ea8f9f..4bb954ba1 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -47,6 +47,16 @@ else LD := $(if $(wildcard ../bin/ld65*),../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: + PQ = "QUIET=1" + PD = --no-print-directory +endif + ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) ifdef CC65_HOME TARGET_PATH = $(CC65_HOME)/target @@ -152,10 +162,13 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000 .o: ifeq ($(SYS),vic20) + $(if $(QUIET),echo $(SYS):$@) $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib else ifeq ($(SYS),plus4) + $(if $(QUIET),echo $(SYS):$@) $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -C plus4-hires.cfg -m $@.map $^ $(SYS).lib else + $(if $(QUIET),echo $(SYS):$@) $(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib endif @@ -387,7 +400,7 @@ endif define SUBDIR_recipe -@+$(MAKE) -C $(dir) --no-print-directory $@ +@+$(MAKE) -C $(dir) $(PD) $@ $(PQ) endef # SUBDIR_recipe @@ -450,17 +463,23 @@ TARGETS := \ # -------------------------------------------------------------------------- # Rule to make the binaries for every platform +define TARGETDIR_recipe + +@+$(MAKE) -C $(dir) $(PD) $(PQ) + +endef # TARGETDIR_recipe + define TARGET_recipe @echo making samples for: $(T) -@$(MAKE) --no-print-directory clean SYS:=$(T) -@$(MAKE) -j2 SYS:=$(T) -@$(MAKE) --no-print-directory clean SYS:=$(T) +@$(MAKE) -j2 SYS:=$(T) $(PQ) +@$(MAKE) $(PD) clean SYS:=$(T) $(PQ) endef # TARGET_recipe platforms: $(foreach T,$(TARGETS),$(TARGET_recipe)) + $(foreach dir,$(DIRLIST),$(TARGETDIR_recipe)) # -------------------------------------------------------------------------- # Overlay rules. Overlays need special ld65 configuration files. Also, the diff --git a/samples/apple2/Makefile b/samples/apple2/Makefile index d9fa40f66..1f39296de 100644 --- a/samples/apple2/Makefile +++ b/samples/apple2/Makefile @@ -40,6 +40,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_apple2 = \ hgrshow \ hgrtest \ @@ -63,6 +71,7 @@ endif disk: hgr.dsk dhgr.dsk hgr.dsk: hgrshow hgrtest + $(if $(QUIET),echo $(SYS):$@) cp prodos.dsk $@ java -jar $(AC) -as $@ hgrshow <hgrshow java -jar $(AC) -as $@ hgrtest <hgrtest @@ -75,12 +84,15 @@ hgr.dsk: hgrshow hgrtest java -jar $(AC) -p $@ winston.hgr bin 0x2000 <winston.hgr hgrshow: hgrshow.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -Oirs -t apple2 --start-addr 0x4000 -m hgrshow.map $^ hgrtest: hgrtest.c werner.s + $(if $(QUIET),echo $(SYS):$@) $(CL) -Oirs -t apple2 -C apple2-hgr.cfg -m hgrtest.map $^ dhgr.dsk: dhgrshow + $(if $(QUIET),echo $(SYS):$@) cp prodos.dsk $@ java -jar $(AC) -as $@ dhgrshow <dhgrshow java -jar $(AC) -p $@ catface.dhgr bin 0x2000 <catface.dhgr @@ -91,6 +103,7 @@ dhgr.dsk: dhgrshow java -jar $(AC) -p $@ venice.dhgr bin 0x2000 <venice.dhgr dhgrshow: dhgrshow.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -Oirs -t apple2enh --start-addr 0x4000 -m dhgrshow.map $^ clean: diff --git a/samples/atari2600/Makefile b/samples/atari2600/Makefile index 71264792d..1573425e8 100644 --- a/samples/atari2600/Makefile +++ b/samples/atari2600/Makefile @@ -39,6 +39,14 @@ else SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_atari2600 = \ hello @@ -58,6 +66,7 @@ else endif hello: hello.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o hello -m hello.map hello.c clean: diff --git a/samples/atari5200/Makefile b/samples/atari5200/Makefile index 1bdf1b75d..4ef0b07e4 100644 --- a/samples/atari5200/Makefile +++ b/samples/atari5200/Makefile @@ -37,6 +37,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_atari5200 = \ hello @@ -56,6 +64,7 @@ else endif hello: hello.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t atari5200 -o hello hello.c clean: diff --git a/samples/cbm/Makefile b/samples/cbm/Makefile index a593569b0..e76ea1769 100644 --- a/samples/cbm/Makefile +++ b/samples/cbm/Makefile @@ -39,6 +39,14 @@ else SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),) ifdef CC65_HOME TARGET_PATH = $(CC65_HOME)/target @@ -139,12 +147,16 @@ else endif fire: fire.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o fire -m fire.map fire.c plasma: plasma.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o plasma -m plasma.map plasma.c nachtm: nachtm.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o nachtm -m nachtm.map nachtm.c hello: hello-asm.s + $(if $(QUIET),echo $(SYS):$@) # Use separate assembler ... $(AS) -t $(SYS) hello-asm.s # ... and linker commands ... @@ -171,6 +183,7 @@ $(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),s >$( endef # D64_WRITE_SEQ_recipe samples.d64: samples + $(if $(QUIET),echo $(SYS):$@) @$(C1541) -format "samples,00" d64 $@ >$(NULLDEV) $(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_PRG_recipe)) # $(foreach file,$(OVERLAYLIST),$(D64_WRITE_PRG_recipe)) diff --git a/samples/disasm/Makefile b/samples/disasm/Makefile index 6599915f6..df883fa7c 100644 --- a/samples/disasm/Makefile +++ b/samples/disasm/Makefile @@ -37,6 +37,14 @@ else DA := $(if $(wildcard ../../bin/da65*),../../bin/da65,da65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + CPP = cpp #CPPFLAGS = -DTEST_ERROR @@ -56,6 +64,7 @@ $(DAIS): fixed.da $(DA) --sync-lines -o $@ -i $< image.bin image.bin: image.s image.cfg + $(if $(QUIET),echo $(SYS):$@) $(CL) -t none -C image.cfg -o image.bin image.s clean: diff --git a/samples/gamate/Makefile b/samples/gamate/Makefile index 35aef293d..4f20f047a 100644 --- a/samples/gamate/Makefile +++ b/samples/gamate/Makefile @@ -37,6 +37,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_gamate = \ nachtm.bin @@ -56,6 +64,7 @@ else endif nachtm.bin: nachtm.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -Os -l nachtm.lst -t gamate -o nachtm.bin nachtm.c ../../util/gamate/gamate-fixcart nachtm.bin diff --git a/samples/geos/Makefile b/samples/geos/Makefile index ad4033f80..0ede7e78c 100644 --- a/samples/geos/Makefile +++ b/samples/geos/Makefile @@ -17,11 +17,15 @@ C1541 ?= c1541 ifeq ($(origin SYS),command line) ifeq ($(SYS),c64) override SYS = geos-cbm - $(info GEOS: c64 -> geos-cbm) + ifneq ($(SILENT),s) + $(info GEOS: c64 -> geos-cbm) + endif endif ifeq ($(SYS),apple2enh) override SYS = geos-apple - $(info GEOS: apple2enh -> geos-apple) + ifneq ($(SILENT),s) + $(info GEOS: apple2enh -> geos-apple) + endif endif endif @@ -55,6 +59,14 @@ else SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + DIRLIST = grc define SUBDIR_recipe @@ -111,36 +123,47 @@ bitmap.c: logo.pcx $(SP) -r logo.pcx -c geos-bitmap -w bitmap.c,ident=bitmap bitmap-demo.cvt: bitmap.c bitmap-demores.grc bitmap-demo.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o $@ -m bitmap-demo.map bitmap-demores.grc bitmap-demo.c filesel.cvt: fileselres.grc filesel.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o $@ -m filesel.map fileselres.grc filesel.c geosconio.cvt: geosconiores.grc geosconio.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o $@ -m geosconio.map geosconiores.grc geosconio.c geosver.cvt: geosverres.grc geosver.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o $@ -m geosver.map geosverres.grc geosver.c getid.cvt: getidres.grc getid.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o $@ -m getid.map getidres.grc getid.c hello1.cvt: hello1res.grc hello1.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o $@ -m hello1.map hello1res.grc hello1.c hello2.cvt: hello2res.grc hello2.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o $@ -m hello2.map hello2res.grc hello2.c overlay-demo.cvt: overlay-demores.grc overlay-demo.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o $@ -m overlay-demo.map overlay-demores.grc overlay-demo.c rmvprot.cvt: rmvprotres.grc rmvprot.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o $@ -m rmvprot.map rmvprotres.grc rmvprot.c vector-demo.cvt: vector-demores.grc vector-demo.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o $@ -m vector-demo.map vector-demores.grc vector-demo.c yesno.cvt: yesnores.grc yesno.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o $@ -m yesno.map yesnores.grc yesno.c diff --git a/samples/geos/grc/Makefile b/samples/geos/grc/Makefile index 360c7bc7d..101d501e8 100644 --- a/samples/geos/grc/Makefile +++ b/samples/geos/grc/Makefile @@ -39,6 +39,14 @@ else GRC := $(if $(wildcard ../../../bin/grc65*),../../../bin/grc65,grc65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_geos-cbm = \ test.s \ vlir.cvt @@ -56,9 +64,11 @@ samples: endif test.s: test.grc + $(if $(QUIET),echo $(SYS):$@) $(GRC) -s test.s test.grc vlir.cvt: vlir.grc vlir0.s vlir1.s vlir2.s + $(if $(QUIET),echo $(SYS):$@) # using separate calls here for demonstration purposes: $(GRC) -t $(SYS) -s vlir.s vlir.grc $(AS) -t $(SYS) vlir.s diff --git a/samples/kim1/Makefile b/samples/kim1/Makefile index dbdbcec8d..eca7d6524 100644 --- a/samples/kim1/Makefile +++ b/samples/kim1/Makefile @@ -37,6 +37,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_kim1 = \ kimHello.bin \ kimSieve.bin \ @@ -66,40 +74,51 @@ ramfont.o: ramfont.asm $(AS) ramfont.asm -o ramfont.o kimLife.bin: kimLife.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t kim1 -C kim1-60k.cfg -Oi -o kimLife.bin kimLife.c kimTest.bin: kimTest.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t kim1 -C kim1-60k.cfg -Oi -o kimTest.bin kimTest.c kimGFX.bin: kimGFX.c subs.o ramfont.o + $(if $(QUIET),echo $(SYS):$@) $(CL) -t kim1 --listing kimGFX.lst -C kim1-mtuE000.cfg -o kimGFX.bin kimGFX.c subs.o ramfont.o -Ln kimgfx.lbl kimSieve.bin: kimSieve.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t kim1 -C kim1-60k.cfg -O -o kimSieve.bin kimSieve.c kimHello.bin: kimHello.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t kim1 -O -o kimHello.bin kimHello.c # To build an intel-format file for the CORSHAM SD card reader kimLife.hex: kimLife.bin + $(if $(QUIET),echo $(SYS):$@) srec_cat kimLife.bin -binary -offset 0x2000 -o kimLife.hex -Intel -address-length=2 kimTest.hex: kimTest.bin + $(if $(QUIET),echo $(SYS):$@) srec_cat kimTest.bin -binary -offset 0x2000 -o kimTest.hex -Intel -address-length=2 kimGFX.hex: kimGFX.bin ramfont.o + $(if $(QUIET),echo $(SYS):$@) srec_cat kimGFX.bin -binary -offset 0x2000 -o kimGFX.hex -Intel -address-length=2 # To build a paper tape file for uploading to the KIM-1 via terminal kimLife.ptp: kimLife.bin + $(if $(QUIET),echo $(SYS):$@) srec_cat kimLife.bin -binary -offset 0x2000 -o kimLife.ptp -MOS_Technologies kimGFX.ptp: kimGFX.bin + $(if $(QUIET),echo $(SYS):$@) srec_cat kimGFX.bin -binary -offset 0x2000 -o kimGFX.ptp -MOS_Technologies kimTest.ptp: kimTest.bin + $(if $(QUIET),echo $(SYS):$@) srec_cat kimTest.bin -binary -offset 0x2000 -o kimTest.ptp -MOS_Technologies clean: diff --git a/samples/lynx/Makefile b/samples/lynx/Makefile index 078ea129a..e27d5801a 100644 --- a/samples/lynx/Makefile +++ b/samples/lynx/Makefile @@ -35,6 +35,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_lynx = \ hello.lnx \ mandelbrot.lnx \ @@ -59,6 +67,7 @@ endif .SUFFIXES: .c .lnx %.lnx : %.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -Oris -m $*.map -o $@ $< clean: diff --git a/samples/sim65/Makefile b/samples/sim65/Makefile index 3a06321ee..43783afca 100644 --- a/samples/sim65/Makefile +++ b/samples/sim65/Makefile @@ -37,6 +37,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_sim6502 = \ cpumode_example.bin \ timer_example.bin \ @@ -61,6 +69,7 @@ endif .SUFFIXES: .c .bin %.bin : %.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -Oris -m $*.map -o $@ $< clean: diff --git a/samples/supervision/Makefile b/samples/supervision/Makefile index 9396be63d..cae5885ff 100644 --- a/samples/supervision/Makefile +++ b/samples/supervision/Makefile @@ -39,6 +39,14 @@ else SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_supervision = \ hello @@ -58,6 +66,7 @@ else endif hello: hello.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o hello -m hello.map hello.c clean: diff --git a/samples/sym1/Makefile b/samples/sym1/Makefile index 8abcfb5aa..a5b2e35b5 100644 --- a/samples/sym1/Makefile +++ b/samples/sym1/Makefile @@ -37,6 +37,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_sym1 = \ symHello.bin symTiny.bin symDisplay.bin symIO.bin symNotepad.bin symExtendedMemory.bin @@ -56,21 +64,27 @@ else endif symHello.bin: symHello.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t sym1 -O -o symHello.bin symHello.c symTiny.bin: symTiny.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t sym1 -O -o symTiny.bin symTiny.c symDisplay.bin: symDisplay.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t sym1 -O -o symDisplay.bin symDisplay.c symIO.bin: symIO.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t sym1 -C sym1-32k.cfg -O -o symIO.bin symIO.c symNotepad.bin: symNotepad.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t sym1 -C sym1-32k.cfg -O -o symNotepad.bin symNotepad.c symExtendedMemory.bin: symExtendedMemory.c + $(if $(QUIET),echo $(SYS):$@) $(CL) -t sym1 -C sym1-32k.cfg -O -o symExtendedMemory.bin symExtendedMemory.c diff --git a/samples/tutorial/Makefile b/samples/tutorial/Makefile index 685c8dd69..3c3d1edb9 100644 --- a/samples/tutorial/Makefile +++ b/samples/tutorial/Makefile @@ -37,6 +37,14 @@ else LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif + EXELIST_atari2600 = \ notavailable @@ -86,9 +94,12 @@ ifndef EXELIST_$(SYS) EXELIST_$(SYS) := ${patsubst %.c,%,$(wildcard *.c)} endif +all: samples + samples: $(EXELIST_$(SYS)) hello: hello.c text.s + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -o hello hello.c text.s # empty target used to skip systems that will not work with any program in this dir From 000789de9564190527cf9fe864f56de253d0e3f1 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 22:36:12 +0200 Subject: [PATCH 635/707] adjust makefiles in util to common behaviour --- util/Makefile | 21 +++++++++++++++------ util/atari/Makefile | 8 ++++++++ util/gamate/Makefile | 8 ++++++++ util/zlib/Makefile | 8 ++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/util/Makefile b/util/Makefile index 337320d36..96d2ec629 100644 --- a/util/Makefile +++ b/util/Makefile @@ -4,6 +4,15 @@ ifneq ($(SILENT),s) $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: + PQ = "QUIET=1" + PD = --no-print-directory +endif .PHONY: atari gamate zlib @@ -12,16 +21,16 @@ util: atari gamate zlib all: util atari: - @$(MAKE) -C atari --no-print-directory $@ + @$(MAKE) -C atari $(PD) $(PQ) gamate: - @$(MAKE) -C gamate --no-print-directory $@ + @$(MAKE) -C gamate $(PD) $(PQ) zlib: - @$(MAKE) -C zlib --no-print-directory $@ + @$(MAKE) -C zlib $(PD) $(PQ) mostlyclean clean: - @$(MAKE) -C atari --no-print-directory $@ - @$(MAKE) -C gamate --no-print-directory $@ - @$(MAKE) -C zlib --no-print-directory $@ + @$(MAKE) -C atari $(PD) $@ $(PQ) + @$(MAKE) -C gamate $(PD) $@ $(PQ) + @$(MAKE) -C zlib $(PD) $@ $(PQ) install zip: diff --git a/util/atari/Makefile b/util/atari/Makefile index aa3163ec4..74b7ee78a 100644 --- a/util/atari/Makefile +++ b/util/atari/Makefile @@ -4,6 +4,13 @@ ifneq ($(SILENT),s) $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif CC = $(CROSS_COMPILE)gcc @@ -28,6 +35,7 @@ CFLAGS += -O3 -Wall -Wextra -Wno-char-subscripts $(USER_CFLAGS) atari: ataricvt ataricvt: ataricvt.c + $(if $(QUIET),echo HOST:$@) $(CC) $(CFLAGS) -o ataricvt ataricvt.c mostlyclean clean: diff --git a/util/gamate/Makefile b/util/gamate/Makefile index d9b4bbd42..7d1681c37 100644 --- a/util/gamate/Makefile +++ b/util/gamate/Makefile @@ -4,6 +4,13 @@ ifneq ($(SILENT),s) $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif CC = $(CROSS_COMPILE)gcc @@ -28,6 +35,7 @@ CFLAGS += -O3 -Wall -Wextra -Wno-char-subscripts $(USER_CFLAGS) gamate: gamate-fixcart gamate-fixcart: gamate-fixcart.c + $(if $(QUIET),echo HOST:$@) $(CC) $(CFLAGS) -o gamate-fixcart gamate-fixcart.c mostlyclean clean: diff --git a/util/zlib/Makefile b/util/zlib/Makefile index 8068ea120..5778ae821 100644 --- a/util/zlib/Makefile +++ b/util/zlib/Makefile @@ -4,6 +4,13 @@ ifneq ($(SILENT),s) $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: +endif CC = $(CROSS_COMPILE)gcc @@ -35,6 +42,7 @@ warning: @echo "note that you need zlib installed first" deflater: deflater.c + $(if $(QUIET),echo HOST:$@) $(CC) $(CFLAGS) -o deflater deflater.c -lz mostlyclean clean: From 261180577ccaf668b73b22bee2d840fa241c59a4 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 22:44:26 +0200 Subject: [PATCH 636/707] add subdirs to "platforms" --- targettest/Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/targettest/Makefile b/targettest/Makefile index edddca0f2..329992d18 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -791,6 +791,12 @@ TARGETS := \ # -------------------------------------------------------------------------- # Rule to make the binaries for every platform +define TARGETDIR_recipe + +@+$(MAKE) -C $(dir) $(PD) $(PQ) + +endef # TARGETDIR_recipe + define TARGET_recipe @echo making targettest for: $(T) @@ -801,6 +807,7 @@ endef # TARGET_recipe platforms: $(foreach T,$(TARGETS),$(TARGET_recipe)) + $(foreach dir,$(DIRLIST),$(TARGETDIR_recipe)) # -------------------------------------------------------------------------- # some programs link against getsp.o From 703b166b295c6f09fe61b7fd97a69b255815a5ac Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 23:18:35 +0200 Subject: [PATCH 637/707] handle -s and QUIET accordingly in libsrc too. those who never used make -s before might start doing it now :) --- libsrc/Makefile | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/libsrc/Makefile b/libsrc/Makefile index 9bbb0aadb..586ce3c03 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -8,6 +8,16 @@ ifneq ($(shell echo),) CMD_EXE = 1 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + +ifdef QUIET + .SILENT: + PQ = "QUIET=1" + PD = --no-print-directory +endif + CBMS = c128 \ c16 \ c64 \ @@ -134,7 +144,7 @@ zip: $(foreach dir,$(OUTPUTDIRS),$(ZIP_recipe)) $(TARGETS): | ../lib - @$(MAKE) --no-print-directory $@ + @$(MAKE) $(PD) $@ $(PQ) # ../lib must be created globally before doing lib targets in parallel ../lib: @@ -259,8 +269,8 @@ $1_DYNS = $$(patsubst $$($1_SRCPAT),$$($1_DYNPAT),$$($1_SRCS)) $1_DRVS = $$(patsubst $$($1_DYNPAT),$$($1_DRVPAT),$$($1_DYNS)) $$($1_STCPAT): $$($1_SRCPAT) - @echo $$(TARGET) - $$< - static - @$$(CA65) -t $$(TARGET) -D DYN_DRV=0 $$(CA65FLAGS) --create-dep $$(@:.o=.d) -o $$@ $$< + $$(if $$(QUIET),@echo $$(TARGET) - $$< - static) + $$(CA65) -t $$(TARGET) -D DYN_DRV=0 $$(CA65FLAGS) --create-dep $$(@:.o=.d) -o $$@ $$< OBJS += $$($1_STCS) DEPS += $$($1_STCS:.o=.d) @@ -268,8 +278,8 @@ DEPS += $$($1_STCS:.o=.d) $$($1_DYNS): | $$($1_DYNDIR) $$($1_DRVPAT): $$($1_DYNPAT) $$(ZPOBJ) | $$($1_DRVDIR) - @echo $$(TARGET) - $$(<F) - @$$(LD65) -o $$@ -t module $$^ + $$(if $$(QUIET),@echo $$(TARGET) - $$(<F)) + $$(LD65) -o $$@ -t module $$^ $$($1_DYNDIR) $$($1_DRVDIR): @$$(call MKDIR,$$@) @@ -291,16 +301,16 @@ export CC65_HOME := $(abspath ..) define ASSEMBLE_recipe -$(if $(QUIET),,@echo $(TARGET) - $<) -@$(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:.o=.d) -o $@ $< + $(if $(QUIET),@echo $(TARGET) - $<) + $(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:.o=.d) -o $@ $< endef # ASSEMBLE_recipe define COMPILE_recipe -$(if $(QUIET),,@echo $(TARGET) - $<) -@$(CC65) -t $(TARGET) $(CC65FLAGS) --create-dep $(@:.o=.d) --dep-target $@ -o $(@:.o=.s) $< -@$(CA65) -t $(TARGET) -o $@ $(@:.o=.s) + $(if $(QUIET),@echo $(TARGET) - $<) + $(CC65) -t $(TARGET) $(CC65FLAGS) --create-dep $(@:.o=.d) --dep-target $@ -o $(@:.o=.s) $< + $(CA65) -t $(TARGET) -o $@ $(@:.o=.s) endef # COMPILE_recipe @@ -311,12 +321,13 @@ endef # COMPILE_recipe $(COMPILE_recipe) $(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../libwrk/$(TARGET) ../lib - @echo $(TARGET) - $(<F) + $(if $(QUIET),@echo $(TARGET) - $(<F)) @$(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:../lib/%.o=../libwrk/$(TARGET)/%.d) -o $@ $< $(EXTRA_OBJS): | ../lib ../lib/$(TARGET).lib: $(OBJS) | ../lib + $(if $(QUIET),@echo $(TARGET) - $<) $(AR65) a $@ $? ../libwrk/$(TARGET) ../target/$(TARGET)/util: From 0c22e310ef07a3457db94704a368a45697385dec Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 23:44:56 +0200 Subject: [PATCH 638/707] ...and patch the Makefile in src the same way --- src/Makefile | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/Makefile b/src/Makefile index 085a50f9d..bdeaf4bc9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,12 +8,6 @@ ifneq ($(shell echo),) CMD_EXE = 1 endif -ifneq ($(V),1) - Q=@ -else - Q= -endif - PROGS = ar65 \ ca65 \ cc65 \ @@ -52,6 +46,21 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET = 1 + NULLOUT = >$(NULLDEV) + NULLERR = 2>$(NULLDEV) +endif + +ifdef QUIET + .SILENT: + PQ = "QUIET=1" + PD = --no-print-directory +ifndef CMD_EXE + CATERR = 2> ../wrk/common/$$@.errlog || (cat ../wrk/common/$$@.errlog && false) +endif +endif + CC = $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar @@ -70,7 +79,10 @@ ifndef BUILD_ID BUILD_ID := N/A endif endif -$(info BUILD_ID: $(BUILD_ID)) + +ifneq ($(SILENT),s) + $(info BUILD_ID: $(BUILD_ID)) +endif CFLAGS += -MMD -MP -O3 -I common \ -Wall -Wextra -Wno-char-subscripts $(USER_CFLAGS) \ @@ -161,8 +173,8 @@ $1: ../bin/$1$(EXE_SUFFIX) endef # PROG_template ../wrk/%.o: %.c - @echo $< - $(Q)$(CC) -c $(CFLAGS) -o $@ $< + $(if $(QUIET),echo CC:$@) + $(CC) -c $(CFLAGS) -o $@ $< ../bin: @$(call MKDIR,$@) @@ -170,7 +182,8 @@ endef # PROG_template $(eval $(call OBJS_template,common)) ../wrk/common/common.a: $(common_OBJS) - $(AR) r $@ $? + $(if $(QUIET),echo AR:$@) + $(AR) r $@ $? $(CATERR) $(foreach prog,$(PROGS),$(eval $(call PROG_template,$(prog)))) @@ -184,6 +197,7 @@ $(eval $(call OBJS_template,dbginfo)) dbginfo: $(dbginfo_OBJS) ../wrk/dbgsh$(EXE_SUFFIX): $(dbginfo_OBJS) ../wrk/common/common.a + $(if $(QUIET),echo LINK:$@) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) dbgsh: ../wrk/dbgsh$(EXE_SUFFIX) From 1f1e1f1490c167e02c53e79e35d060608386fd50 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Thu, 26 Jun 2025 23:53:36 +0200 Subject: [PATCH 639/707] output target before name(s) --- targettest/Makefile | 7 +++++-- targettest/accelerator/Makefile | 16 ++++++++-------- targettest/atari/Makefile | 18 +++++++++--------- targettest/cbm/Makefile | 6 +++--- targettest/gamate/Makefile | 6 +++--- targettest/pce/Makefile | 2 +- 6 files changed, 29 insertions(+), 26 deletions(-) diff --git a/targettest/Makefile b/targettest/Makefile index 329992d18..ebdecfba6 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -130,12 +130,12 @@ DISK_atarixl = testcode.atr %: %.s .c.o: - $(if $(QUIET),echo targettest/$*.c) + $(if $(QUIET),echo $(SYS):$*.c) $(CC) $(CFLAGS) -Ors --codesize 500 -T -g -t $(SYS) $< $(AS) $(<:.c=.s) .s.o: - $(if $(QUIET),echo targettest/$*.s) + $(if $(QUIET),echo $(SYS):$*.s) $(AS) $(ASFLAGS) -t $(SYS) $< .PRECIOUS: %.o @@ -813,10 +813,12 @@ platforms: # some programs link against getsp.o mouse-test: mouse-test.o getsp.o + $(if $(QUIET),echo $(SYS):$@) $(LD) $(LDFLAGS) -t $(SYS) -o $@ $^ $(SYS).lib ifneq ($(SYS),vic20) ft: ft.o getsp.o + $(if $(QUIET),echo $(SYS):$@) $(LD) $(LDFLAGS) -t $(SYS) -o $@ $^ $(SYS).lib endif @@ -824,6 +826,7 @@ endif ifeq ($(SYS),vic20) ft: ft.o getsp.o + $(if $(QUIET),echo $(SYS):$@) $(LD) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib endif diff --git a/targettest/accelerator/Makefile b/targettest/accelerator/Makefile index 0a6a9bb02..a8d26e368 100644 --- a/targettest/accelerator/Makefile +++ b/targettest/accelerator/Makefile @@ -72,35 +72,35 @@ else endif c64-scpu-test.prg: c64-c128-scpu-test.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg c128-scpu-test.prg: c64-c128-scpu-test.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t c128 c64-c128-scpu-test.c -o c128-scpu-test.prg c64dtv-test.prg: c64dtv-test.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t c64 c64dtv-test.c -o c64dtv-test.prg c64-test.prg: c64-c128-test.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t c64 c64-c128-test.c -o c64-test.prg c128-test.prg: c64-c128-test.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t c128 c64-c128-test.c -o c128-test.prg chameleon-test.prg: chameleon-test.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t c64 chameleon-test.c -o chameleon-test.prg c65-test.prg: c65-test.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t c64 c65-test.c -o c65-test.prg turbomaster-test.prg: turbomaster-test.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t c64 turbomaster-test.c -o turbomaster-test.prg clean: diff --git a/targettest/atari/Makefile b/targettest/atari/Makefile index ef8d1883c..099dd291c 100644 --- a/targettest/atari/Makefile +++ b/targettest/atari/Makefile @@ -72,33 +72,33 @@ else endif charmapping.xex: charmapping.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t atari -o charmapping.xex charmapping.c defdev.xex: defdev.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t atari -o defdev.xex defdev.c displaylist.xex: displaylist.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t atari -o displaylist.xex displaylist.c mem.xex: mem.c ../getsp.s - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t atari -o mem.xex mem.c ../getsp.s multi.xex: multi-xex.s multi-xex.cfg - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t atari -C multi-xex.cfg multi-xex.s -o multi.xex ostype.xex: ostype.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t atari -o ostype.xex ostype.c scrcode.com: scrcode.s - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) # ca65 -t atari -o scrcode.o scrcode.s # ld65 -C atari-asm.cfg -o scrcode.com scrcode.o $(CL) -t atari -C atari-asm.cfg -o scrcode.com scrcode.s sys.xex: sys.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t atari -o sys.xex sys.c sound.xex: sound.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t atari -o sound.xex sound.c clean: @$(DEL) charmapping.xex 2>$(NULLDEV) diff --git a/targettest/cbm/Makefile b/targettest/cbm/Makefile index 96acf49a0..6359a154a 100644 --- a/targettest/cbm/Makefile +++ b/targettest/cbm/Makefile @@ -81,14 +81,14 @@ endif ifeq ($(SYS),c64) petscii.prg: petscii.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t $(SYS) -O -o petscii.prg petscii.c else petscii.prg: endif cbmdir-test.prg: cbmdir-test.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) ifeq ($(SYS),vic20) $(CL) -t $(SYS) -C vic20-32k.cfg -Oris -o $@ $< else @@ -96,7 +96,7 @@ else endif cbmread.prg: cbmread.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) ifeq ($(SYS),vic20) $(CL) -t $(SYS) -C vic20-32k.cfg -Oris -o $@ $< else diff --git a/targettest/gamate/Makefile b/targettest/gamate/Makefile index 3e3d1f9d8..21fd039ec 100644 --- a/targettest/gamate/Makefile +++ b/targettest/gamate/Makefile @@ -64,13 +64,13 @@ else endif audiotest.bin: audiotest.s - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -l audiotest.lst -t gamate -o audiotest.bin audiotest.s lcdtest.bin: lcdtest.s - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -l lcdtest.lst -t gamate -o lcdtest.bin lcdtest.s ctest.bin: ctest.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -l ctest.lst -t gamate -o ctest.bin ctest.c clean: diff --git a/targettest/pce/Makefile b/targettest/pce/Makefile index 2a0be84d5..53516d55d 100644 --- a/targettest/pce/Makefile +++ b/targettest/pce/Makefile @@ -79,7 +79,7 @@ else endif %.bin: %.c - $(if $(QUIET),echo $@) + $(if $(QUIET),echo $(SYS):$@) $(CL) -t pce $< -Wl -D__CARTSIZE__=${CARTSIZE} -m $*.map -o $@ ifndef QUIET @echo "use 'make conio.pce' to produce a .pce file using dd" From 0d98ab42f03de4e8d5693892dd7737e3ddc49441 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 27 Jun 2025 00:00:48 +0200 Subject: [PATCH 640/707] pass QUIET in the workflows --- .github/workflows/build-on-pull-request.yml | 16 ++++++++-------- .github/workflows/snapshot-on-push-master.yml | 18 +++++++++--------- .github/workflows/windows-test-scheduled.yml | 8 ++++---- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index b577e4b03..7f80663f2 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -29,29 +29,29 @@ jobs: run: make -j2 sorted - name: Build the tools. shell: bash - run: make -j2 bin USER_CFLAGS=-Werror + run: make -j2 bin USER_CFLAGS=-Werror QUIET=1 - name: Build the dbginfo example shell: bash - run: make -j2 -C src test + run: make -j2 -C src test QUIET=1 - name: Build the utilities. shell: bash - run: make -j2 util + run: make -j2 util QUIET=1 - name: Build the platform libraries. shell: bash run: make -j2 lib QUIET=1 - name: check test that no modules use sp shell: bash - run: make -j2 checksp QUIET=1 + run: make -j2 checksp QUIET=1 - name: Run the regression tests. shell: bash run: make -j2 test QUIET=1 - name: Test that the samples can be built. - run: make -C samples platforms + run: make -C samples platforms QUIET=1 - name: Test that the targettest programs can be built. - run: make -C targettest platforms + run: make -C targettest platforms QUIET=1 - name: Build the document files. shell: bash - run: make -j2 doc + run: make -j2 doc QUIET=1 - name: Upload a documents snapshot. uses: actions/upload-artifact@v4 with: @@ -90,7 +90,7 @@ jobs: - name: Build utils (MinGW) shell: cmd - run: make -j2 util SHELL=cmd + run: make -j2 util QUIET=1 SHELL=cmd - name: Build the platform libraries (make lib) shell: cmd diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index 557ba24af..c9c8a0c47 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -55,8 +55,8 @@ jobs: - name: Build the tools. shell: bash run: | - make -j2 bin USER_CFLAGS=-Werror - make -j2 util + make -j2 bin USER_CFLAGS=-Werror QUIET=1 + make -j2 util QUIET=1 - name: Build the platform libraries. shell: bash run: make -j2 lib QUIET=1 @@ -65,26 +65,26 @@ jobs: run: make -j2 test QUIET=1 - name: Test that the samples can be built. shell: bash - run: make -j2 samples + run: make -j2 samples QUIET=1 - name: Remove the output from the samples tests. shell: bash - run: make -C samples clean + run: make -C samples clean QUIET=1 - name: Remove programs in util directory shell: bash - run: make -C util clean + run: make -C util clean QUIET=1 - name: Build the document files. shell: bash - run: make -j2 doc + run: make -j2 doc QUIET=1 - name: Build and package 64-bit Windows versions of the tools. run: | - make -C src clean + make -C src clean QUIET=1 make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=x86_64-w64-mingw32- make zip mv cc65.zip cc65-snapshot-win64.zip - name: Build and package 32-bit Windows versions of the tools. run: | - make -C src clean - make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=i686-w64-mingw32- + make -C src clean QUIET=1 + make -j2 bin USER_CFLAGS=-Werror QUIET=1 CROSS_COMPILE=i686-w64-mingw32- make zip mv cc65.zip cc65-snapshot-win32.zip diff --git a/.github/workflows/windows-test-scheduled.yml b/.github/workflows/windows-test-scheduled.yml index fa22473f4..2e24e1d01 100644 --- a/.github/workflows/windows-test-scheduled.yml +++ b/.github/workflows/windows-test-scheduled.yml @@ -60,19 +60,19 @@ jobs: - name: Build utils (MinGW) if: steps.check-sha.outputs.cache-hit != 'true' shell: cmd - run: make -j2 util SHELL=cmd + run: make -j2 util SHELL=cmd QUIET=1 - name: Build the platform libraries (make lib) if: steps.check-sha.outputs.cache-hit != 'true' shell: cmd - run: make -j2 lib QUIET=1 SHELL=cmd + run: make -j2 lib QUIET=1 SHELL=cmd QUIET=1 - name: Run the regression tests (make test) if: steps.check-sha.outputs.cache-hit != 'true' shell: cmd - run: make -j2 test QUIET=1 SHELL=cmd + run: make -j2 test QUIET=1 SHELL=cmd QUIET=1 - name: Test that the samples can be built (make samples) if: steps.check-sha.outputs.cache-hit != 'true' shell: cmd - run: make -j2 samples SHELL=cmd + run: make -j2 samples SHELL=cmd QUIET=1 From ecdc59de474f654ef92c51adc598034d086ce815 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 27 Jun 2025 00:10:07 +0200 Subject: [PATCH 641/707] more QUIET=1 --- .github/workflows/build-on-pull-request.yml | 4 ++-- .github/workflows/snapshot-on-push-master.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 7f80663f2..f5aacca31 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -59,8 +59,8 @@ jobs: path: ./html - name: Build 64-bit Windows versions of the tools. run: | - make -C src clean - make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=x86_64-w64-mingw32- + make -C src clean QUIET=1 + make -j2 bin QUIET=1 USER_CFLAGS=-Werror CROSS_COMPILE=x86_64-w64-mingw32- build_windows: name: Build and Test (Windows) diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index c9c8a0c47..591b221be 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -78,7 +78,7 @@ jobs: - name: Build and package 64-bit Windows versions of the tools. run: | make -C src clean QUIET=1 - make -j2 bin USER_CFLAGS=-Werror CROSS_COMPILE=x86_64-w64-mingw32- + make -j2 bin QUIET=1 USER_CFLAGS=-Werror CROSS_COMPILE=x86_64-w64-mingw32- make zip mv cc65.zip cc65-snapshot-win64.zip - name: Build and package 32-bit Windows versions of the tools. From 74a22621574a401abf93b21c40777b9075601ef2 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 27 Jun 2025 17:26:11 +0200 Subject: [PATCH 642/707] hotfix --- asminc/zeropage.inc | 8 ++++++++ libsrc/runtime/sp-compat.s | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/asminc/zeropage.inc b/asminc/zeropage.inc index 2d4b144db..8d508fc5a 100644 --- a/asminc/zeropage.inc +++ b/asminc/zeropage.inc @@ -13,10 +13,18 @@ .globalzp tmp1, tmp2, tmp3, tmp4 .globalzp regbank +; FIXME: there must be a less ugly way to do this +.ifp4510 +.else +.ifp45GS02 +.else + ; The following symbol is supplied for compatibility reasons only, it ; will get removed in future versions. Using it will cause a linker ; warning. .globalzp sp +.endif +.endif ; The size of the register bank diff --git a/libsrc/runtime/sp-compat.s b/libsrc/runtime/sp-compat.s index 797fef47b..77972212f 100644 --- a/libsrc/runtime/sp-compat.s +++ b/libsrc/runtime/sp-compat.s @@ -5,7 +5,15 @@ ; linker warning if it is used. Added after renaming "sp" to "c_sp". ; +; FIXME: there must be a less ugly way to do this +.ifp4510 +.else +.ifp45GS02 +.else + .include "zeropage.inc" .export sp := c_sp .assert 0, ldwarning, "Symbol 'sp' is deprecated - please use 'c_sp' instead" +.endif +.endif From 0d28f6ff8c9e049fc24e047db2f4ee4ff5872e4a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 27 Jun 2025 17:32:20 +0200 Subject: [PATCH 643/707] fix test --- test/asm/listing/080-sp-compat.s | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/asm/listing/080-sp-compat.s b/test/asm/listing/080-sp-compat.s index 8c22a71d3..54c48e8c3 100644 --- a/test/asm/listing/080-sp-compat.s +++ b/test/asm/listing/080-sp-compat.s @@ -1,7 +1,16 @@ .include "zeropage.inc" +; FIXME: there must be a less ugly way to do this +.ifp4510 +.else +.ifp45GS02 +.else + .proc _func ldy #0 lda (sp),y rts .endproc + +.endif +.endif From 0a5211dcaa4d1825ed38f97afc1d162850c934c6 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 27 Jun 2025 17:39:04 +0200 Subject: [PATCH 644/707] ...and the reference for the test --- test/asm/listing/ref/080-sp-compat.ld65err2-ref | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/asm/listing/ref/080-sp-compat.ld65err2-ref b/test/asm/listing/ref/080-sp-compat.ld65err2-ref index fe2611088..78935d2b3 100644 --- a/test/asm/listing/ref/080-sp-compat.ld65err2-ref +++ b/test/asm/listing/ref/080-sp-compat.ld65err2-ref @@ -1 +1 @@ -ld65: Warning: runtime/sp-compat.s:10: Symbol 'sp' is deprecated - please use 'c_sp' instead +ld65: Warning: runtime/sp-compat.s:16: Symbol 'sp' is deprecated - please use 'c_sp' instead From 76aa7cbc40ef8e2cde5aa18c2dfcc360f99d00d7 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Fri, 27 Jun 2025 19:40:41 +0200 Subject: [PATCH 645/707] add names and bit(field)s for WDC65C02 and 65CE02 --- asminc/cpu.mac | 4 ++++ src/common/cpu.c | 12 ++++++++---- src/common/cpu.h | 10 +++++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index c66641078..728c99262 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -12,6 +12,8 @@ CPU_ISET_HUC6280 = $0100 CPU_ISET_M740 = $0200 CPU_ISET_4510 = $0400 CPU_ISET_45GS02 = $0800 +CPU_ISET_W65C02 = $1000 +CPU_ISET_65CE02 = $2000 ; CPU capabilities ; make sure to only combine the instruction sets that are 100% compatible @@ -31,3 +33,5 @@ CPU_HUC6280 = CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02 CPU_4510 = CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 CPU_45GS02 = CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_4510 CPU_M740 = CPU_ISET_M740 | CPU_ISET_6502 +CPU_W65C02 = CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 +CPU_65CE02 = CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 diff --git a/src/common/cpu.c b/src/common/cpu.c index 54bb8a3fb..31fa8d7bf 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -56,14 +56,16 @@ const char* CPUNames[CPU_COUNT] = { "6502", "6502X", "6502DTV", - "65SC02", - "65C02", + "65SC02", /* the original CMOS instruction set */ + "65C02", /* CMOS with Rockwell extensions */ "65816", "sweet16", "huc6280", "m740", "4510", "45GS02" + "W65C02", /* CMOS with WDC extensions */ + "65CE02", /* CMOS with GTE extensions */ }; /* Tables with CPU instruction sets @@ -84,8 +86,10 @@ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_M740 | CPU_ISET_6502, /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ /* FIXME: 4510 does not have wai/stp */ - CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02, - CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_4510, + CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02, + CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_4510, + CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, }; diff --git a/src/common/cpu.h b/src/common/cpu.h index 81795e146..0784600f7 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -51,14 +51,16 @@ typedef enum { CPU_6502, CPU_6502X, /* "Extended", that is: with illegal opcodes */ CPU_6502DTV, /* CPU_6502 + DTV extra and illegal opcodes */ - CPU_65SC02, - CPU_65C02, + CPU_65SC02, /* the original CMOS instruction set */ + CPU_65C02, /* CMOS with Rockwell extensions */ CPU_65816, CPU_SWEET16, CPU_HUC6280, /* Used in PC engine */ CPU_M740, /* Mitsubishi 740 series MCUs */ CPU_4510, /* CPU of C65 */ CPU_45GS02, /* CPU of MEGA65 */ + CPU_W65C02, /* CMOS with WDC extensions */ + CPU_65CE02, /* CMOS with GTE extensions */ CPU_COUNT /* Number of different CPUs */ } cpu_t; @@ -75,7 +77,9 @@ enum { CPU_ISET_HUC6280 = 1 << CPU_HUC6280, CPU_ISET_M740 = 1 << CPU_M740, CPU_ISET_4510 = 1 << CPU_4510, - CPU_ISET_45GS02 = 1 << CPU_45GS02 + CPU_ISET_45GS02 = 1 << CPU_45GS02, + CPU_ISET_W65C02 = 1 << CPU_W65C02, + CPU_ISET_65CE02 = 1 << CPU_65CE02 }; /* CPU used */ From e93356e3bbd0a81392a43649cb32cca2dbab474c Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 00:38:16 +0200 Subject: [PATCH 646/707] add 65CE02 table --- src/ca65/instr.c | 269 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 263 insertions(+), 6 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index c19be11b2..b920755d3 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -426,7 +426,7 @@ static const struct { } }; -/* Instruction table for the 65SC02 */ +/* Instruction table for the 65SC02 (original CMOS) */ static const struct { unsigned Count; InsDesc Ins[66]; @@ -505,14 +505,125 @@ static const struct { } }; -/* Instruction table for the 65C02 */ +/* Instruction table for the 65C02 (CMOS with Rockwell extensions) */ static const struct { unsigned Count; - InsDesc Ins[100]; + InsDesc Ins[98]; } InsTab65C02 = { /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab65C02.Ins) / sizeof (InsTab65C02.Ins[0]), { +/* BEGIN SORTED.SH */ + { "ADC", 0x080A66C, 0x60, 0, PutAll }, + { "AND", 0x080A66C, 0x20, 0, PutAll }, + { "ASL", 0x000006e, 0x02, 1, PutAll }, + { "BBR0", 0x0000000, 0x0F, 0, PutBitBranch }, + { "BBR1", 0x0000000, 0x1F, 0, PutBitBranch }, + { "BBR2", 0x0000000, 0x2F, 0, PutBitBranch }, + { "BBR3", 0x0000000, 0x3F, 0, PutBitBranch }, + { "BBR4", 0x0000000, 0x4F, 0, PutBitBranch }, + { "BBR5", 0x0000000, 0x5F, 0, PutBitBranch }, + { "BBR6", 0x0000000, 0x6F, 0, PutBitBranch }, + { "BBR7", 0x0000000, 0x7F, 0, PutBitBranch }, + { "BBS0", 0x0000000, 0x8F, 0, PutBitBranch }, + { "BBS1", 0x0000000, 0x9F, 0, PutBitBranch }, + { "BBS2", 0x0000000, 0xAF, 0, PutBitBranch }, + { "BBS3", 0x0000000, 0xBF, 0, PutBitBranch }, + { "BBS4", 0x0000000, 0xCF, 0, PutBitBranch }, + { "BBS5", 0x0000000, 0xDF, 0, PutBitBranch }, + { "BBS6", 0x0000000, 0xEF, 0, PutBitBranch }, + { "BBS7", 0x0000000, 0xFF, 0, PutBitBranch }, + { "BCC", 0x0020000, 0x90, 0, PutPCRel8 }, + { "BCS", 0x0020000, 0xb0, 0, PutPCRel8 }, + { "BEQ", 0x0020000, 0xf0, 0, PutPCRel8 }, + { "BIT", 0x0A0006C, 0x00, 2, PutAll }, + { "BMI", 0x0020000, 0x30, 0, PutPCRel8 }, + { "BNE", 0x0020000, 0xd0, 0, PutPCRel8 }, + { "BPL", 0x0020000, 0x10, 0, PutPCRel8 }, + { "BRA", 0x0020000, 0x80, 0, PutPCRel8 }, + { "BRK", 0x0800005, 0x00, 6, PutAll }, + { "BVC", 0x0020000, 0x50, 0, PutPCRel8 }, + { "BVS", 0x0020000, 0x70, 0, PutPCRel8 }, + { "CLC", 0x0000001, 0x18, 0, PutAll }, + { "CLD", 0x0000001, 0xd8, 0, PutAll }, + { "CLI", 0x0000001, 0x58, 0, PutAll }, + { "CLV", 0x0000001, 0xb8, 0, PutAll }, + { "CMP", 0x080A66C, 0xc0, 0, PutAll }, + { "CPX", 0x080000C, 0xe0, 1, PutAll }, + { "CPY", 0x080000C, 0xc0, 1, PutAll }, + { "DEA", 0x0000001, 0x00, 3, PutAll }, /* == DEC */ + { "DEC", 0x000006F, 0x00, 3, PutAll }, + { "DEX", 0x0000001, 0xca, 0, PutAll }, + { "DEY", 0x0000001, 0x88, 0, PutAll }, + { "EOR", 0x080A66C, 0x40, 0, PutAll }, + { "INA", 0x0000001, 0x00, 4, PutAll }, /* == INC */ + { "INC", 0x000006f, 0x00, 4, PutAll }, + { "INX", 0x0000001, 0xe8, 0, PutAll }, + { "INY", 0x0000001, 0xc8, 0, PutAll }, + { "JMP", 0x0010808, 0x4c, 6, PutAll }, + { "JSR", 0x0000008, 0x20, 7, PutAll }, + { "LDA", 0x080A66C, 0xa0, 0, PutAll }, + { "LDX", 0x080030C, 0xa2, 1, PutAll }, + { "LDY", 0x080006C, 0xa0, 1, PutAll }, + { "LSR", 0x000006F, 0x42, 1, PutAll }, + { "NOP", 0x0000001, 0xea, 0, PutAll }, + { "ORA", 0x080A66C, 0x00, 0, PutAll }, + { "PHA", 0x0000001, 0x48, 0, PutAll }, + { "PHP", 0x0000001, 0x08, 0, PutAll }, + { "PHX", 0x0000001, 0xda, 0, PutAll }, + { "PHY", 0x0000001, 0x5a, 0, PutAll }, + { "PLA", 0x0000001, 0x68, 0, PutAll }, + { "PLP", 0x0000001, 0x28, 0, PutAll }, + { "PLX", 0x0000001, 0xfa, 0, PutAll }, + { "PLY", 0x0000001, 0x7a, 0, PutAll }, + { "RMB0", 0x0000004, 0x07, 1, PutAll }, + { "RMB1", 0x0000004, 0x17, 1, PutAll }, + { "RMB2", 0x0000004, 0x27, 1, PutAll }, + { "RMB3", 0x0000004, 0x37, 1, PutAll }, + { "RMB4", 0x0000004, 0x47, 1, PutAll }, + { "RMB5", 0x0000004, 0x57, 1, PutAll }, + { "RMB6", 0x0000004, 0x67, 1, PutAll }, + { "RMB7", 0x0000004, 0x77, 1, PutAll }, + { "ROL", 0x000006F, 0x22, 1, PutAll }, + { "ROR", 0x000006F, 0x62, 1, PutAll }, + { "RTI", 0x0000001, 0x40, 0, PutAll }, + { "RTS", 0x0000001, 0x60, 0, PutAll }, + { "SBC", 0x080A66C, 0xe0, 0, PutAll }, + { "SEC", 0x0000001, 0x38, 0, PutAll }, + { "SED", 0x0000001, 0xf8, 0, PutAll }, + { "SEI", 0x0000001, 0x78, 0, PutAll }, + { "SMB0", 0x0000004, 0x87, 1, PutAll }, + { "SMB1", 0x0000004, 0x97, 1, PutAll }, + { "SMB2", 0x0000004, 0xA7, 1, PutAll }, + { "SMB3", 0x0000004, 0xB7, 1, PutAll }, + { "SMB4", 0x0000004, 0xC7, 1, PutAll }, + { "SMB5", 0x0000004, 0xD7, 1, PutAll }, + { "SMB6", 0x0000004, 0xE7, 1, PutAll }, + { "SMB7", 0x0000004, 0xF7, 1, PutAll }, + { "STA", 0x000A66C, 0x80, 0, PutAll }, + { "STX", 0x000010c, 0x82, 1, PutAll }, + { "STY", 0x000002c, 0x80, 1, PutAll }, + { "STZ", 0x000006c, 0x04, 5, PutAll }, + { "TAX", 0x0000001, 0xaa, 0, PutAll }, + { "TAY", 0x0000001, 0xa8, 0, PutAll }, + { "TRB", 0x000000c, 0x10, 1, PutAll }, + { "TSB", 0x000000c, 0x00, 1, PutAll }, + { "TSX", 0x0000001, 0xba, 0, PutAll }, + { "TXA", 0x0000001, 0x8a, 0, PutAll }, + { "TXS", 0x0000001, 0x9a, 0, PutAll }, + { "TYA", 0x0000001, 0x98, 0, PutAll }, +/* END SORTED.SH */ + } +}; + +/* Instruction table for the W65C02 (CMOS with WDC extensions) */ +static const struct { + unsigned Count; + InsDesc Ins[100]; +} InsTabW65C02 = { + /* CAUTION: table must be sorted for bsearch */ + sizeof (InsTabW65C02.Ins) / sizeof (InsTabW65C02.Ins[0]), + { /* BEGIN SORTED.SH */ { "ADC", 0x080A66C, 0x60, 0, PutAll }, { "AND", 0x080A66C, 0x20, 0, PutAll }, @@ -618,6 +729,150 @@ static const struct { } }; +/* Instruction table for the 65CE02 */ +static const struct { + unsigned Count; + InsDesc Ins[131]; +} InsTab65CE02 = { + /* CAUTION: table must be sorted for bsearch */ + sizeof (InsTab65CE02.Ins) / sizeof (InsTab65CE02.Ins[0]), + { +/* BEGIN SORTED.SH */ + { "ADC", 0x080A66C, 0x60, 0, PutAll }, + { "AND", 0x080A66C, 0x20, 0, PutAll }, + { "ASL", 0x000006e, 0x02, 1, PutAll }, + { "ASR", 0x0000026, 0x43, 0, Put4510 }, + { "BBR0", 0x0000000, 0x0F, 0, PutBitBranch }, + { "BBR1", 0x0000000, 0x1F, 0, PutBitBranch }, + { "BBR2", 0x0000000, 0x2F, 0, PutBitBranch }, + { "BBR3", 0x0000000, 0x3F, 0, PutBitBranch }, + { "BBR4", 0x0000000, 0x4F, 0, PutBitBranch }, + { "BBR5", 0x0000000, 0x5F, 0, PutBitBranch }, + { "BBR6", 0x0000000, 0x6F, 0, PutBitBranch }, + { "BBR7", 0x0000000, 0x7F, 0, PutBitBranch }, + { "BBS0", 0x0000000, 0x8F, 0, PutBitBranch }, + { "BBS1", 0x0000000, 0x9F, 0, PutBitBranch }, + { "BBS2", 0x0000000, 0xAF, 0, PutBitBranch }, + { "BBS3", 0x0000000, 0xBF, 0, PutBitBranch }, + { "BBS4", 0x0000000, 0xCF, 0, PutBitBranch }, + { "BBS5", 0x0000000, 0xDF, 0, PutBitBranch }, + { "BBS6", 0x0000000, 0xEF, 0, PutBitBranch }, + { "BBS7", 0x0000000, 0xFF, 0, PutBitBranch }, + { "BCC", 0x0020000, 0x90, 0, PutPCRel8 }, + { "BCS", 0x0020000, 0xb0, 0, PutPCRel8 }, + { "BEQ", 0x0020000, 0xf0, 0, PutPCRel8 }, + { "BIT", 0x0A0006C, 0x00, 2, PutAll }, + { "BMI", 0x0020000, 0x30, 0, PutPCRel8 }, + { "BNE", 0x0020000, 0xd0, 0, PutPCRel8 }, + { "BPL", 0x0020000, 0x10, 0, PutPCRel8 }, + { "BRA", 0x0020000, 0x80, 0, PutPCRel8 }, + { "BRK", 0x0800005, 0x00, 6, PutAll }, + { "BSR", 0x0040000, 0x63, 0, PutPCRel4510 }, + { "BVC", 0x0020000, 0x50, 0, PutPCRel8 }, + { "BVS", 0x0020000, 0x70, 0, PutPCRel8 }, + { "CLC", 0x0000001, 0x18, 0, PutAll }, + { "CLD", 0x0000001, 0xd8, 0, PutAll }, + { "CLE", 0x0000001, 0x02, 0, PutAll }, + { "CLI", 0x0000001, 0x58, 0, PutAll }, + { "CLV", 0x0000001, 0xb8, 0, PutAll }, + { "CMP", 0x080A66C, 0xc0, 0, PutAll }, + { "CPX", 0x080000C, 0xe0, 1, PutAll }, + { "CPY", 0x080000C, 0xc0, 1, PutAll }, + { "CPZ", 0x080000C, 0xd0, 1, Put4510 }, + { "DEA", 0x0000001, 0x00, 3, PutAll }, /* == DEC */ + { "DEC", 0x000006F, 0x00, 3, PutAll }, + { "DEW", 0x0000004, 0xc3, 9, PutAll }, + { "DEX", 0x0000001, 0xca, 0, PutAll }, + { "DEY", 0x0000001, 0x88, 0, PutAll }, + { "DEZ", 0x0000001, 0x3B, 0, PutAll }, + { "EOM", 0x0000001, 0xea, 0, PutAll }, + { "EOR", 0x080A66C, 0x40, 0, PutAll }, + { "INA", 0x0000001, 0x00, 4, PutAll }, /* == INC */ + { "INC", 0x000006f, 0x00, 4, PutAll }, + { "INW", 0x0000004, 0xe3, 9, PutAll }, + { "INX", 0x0000001, 0xe8, 0, PutAll }, + { "INY", 0x0000001, 0xc8, 0, PutAll }, + { "INZ", 0x0000001, 0x1B, 0, PutAll }, + { "JMP", 0x0010808, 0x4c, 6, PutAll }, + { "JSR", 0x0010808, 0x20, 7, Put4510 }, + { "LBCC", 0x0040000, 0x93, 0, PutPCRel4510 }, + { "LBCS", 0x0040000, 0xb3, 0, PutPCRel4510 }, + { "LBEQ", 0x0040000, 0xf3, 0, PutPCRel4510 }, + { "LBMI", 0x0040000, 0x33, 0, PutPCRel4510 }, + { "LBNE", 0x0040000, 0xd3, 0, PutPCRel4510 }, + { "LBPL", 0x0040000, 0x13, 0, PutPCRel4510 }, + { "LBRA", 0x0040000, 0x83, 0, PutPCRel4510 }, + { "LBVC", 0x0040000, 0x53, 0, PutPCRel4510 }, + { "LBVS", 0x0040000, 0x73, 0, PutPCRel4510 }, + { "LDA", 0x090A66C, 0xa0, 0, Put4510 }, + { "LDX", 0x080030C, 0xa2, 1, PutAll }, + { "LDY", 0x080006C, 0xa0, 1, PutAll }, + { "LDZ", 0x0800048, 0xa3, 1, Put4510 }, + { "LSR", 0x000006F, 0x42, 1, PutAll }, + { "AUG", 0x0000001, 0x5C, 0, PutAll }, + { "NEG", 0x0000001, 0x42, 0, PutAll }, + { "NOP", 0x0000001, 0xea, 0, PutAll }, /* == EOM */ + { "ORA", 0x080A66C, 0x00, 0, PutAll }, + { "PHA", 0x0000001, 0x48, 0, PutAll }, + { "PHD", 0x8000008, 0xf4, 1, PutAll }, /* == PHW */ + { "PHP", 0x0000001, 0x08, 0, PutAll }, + { "PHW", 0x8000008, 0xf4, 1, PutAll }, + { "PHX", 0x0000001, 0xda, 0, PutAll }, + { "PHY", 0x0000001, 0x5a, 0, PutAll }, + { "PLA", 0x0000001, 0x68, 0, PutAll }, + { "PLP", 0x0000001, 0x28, 0, PutAll }, + { "PLX", 0x0000001, 0xfa, 0, PutAll }, + { "PLY", 0x0000001, 0x7a, 0, PutAll }, + { "PLZ", 0x0000001, 0xfb, 0, PutAll }, + { "RMB0", 0x0000004, 0x07, 1, PutAll }, + { "RMB1", 0x0000004, 0x17, 1, PutAll }, + { "RMB2", 0x0000004, 0x27, 1, PutAll }, + { "RMB3", 0x0000004, 0x37, 1, PutAll }, + { "RMB4", 0x0000004, 0x47, 1, PutAll }, + { "RMB5", 0x0000004, 0x57, 1, PutAll }, + { "RMB6", 0x0000004, 0x67, 1, PutAll }, + { "RMB7", 0x0000004, 0x77, 1, PutAll }, + { "ROL", 0x000006F, 0x22, 1, PutAll }, + { "ROR", 0x000006F, 0x62, 1, PutAll }, + { "ROW", 0x0000008, 0xeb, 6, PutAll }, + { "RTI", 0x0000001, 0x40, 0, PutAll }, + { "RTN", 0x0800000, 0x62, 1, PutAll }, + { "RTS", 0x0000001, 0x60, 0, PutAll }, + { "SBC", 0x080A66C, 0xe0, 0, PutAll }, + { "SEC", 0x0000001, 0x38, 0, PutAll }, + { "SED", 0x0000001, 0xf8, 0, PutAll }, + { "SEE", 0x0000001, 0x03, 0, PutAll }, + { "SEI", 0x0000001, 0x78, 0, PutAll }, + { "SMB0", 0x0000004, 0x87, 1, PutAll }, + { "SMB1", 0x0000004, 0x97, 1, PutAll }, + { "SMB2", 0x0000004, 0xA7, 1, PutAll }, + { "SMB3", 0x0000004, 0xB7, 1, PutAll }, + { "SMB4", 0x0000004, 0xC7, 1, PutAll }, + { "SMB5", 0x0000004, 0xD7, 1, PutAll }, + { "SMB6", 0x0000004, 0xE7, 1, PutAll }, + { "SMB7", 0x0000004, 0xF7, 1, PutAll }, + { "STA", 0x010A66C, 0x80, 0, Put4510 }, + { "STX", 0x000030c, 0x82, 1, Put4510 }, + { "STY", 0x000006c, 0x80, 1, Put4510 }, + { "STZ", 0x000006c, 0x04, 5, PutAll }, + { "TAB", 0x0000001, 0x5b, 0, PutAll }, + { "TAX", 0x0000001, 0xaa, 0, PutAll }, + { "TAY", 0x0000001, 0xa8, 0, PutAll }, + { "TAZ", 0x0000001, 0x4b, 0, PutAll }, + { "TBA", 0x0000001, 0x7b, 0, PutAll }, + { "TRB", 0x000000c, 0x10, 1, PutAll }, + { "TSB", 0x000000c, 0x00, 1, PutAll }, + { "TSX", 0x0000001, 0xba, 0, PutAll }, + { "TSY", 0x0000001, 0x0b, 0, PutAll }, + { "TXA", 0x0000001, 0x8a, 0, PutAll }, + { "TXS", 0x0000001, 0x9a, 0, PutAll }, + { "TYA", 0x0000001, 0x98, 0, PutAll }, + { "TYS", 0x0000001, 0x2b, 0, PutAll }, + { "TZA", 0x0000001, 0x6b, 0, PutAll }, +/* END SORTED.SH */ + } +}; + /* Instruction table for the 4510 */ static const struct { unsigned Count; @@ -1355,14 +1610,16 @@ static const InsTable* InsTabs[CPU_COUNT] = { (const InsTable*) &InsTab6502, (const InsTable*) &InsTab6502X, (const InsTable*) &InsTab6502DTV, - (const InsTable*) &InsTab65SC02, - (const InsTable*) &InsTab65C02, + (const InsTable*) &InsTab65SC02, /* original CMOS */ + (const InsTable*) &InsTab65C02, /* CMOS with Rockwell extensions */ (const InsTable*) &InsTab65816, (const InsTable*) &InsTabSweet16, (const InsTable*) &InsTabHuC6280, - (const InsTable*) &InsTabm740, /* Mitsubishi 740 */ + (const InsTable*) &InsTabm740, /* Mitsubishi 740 */ (const InsTable*) &InsTab4510, (const InsTable*) &InsTab45GS02, + (const InsTable*) &InsTabW65C02, /* CMOS with WDC extensions */ + (const InsTable*) &InsTab65CE02, /* CMOS with GTE extensions */ }; const InsTable* InsTab = (const InsTable*) &InsTab6502; From e3140349b086f1062676c26f558d4b9bff636987 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 00:54:13 +0200 Subject: [PATCH 647/707] add 65CE02 and W65C02 to disassembler --- src/da65/opc65c02.c | 4 +- src/da65/opc65ce02.c | 306 +++++++++++++++++++++++++++++++++++++++++++ src/da65/opc65ce02.h | 58 ++++++++ src/da65/opctable.c | 4 + src/da65/opcw65c02.c | 306 +++++++++++++++++++++++++++++++++++++++++++ src/da65/opcw65c02.h | 58 ++++++++ 6 files changed, 734 insertions(+), 2 deletions(-) create mode 100644 src/da65/opc65ce02.c create mode 100644 src/da65/opc65ce02.h create mode 100644 src/da65/opcw65c02.c create mode 100644 src/da65/opcw65c02.h diff --git a/src/da65/opc65c02.c b/src/da65/opc65c02.c index b69558f2a..88c8c8dec 100644 --- a/src/da65/opc65c02.c +++ b/src/da65/opc65c02.c @@ -250,7 +250,7 @@ const OpcDesc OpcTable_65C02[256] = { { "iny", 1, flNone, OH_Implicit }, /* $c8 */ { "cmp", 2, flNone, OH_Immediate }, /* $c9 */ { "dex", 1, flNone, OH_Implicit }, /* $ca */ - { "wai", 1, flNone, OH_Implicit }, /* $cb */ + { "", 1, flIllegal, OH_Illegal, }, /* $cb */ { "cpy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cc */ { "cmp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cd */ { "dec", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ce */ @@ -266,7 +266,7 @@ const OpcDesc OpcTable_65C02[256] = { { "cld", 1, flNone, OH_Implicit }, /* $d8 */ { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */ { "phx", 1, flNone, OH_Implicit }, /* $da */ - { "stp", 1, flNone, OH_Implicit }, /* $db */ + { "", 1, flIllegal, OH_Illegal, }, /* $db */ { "", 1, flIllegal, OH_Illegal, }, /* $dc */ { "cmp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dd */ { "dec", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $de */ diff --git a/src/da65/opc65ce02.c b/src/da65/opc65ce02.c new file mode 100644 index 000000000..093e79a9e --- /dev/null +++ b/src/da65/opc65ce02.c @@ -0,0 +1,306 @@ +/*****************************************************************************/ +/* */ +/* opc65CE02.c */ +/* */ +/* 65CE02 opcode description table */ +/* */ +/* */ +/* */ +/* (C) 2003-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +/* da65 */ +#include "handler.h" +#include "opc65ce02.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all opcodes */ +const OpcDesc OpcTable_65CE02[256] = { + { "brk", 1, flNone, OH_Implicit }, /* $00 */ + { "ora", 2, flUseLabel, OH_DirectXIndirect }, /* $01 */ + { "cle", 1, flNone, OH_Implicit }, /* $02 */ + { "see", 1, flNone, OH_Implicit }, /* $03 */ + { "tsb", 2, flUseLabel, OH_Direct }, /* $04 */ + { "ora", 2, flUseLabel, OH_Direct }, /* $05 */ + { "asl", 2, flUseLabel, OH_Direct }, /* $06 */ + { "rmb0", 2, flUseLabel, OH_Direct }, /* $07 */ + { "php", 1, flNone, OH_Implicit }, /* $08 */ + { "ora", 2, flNone, OH_Immediate }, /* $09 */ + { "asl", 1, flNone, OH_Accumulator }, /* $0a */ + { "tsy", 1, flNone, OH_Implicit }, /* $0b */ + { "tsb", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0c */ + { "ora", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0d */ + { "asl", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0e */ + { "bbr0", 3, flUseLabel, OH_BitBranch }, /* $0f */ + { "bpl", 2, flLabel, OH_Relative }, /* $10 */ + { "ora", 2, flUseLabel, OH_DirectIndirectY }, /* $11 */ + { "ora", 2, flUseLabel, OH_DirectIndirectZ }, /* $12 */ + { "lbpl", 3, flLabel, OH_RelativeLong4510 }, /* $13 */ + { "trb", 2, flUseLabel, OH_Direct }, /* $14 */ + { "ora", 2, flUseLabel, OH_DirectX }, /* $15 */ + { "asl", 2, flUseLabel, OH_DirectX }, /* $16 */ + { "rmb1", 2, flUseLabel, OH_Direct }, /* $17 */ + { "clc", 1, flNone, OH_Implicit }, /* $18 */ + { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */ + { "inc", 1, flNone, OH_Accumulator }, /* $1a */ + { "inz", 1, flNone, OH_Implicit }, /* $1b */ + { "trb", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $1c */ + { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */ + { "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */ + { "bbr1", 3, flUseLabel, OH_BitBranch }, /* $1f */ + { "jsr", 3, flLabel, OH_Absolute }, /* $20 */ + { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */ + { "jsr", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $22 */ + { "jsr", 3, flLabel, OH_JmpAbsoluteXIndirect }, /* $23 */ + { "bit", 2, flUseLabel, OH_Direct }, /* $24 */ + { "and", 2, flUseLabel, OH_Direct }, /* $25 */ + { "rol", 2, flUseLabel, OH_Direct }, /* $26 */ + { "rmb2", 2, flUseLabel, OH_Direct }, /* $27 */ + { "plp", 1, flNone, OH_Implicit }, /* $28 */ + { "and", 2, flNone, OH_Immediate }, /* $29 */ + { "rol", 1, flNone, OH_Accumulator }, /* $2a */ + { "tys", 1, flNone, OH_Implicit }, /* $2b */ + { "bit", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2c */ + { "and", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2d */ + { "rol", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2e */ + { "bbr2", 3, flUseLabel, OH_BitBranch }, /* $2f */ + { "bmi", 2, flLabel, OH_Relative }, /* $30 */ + { "and", 2, flUseLabel, OH_DirectIndirectY }, /* $31 */ + { "and", 2, flUseLabel, OH_DirectIndirectZ }, /* $32 */ + { "lbmi", 3, flLabel, OH_RelativeLong4510 }, /* $33 */ + { "bit", 2, flUseLabel, OH_DirectX }, /* $34 */ + { "and", 2, flUseLabel, OH_DirectX }, /* $35 */ + { "rol", 2, flUseLabel, OH_DirectX }, /* $36 */ + { "rmb3", 2, flUseLabel, OH_Direct }, /* $37 */ + { "sec", 1, flNone, OH_Implicit }, /* $38 */ + { "and", 3, flUseLabel, OH_AbsoluteY }, /* $39 */ + { "dec", 1, flNone, OH_Accumulator }, /* $3a */ + { "dez", 1, flNone, OH_Implicit }, /* $3b */ + { "bit", 3, flUseLabel, OH_AbsoluteX }, /* $3c */ + { "and", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3d */ + { "rol", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3e */ + { "bbr3", 3, flUseLabel, OH_BitBranch }, /* $3f */ + { "rti", 1, flNone, OH_Rts }, /* $40 */ + { "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */ + { "neg", 1, flNone, OH_Implicit }, /* $42 */ + { "asr", 1, flNone, OH_Accumulator }, /* $43 */ + { "asr", 2, flUseLabel, OH_Direct }, /* $44 */ + { "eor", 2, flUseLabel, OH_Direct }, /* $45 */ + { "lsr", 2, flUseLabel, OH_Direct }, /* $46 */ + { "rmb4", 2, flUseLabel, OH_Direct }, /* $47 */ + { "pha", 1, flNone, OH_Implicit }, /* $48 */ + { "eor", 2, flNone, OH_Immediate }, /* $49 */ + { "lsr", 1, flNone, OH_Accumulator }, /* $4a */ + { "taz", 1, flNone, OH_Implicit }, /* $4b */ + { "jmp", 3, flLabel, OH_JmpAbsolute }, /* $4c */ + { "eor", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4d */ + { "lsr", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4e */ + { "bbr4", 3, flUseLabel, OH_BitBranch }, /* $4f */ + { "bvc", 2, flLabel, OH_Relative }, /* $50 */ + { "eor", 2, flUseLabel, OH_DirectIndirectY }, /* $51 */ + { "eor", 2, flUseLabel, OH_DirectIndirectZ }, /* $52 */ + { "lbvc", 3, flLabel, OH_RelativeLong4510 }, /* $53 */ + { "asr", 2, flUseLabel, OH_DirectX }, /* $54 */ + { "eor", 2, flUseLabel, OH_DirectX }, /* $55 */ + { "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */ + { "rmb5", 2, flUseLabel, OH_Direct }, /* $57 */ + { "cli", 1, flNone, OH_Implicit }, /* $58 */ + { "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */ + { "phy", 1, flNone, OH_Implicit }, /* $5a */ + { "tab", 1, flNone, OH_Implicit }, /* $5b */ + { "aug", 1, flNone, OH_Implicit }, /* $5c */ + { "eor", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5d */ + { "lsr", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5e */ + { "bbr5", 3, flUseLabel, OH_BitBranch }, /* $5f */ + { "rts", 1, flNone, OH_Rts }, /* $60 */ + { "adc", 2, flUseLabel, OH_DirectXIndirect }, /* $61 */ + { "rtn", 2, flNone, OH_Immediate }, /* $62 */ + { "bsr", 3, flLabel, OH_RelativeLong4510 }, /* $63 */ + { "stz", 2, flUseLabel, OH_Direct }, /* $64 */ + { "adc", 2, flUseLabel, OH_Direct }, /* $65 */ + { "ror", 2, flUseLabel, OH_Direct }, /* $66 */ + { "rmb6", 2, flUseLabel, OH_Direct, }, /* $67 */ + { "pla", 1, flNone, OH_Implicit }, /* $68 */ + { "adc", 2, flNone, OH_Immediate }, /* $69 */ + { "ror", 1, flNone, OH_Accumulator }, /* $6a */ + { "tza", 1, flNone, OH_Implicit }, /* $6b */ + { "jmp", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $6c */ + { "adc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6d */ + { "ror", 3, flUseLabel, OH_Absolute }, /* $6e */ + { "bbr6", 3, flUseLabel, OH_BitBranch }, /* $6f */ + { "bvs", 2, flLabel, OH_Relative }, /* $70 */ + { "adc", 2, flUseLabel, OH_DirectIndirectY }, /* $71 */ + { "adc", 2, flUseLabel, OH_DirectIndirectZ }, /* $72 */ + { "lbvs", 3, flLabel, OH_RelativeLong4510 }, /* $73 */ + { "stz", 2, flUseLabel, OH_DirectX }, /* $74 */ + { "adc", 2, flUseLabel, OH_DirectX }, /* $75 */ + { "ror", 2, flUseLabel, OH_DirectX }, /* $76 */ + { "rmb7", 2, flUseLabel, OH_Direct }, /* $77 */ + { "sei", 1, flNone, OH_Implicit }, /* $78 */ + { "adc", 3, flUseLabel, OH_AbsoluteY }, /* $79 */ + { "ply", 1, flNone, OH_Implicit }, /* $7a */ + { "tba", 1, flNone, OH_Implicit }, /* $7b */ + { "jmp", 3, flLabel, OH_AbsoluteXIndirect }, /* $7c */ + { "adc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7d */ + { "ror", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7e */ + { "bbr7", 3, flUseLabel, OH_BitBranch }, /* $7f */ + { "bra", 2, flLabel, OH_Relative }, /* $80 */ + { "sta", 2, flUseLabel, OH_DirectXIndirect }, /* $81 */ + { "sta", 2, flNone, OH_StackRelativeIndirectY4510}, /* $82 */ + { "lbra", 3, flLabel, OH_RelativeLong4510 }, /* $83 */ + { "sty", 2, flUseLabel, OH_Direct }, /* $84 */ + { "sta", 2, flUseLabel, OH_Direct }, /* $85 */ + { "stx", 2, flUseLabel, OH_Direct }, /* $86 */ + { "smb0", 2, flUseLabel, OH_Direct }, /* $87 */ + { "dey", 1, flNone, OH_Implicit }, /* $88 */ + { "bit", 2, flNone, OH_Immediate }, /* $89 */ + { "txa", 1, flNone, OH_Implicit }, /* $8a */ + { "sty", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $8b */ + { "sty", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8c */ + { "sta", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8d */ + { "stx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8e */ + { "bbs0", 3, flUseLabel, OH_BitBranch }, /* $8f */ + { "bcc", 2, flLabel, OH_Relative }, /* $90 */ + { "sta", 2, flUseLabel, OH_DirectIndirectY }, /* $91 */ + { "sta", 2, flUseLabel, OH_DirectIndirectZ }, /* $92 */ + { "lbcc", 3, flLabel, OH_RelativeLong4510 }, /* $93 */ + { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */ + { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */ + { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */ + { "smb1", 2, flUseLabel, OH_Direct }, /* $97 */ + { "tya", 1, flNone, OH_Implicit }, /* $98 */ + { "sta", 3, flUseLabel, OH_AbsoluteY }, /* $99 */ + { "txs", 1, flNone, OH_Implicit }, /* $9a */ + { "stx", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $9b */ + { "stz", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $9c */ + { "sta", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9d */ + { "stz", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9e */ + { "bbs1", 3, flUseLabel, OH_BitBranch }, /* $9f */ + { "ldy", 2, flNone, OH_Immediate }, /* $a0 */ + { "lda", 2, flUseLabel, OH_DirectXIndirect }, /* $a1 */ + { "ldx", 2, flNone, OH_Immediate }, /* $a2 */ + { "ldz", 2, flNone, OH_Immediate }, /* $a3 */ + { "ldy", 2, flUseLabel, OH_Direct }, /* $a4 */ + { "lda", 2, flUseLabel, OH_Direct }, /* $a5 */ + { "ldx", 2, flUseLabel, OH_Direct }, /* $a6 */ + { "smb2", 2, flUseLabel, OH_Direct }, /* $a7 */ + { "tay", 1, flNone, OH_Implicit }, /* $a8 */ + { "lda", 2, flNone, OH_Immediate }, /* $a9 */ + { "tax", 1, flNone, OH_Implicit }, /* $aa */ + { "ldz", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ab */ + { "ldy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ac */ + { "lda", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ad */ + { "ldx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ae */ + { "bbs2", 3, flUseLabel, OH_BitBranch }, /* $af */ + { "bcs", 2, flLabel, OH_Relative }, /* $b0 */ + { "lda", 2, flUseLabel, OH_DirectIndirectY }, /* $b1 */ + { "lda", 2, flUseLabel, OH_DirectIndirectZ }, /* $b2 */ + { "lbcs", 3, flLabel, OH_RelativeLong4510 }, /* $b3 */ + { "ldy", 2, flUseLabel, OH_DirectX }, /* $b4 */ + { "lda", 2, flUseLabel, OH_DirectX }, /* $b5 */ + { "ldx", 2, flUseLabel, OH_DirectY }, /* $b6 */ + { "smb3", 2, flUseLabel, OH_Direct }, /* $b7 */ + { "clv", 1, flNone, OH_Implicit }, /* $b8 */ + { "lda", 3, flUseLabel, OH_AbsoluteY }, /* $b9 */ + { "tsx", 1, flNone, OH_Implicit }, /* $ba */ + { "ldz", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bb */ + { "ldy", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bc */ + { "lda", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bd */ + { "ldx", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $be */ + { "bbs3", 3, flUseLabel, OH_BitBranch }, /* $bf */ + { "cpy", 2, flNone, OH_Immediate }, /* $c0 */ + { "cmp", 2, flUseLabel, OH_DirectXIndirect }, /* $c1 */ + { "cpz", 2, flNone, OH_Immediate }, /* $c2 */ + { "dew", 2, flUseLabel, OH_Direct }, /* $c3 */ + { "cpy", 2, flUseLabel, OH_Direct }, /* $c4 */ + { "cmp", 2, flUseLabel, OH_Direct }, /* $c5 */ + { "dec", 2, flUseLabel, OH_Direct }, /* $c6 */ + { "smb4", 2, flUseLabel, OH_Direct }, /* $c7 */ + { "iny", 1, flNone, OH_Implicit }, /* $c8 */ + { "cmp", 2, flNone, OH_Immediate }, /* $c9 */ + { "dex", 1, flNone, OH_Implicit }, /* $ca */ + { "asw", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cb */ + { "cpy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cc */ + { "cmp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cd */ + { "dec", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ce */ + { "bbs4", 3, flUseLabel, OH_BitBranch }, /* $cf */ + { "bne", 2, flLabel, OH_Relative }, /* $d0 */ + { "cmp", 2, flUseLabel, OH_DirectIndirectY }, /* $d1 */ + { "cmp", 2, flUseLabel, OH_DirectIndirectZ }, /* $d2 */ + { "lbne", 3, flLabel, OH_RelativeLong4510 }, /* $d3 */ + { "cpz", 2, flUseLabel, OH_Direct }, /* $d4 */ + { "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */ + { "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */ + { "smb5", 2, flUseLabel, OH_Direct }, /* $d7 */ + { "cld", 1, flNone, OH_Implicit }, /* $d8 */ + { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */ + { "phx", 1, flNone, OH_Implicit }, /* $da */ + { "phz", 1, flNone, OH_Implicit }, /* $db */ + { "cpz", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $dc */ + { "cmp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dd */ + { "dec", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $de */ + { "bbs5", 3, flUseLabel, OH_BitBranch }, /* $df */ + { "cpx", 2, flNone, OH_Immediate }, /* $e0 */ + { "sbc", 2, flUseLabel, OH_DirectXIndirect }, /* $e1 */ + { "lda", 2, flNone, OH_StackRelativeIndirectY4510}, /* $e2 */ + { "inw", 2, flUseLabel, OH_Direct }, /* $e3 */ + { "cpx", 2, flUseLabel, OH_Direct }, /* $e4 */ + { "sbc", 2, flUseLabel, OH_Direct }, /* $e5 */ + { "inc", 2, flUseLabel, OH_Direct }, /* $e6 */ + { "smb6", 2, flUseLabel, OH_Direct }, /* $e7 */ + { "inx", 1, flNone, OH_Implicit }, /* $e8 */ + { "sbc", 2, flNone, OH_Immediate }, /* $e9 */ + { "eom", 1, flNone, OH_Implicit }, /* $ea */ + { "row", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $eb */ + { "cpx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ec */ + { "sbc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ed */ + { "inc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ee */ + { "bbs6", 3, flUseLabel, OH_BitBranch }, /* $ef */ + { "beq", 2, flLabel, OH_Relative }, /* $f0 */ + { "sbc", 2, flUseLabel, OH_DirectIndirectY }, /* $f1 */ + { "sbc", 2, flUseLabel, OH_DirectIndirectZ }, /* $f2 */ + { "lbeq", 3, flLabel, OH_RelativeLong4510 }, /* $f3 */ + { "phw", 3, flNone, OH_ImmediateWord }, /* $f4 */ + { "sbc", 2, flUseLabel, OH_DirectX }, /* $f5 */ + { "inc", 2, flUseLabel, OH_DirectX }, /* $f6 */ + { "smb7", 2, flUseLabel, OH_Direct }, /* $f7 */ + { "sed", 1, flNone, OH_Implicit }, /* $f8 */ + { "sbc", 3, flUseLabel, OH_AbsoluteY }, /* $f9 */ + { "plx", 1, flNone, OH_Implicit }, /* $fa */ + { "plz", 1, flNone, OH_Implicit }, /* $fb */ + { "phw", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $fc */ + { "sbc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fd */ + { "inc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fe */ + { "bbs7", 3, flUseLabel, OH_BitBranch }, /* $ff */ +}; diff --git a/src/da65/opc65ce02.h b/src/da65/opc65ce02.h new file mode 100644 index 000000000..e3987dbcd --- /dev/null +++ b/src/da65/opc65ce02.h @@ -0,0 +1,58 @@ +/*****************************************************************************/ +/* */ +/* opc65CE02.h */ +/* */ +/* 65CE02 opcode description table */ +/* */ +/* */ +/* */ +/* (C) 2003 Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef OPC65CE02_H +#define OPC65CE02_H + + + +#include "opcdesc.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all opcodes */ +extern const OpcDesc OpcTable_65CE02[256]; + + + +/* End of opc65CE02.h */ + +#endif diff --git a/src/da65/opctable.c b/src/da65/opctable.c index 445f8880c..de90dd83a 100644 --- a/src/da65/opctable.c +++ b/src/da65/opctable.c @@ -43,6 +43,8 @@ #include "opc65816.h" #include "opc65c02.h" #include "opc65sc02.h" +#include "opcw65c02.h" +#include "opc65ce02.h" #include "opchuc6280.h" #include "opcm740.h" #include "opctable.h" @@ -75,6 +77,8 @@ void SetOpcTable (cpu_t CPU) case CPU_6502DTV: OpcTable = OpcTable_6502DTV; break; case CPU_65SC02: OpcTable = OpcTable_65SC02; break; case CPU_65C02: OpcTable = OpcTable_65C02; break; + case CPU_W65C02: OpcTable = OpcTable_W65C02; break; + case CPU_65CE02: OpcTable = OpcTable_65CE02; break; case CPU_65816: OpcTable = OpcTable_65816; break; case CPU_HUC6280: OpcTable = OpcTable_HuC6280; break; case CPU_M740: OpcTable = OpcTable_M740; break; diff --git a/src/da65/opcw65c02.c b/src/da65/opcw65c02.c new file mode 100644 index 000000000..2c48e1019 --- /dev/null +++ b/src/da65/opcw65c02.c @@ -0,0 +1,306 @@ +/*****************************************************************************/ +/* */ +/* opcw65c02.c */ +/* */ +/* W65C02 opcode description table */ +/* */ +/* */ +/* */ +/* (C) 2003-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +/* da65 */ +#include "handler.h" +#include "opcw65c02.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all opcodes */ +const OpcDesc OpcTable_W65C02[256] = { + { "brk", 1, flNone, OH_Implicit }, /* $00 */ + { "ora", 2, flUseLabel, OH_DirectXIndirect }, /* $01 */ + { "", 1, flIllegal, OH_Illegal, }, /* $02 */ + { "", 1, flIllegal, OH_Illegal, }, /* $03 */ + { "tsb", 2, flUseLabel, OH_Direct }, /* $04 */ + { "ora", 2, flUseLabel, OH_Direct }, /* $05 */ + { "asl", 2, flUseLabel, OH_Direct }, /* $06 */ + { "rmb0", 2, flUseLabel, OH_Direct, }, /* $07 */ + { "php", 1, flNone, OH_Implicit }, /* $08 */ + { "ora", 2, flNone, OH_Immediate }, /* $09 */ + { "asl", 1, flNone, OH_Accumulator }, /* $0a */ + { "", 1, flIllegal, OH_Illegal, }, /* $0b */ + { "tsb", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0c */ + { "ora", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0d */ + { "asl", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $0e */ + { "bbr0", 3, flUseLabel, OH_BitBranch }, /* $0f */ + { "bpl", 2, flLabel, OH_Relative }, /* $10 */ + { "ora", 2, flUseLabel, OH_DirectIndirectY }, /* $11 */ + { "ora", 2, flUseLabel, OH_DirectIndirect }, /* $12 */ + { "", 1, flIllegal, OH_Illegal, }, /* $13 */ + { "trb", 2, flUseLabel, OH_Direct }, /* $14 */ + { "ora", 2, flUseLabel, OH_DirectX }, /* $15 */ + { "asl", 2, flUseLabel, OH_DirectX }, /* $16 */ + { "rmb1", 2, flUseLabel, OH_Direct, }, /* $17 */ + { "clc", 1, flNone, OH_Implicit }, /* $18 */ + { "ora", 3, flUseLabel, OH_AbsoluteY }, /* $19 */ + { "inc", 1, flNone, OH_Accumulator }, /* $1a */ + { "", 1, flIllegal, OH_Illegal, }, /* $1b */ + { "trb", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $1c */ + { "ora", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1d */ + { "asl", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $1e */ + { "bbr1", 3, flUseLabel, OH_BitBranch }, /* $1f */ + { "jsr", 3, flLabel, OH_JsrAbsolute }, /* $20 */ + { "and", 2, flUseLabel, OH_DirectXIndirect }, /* $21 */ + { "", 1, flIllegal, OH_Illegal, }, /* $22 */ + { "", 1, flIllegal, OH_Illegal, }, /* $23 */ + { "bit", 2, flUseLabel, OH_Direct }, /* $24 */ + { "and", 2, flUseLabel, OH_Direct }, /* $25 */ + { "rol", 2, flUseLabel, OH_Direct }, /* $26 */ + { "rmb2", 2, flUseLabel, OH_Direct, }, /* $27 */ + { "plp", 1, flNone, OH_Implicit }, /* $28 */ + { "and", 2, flNone, OH_Immediate }, /* $29 */ + { "rol", 1, flNone, OH_Accumulator }, /* $2a */ + { "", 1, flIllegal, OH_Illegal, }, /* $2b */ + { "bit", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2c */ + { "and", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2d */ + { "rol", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $2e */ + { "bbr2", 3, flUseLabel, OH_BitBranch }, /* $2f */ + { "bmi", 2, flLabel, OH_Relative }, /* $30 */ + { "and", 2, flUseLabel, OH_DirectIndirectY }, /* $31 */ + { "and", 2, flUseLabel, OH_DirectIndirect, }, /* $32 */ + { "", 1, flIllegal, OH_Illegal, }, /* $33 */ + { "bit", 2, flUseLabel, OH_DirectX }, /* $34 */ + { "and", 2, flUseLabel, OH_DirectX }, /* $35 */ + { "rol", 2, flUseLabel, OH_DirectX }, /* $36 */ + { "rmb3", 2, flUseLabel, OH_Direct, }, /* $37 */ + { "sec", 1, flNone, OH_Implicit }, /* $38 */ + { "and", 3, flUseLabel, OH_AbsoluteY }, /* $39 */ + { "dec", 1, flNone, OH_Accumulator }, /* $3a */ + { "", 1, flIllegal, OH_Illegal, }, /* $3b */ + { "bit", 3, flUseLabel, OH_AbsoluteX }, /* $3c */ + { "and", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3d */ + { "rol", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $3e */ + { "bbr3", 3, flUseLabel, OH_BitBranch }, /* $3f */ + { "rti", 1, flNone, OH_Rts }, /* $40 */ + { "eor", 2, flUseLabel, OH_DirectXIndirect }, /* $41 */ + { "", 1, flIllegal, OH_Illegal, }, /* $42 */ + { "", 1, flIllegal, OH_Illegal, }, /* $43 */ + { "", 1, flIllegal, OH_Illegal, }, /* $44 */ + { "eor", 2, flUseLabel, OH_Direct }, /* $45 */ + { "lsr", 2, flUseLabel, OH_Direct }, /* $46 */ + { "rmb4", 2, flUseLabel, OH_Direct, }, /* $47 */ + { "pha", 1, flNone, OH_Implicit }, /* $48 */ + { "eor", 2, flNone, OH_Immediate }, /* $49 */ + { "lsr", 1, flNone, OH_Accumulator }, /* $4a */ + { "", 1, flIllegal, OH_Illegal, }, /* $4b */ + { "jmp", 3, flLabel, OH_JmpAbsolute }, /* $4c */ + { "eor", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4d */ + { "lsr", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $4e */ + { "bbr4", 3, flUseLabel, OH_BitBranch }, /* $4f */ + { "bvc", 2, flLabel, OH_Relative }, /* $50 */ + { "eor", 2, flUseLabel, OH_DirectIndirectY }, /* $51 */ + { "eor", 2, flUseLabel, OH_DirectIndirect }, /* $52 */ + { "", 1, flIllegal, OH_Illegal, }, /* $53 */ + { "", 1, flIllegal, OH_Illegal, }, /* $54 */ + { "eor", 2, flUseLabel, OH_DirectX }, /* $55 */ + { "lsr", 2, flUseLabel, OH_DirectX }, /* $56 */ + { "rmb5", 2, flUseLabel, OH_Direct, }, /* $57 */ + { "cli", 1, flNone, OH_Implicit }, /* $58 */ + { "eor", 3, flUseLabel, OH_AbsoluteY }, /* $59 */ + { "phy", 1, flNone, OH_Implicit }, /* $5a */ + { "", 1, flIllegal, OH_Illegal, }, /* $5b */ + { "", 1, flIllegal, OH_Illegal, }, /* $5c */ + { "eor", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5d */ + { "lsr", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $5e */ + { "bbr5", 3, flUseLabel, OH_BitBranch }, /* $5f */ + { "rts", 1, flNone, OH_Rts }, /* $60 */ + { "adc", 2, flUseLabel, OH_DirectXIndirect }, /* $61 */ + { "", 1, flIllegal, OH_Illegal, }, /* $62 */ + { "", 1, flIllegal, OH_Illegal, }, /* $63 */ + { "stz", 2, flUseLabel, OH_Direct }, /* $64 */ + { "adc", 2, flUseLabel, OH_Direct }, /* $65 */ + { "ror", 2, flUseLabel, OH_Direct }, /* $66 */ + { "rmb6", 2, flUseLabel, OH_Direct, }, /* $67 */ + { "pla", 1, flNone, OH_Implicit }, /* $68 */ + { "adc", 2, flNone, OH_Immediate }, /* $69 */ + { "ror", 1, flNone, OH_Accumulator }, /* $6a */ + { "", 1, flIllegal, OH_Illegal, }, /* $6b */ + { "jmp", 3, flLabel, OH_JmpAbsoluteIndirect }, /* $6c */ + { "adc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6d */ + { "ror", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $6e */ + { "bbr6", 3, flUseLabel, OH_BitBranch }, /* $6f */ + { "bvs", 2, flLabel, OH_Relative }, /* $70 */ + { "adc", 2, flUseLabel, OH_DirectIndirectY }, /* $71 */ + { "adc", 2, flUseLabel, OH_DirectIndirect, }, /* $72 */ + { "", 1, flIllegal, OH_Illegal, }, /* $73 */ + { "stz", 2, flUseLabel, OH_DirectX }, /* $74 */ + { "adc", 2, flUseLabel, OH_DirectX }, /* $75 */ + { "ror", 2, flUseLabel, OH_DirectX }, /* $76 */ + { "rmb7", 2, flUseLabel, OH_Direct, }, /* $77 */ + { "sei", 1, flNone, OH_Implicit }, /* $78 */ + { "adc", 3, flUseLabel, OH_AbsoluteY }, /* $79 */ + { "ply", 1, flNone, OH_Implicit }, /* $7a */ + { "", 1, flIllegal, OH_Illegal, }, /* $7b */ + { "jmp", 3, flLabel, OH_AbsoluteXIndirect }, /* $7c */ + { "adc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7d */ + { "ror", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $7e */ + { "bbr7", 3, flUseLabel, OH_BitBranch }, /* $7f */ + { "bra", 2, flLabel, OH_Relative }, /* $80 */ + { "sta", 2, flUseLabel, OH_DirectXIndirect }, /* $81 */ + { "", 1, flIllegal, OH_Illegal, }, /* $82 */ + { "", 1, flIllegal, OH_Illegal, }, /* $83 */ + { "sty", 2, flUseLabel, OH_Direct }, /* $84 */ + { "sta", 2, flUseLabel, OH_Direct }, /* $85 */ + { "stx", 2, flUseLabel, OH_Direct }, /* $86 */ + { "smb0", 2, flUseLabel, OH_Direct, }, /* $87 */ + { "dey", 1, flNone, OH_Implicit }, /* $88 */ + { "bit", 2, flNone, OH_Immediate }, /* $89 */ + { "txa", 1, flNone, OH_Implicit }, /* $8a */ + { "", 1, flIllegal, OH_Illegal, }, /* $8b */ + { "sty", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8c */ + { "sta", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8d */ + { "stx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $8e */ + { "bbs0", 3, flUseLabel, OH_BitBranch }, /* $8f */ + { "bcc", 2, flLabel, OH_Relative }, /* $90 */ + { "sta", 2, flUseLabel, OH_DirectIndirectY }, /* $91 */ + { "sta", 2, flUseLabel, OH_DirectIndirect }, /* $92 */ + { "", 1, flIllegal, OH_Illegal, }, /* $93 */ + { "sty", 2, flUseLabel, OH_DirectX }, /* $94 */ + { "sta", 2, flUseLabel, OH_DirectX }, /* $95 */ + { "stx", 2, flUseLabel, OH_DirectY }, /* $96 */ + { "smb1", 2, flUseLabel, OH_Direct, }, /* $97 */ + { "tya", 1, flNone, OH_Implicit }, /* $98 */ + { "sta", 3, flUseLabel, OH_AbsoluteY }, /* $99 */ + { "txs", 1, flNone, OH_Implicit }, /* $9a */ + { "", 1, flIllegal, OH_Illegal, }, /* $9b */ + { "stz", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $9c */ + { "sta", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9d */ + { "stz", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $9e */ + { "bbs1", 3, flUseLabel, OH_BitBranch }, /* $9f */ + { "ldy", 2, flNone, OH_Immediate }, /* $a0 */ + { "lda", 2, flUseLabel, OH_DirectXIndirect }, /* $a1 */ + { "ldx", 2, flNone, OH_Immediate }, /* $a2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $a3 */ + { "ldy", 2, flUseLabel, OH_Direct }, /* $a4 */ + { "lda", 2, flUseLabel, OH_Direct }, /* $a5 */ + { "ldx", 2, flUseLabel, OH_Direct }, /* $a6 */ + { "smb2", 2, flUseLabel, OH_Direct, }, /* $a7 */ + { "tay", 1, flNone, OH_Implicit }, /* $a8 */ + { "lda", 2, flNone, OH_Immediate }, /* $a9 */ + { "tax", 1, flNone, OH_Implicit }, /* $aa */ + { "", 1, flIllegal, OH_Illegal, }, /* $ab */ + { "ldy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ac */ + { "lda", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ad */ + { "ldx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ae */ + { "bbs2", 3, flUseLabel, OH_BitBranch }, /* $af */ + { "bcs", 2, flLabel, OH_Relative }, /* $b0 */ + { "lda", 2, flUseLabel, OH_DirectIndirectY }, /* $b1 */ + { "lda", 2, flUseLabel, OH_DirectIndirect }, /* $b2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $b3 */ + { "ldy", 2, flUseLabel, OH_DirectX }, /* $b4 */ + { "lda", 2, flUseLabel, OH_DirectX }, /* $b5 */ + { "ldx", 2, flUseLabel, OH_DirectY }, /* $b6 */ + { "smb3", 2, flUseLabel, OH_Direct, }, /* $b7 */ + { "clv", 1, flNone, OH_Implicit }, /* $b8 */ + { "lda", 3, flUseLabel, OH_AbsoluteY }, /* $b9 */ + { "tsx", 1, flNone, OH_Implicit }, /* $ba */ + { "", 1, flIllegal, OH_Illegal, }, /* $bb */ + { "ldy", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bc */ + { "lda", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $bd */ + { "ldx", 3, flUseLabel|flAbsOverride, OH_AbsoluteY }, /* $be */ + { "bbs3", 3, flUseLabel, OH_BitBranch }, /* $bf */ + { "cpy", 2, flNone, OH_Immediate }, /* $c0 */ + { "cmp", 2, flUseLabel, OH_DirectXIndirect }, /* $c1 */ + { "", 1, flIllegal, OH_Illegal, }, /* $c2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $c3 */ + { "cpy", 2, flUseLabel, OH_Direct }, /* $c4 */ + { "cmp", 2, flUseLabel, OH_Direct }, /* $c5 */ + { "dec", 2, flUseLabel, OH_Direct }, /* $c6 */ + { "smb4", 2, flUseLabel, OH_Direct, }, /* $c7 */ + { "iny", 1, flNone, OH_Implicit }, /* $c8 */ + { "cmp", 2, flNone, OH_Immediate }, /* $c9 */ + { "dex", 1, flNone, OH_Implicit }, /* $ca */ + { "wai", 1, flNone, OH_Implicit }, /* $cb */ + { "cpy", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cc */ + { "cmp", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $cd */ + { "dec", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ce */ + { "bbs4", 3, flUseLabel, OH_BitBranch }, /* $cf */ + { "bne", 2, flLabel, OH_Relative }, /* $d0 */ + { "cmp", 2, flUseLabel, OH_DirectIndirectY }, /* $d1 */ + { "cmp", 2, flUseLabel, OH_DirectIndirect }, /* $d2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $d3 */ + { "", 1, flIllegal, OH_Illegal, }, /* $d4 */ + { "cmp", 2, flUseLabel, OH_DirectX }, /* $d5 */ + { "dec", 2, flUseLabel, OH_DirectX }, /* $d6 */ + { "smb5", 2, flUseLabel, OH_Direct, }, /* $d7 */ + { "cld", 1, flNone, OH_Implicit }, /* $d8 */ + { "cmp", 3, flUseLabel, OH_AbsoluteY }, /* $d9 */ + { "phx", 1, flNone, OH_Implicit }, /* $da */ + { "stp", 1, flNone, OH_Implicit }, /* $db */ + { "", 1, flIllegal, OH_Illegal, }, /* $dc */ + { "cmp", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $dd */ + { "dec", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $de */ + { "bbs5", 3, flUseLabel, OH_BitBranch }, /* $df */ + { "cpx", 2, flNone, OH_Immediate }, /* $e0 */ + { "sbc", 2, flUseLabel, OH_DirectXIndirect }, /* $e1 */ + { "", 1, flIllegal, OH_Illegal, }, /* $e2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $e3 */ + { "cpx", 2, flUseLabel, OH_Direct }, /* $e4 */ + { "sbc", 2, flUseLabel, OH_Direct }, /* $e5 */ + { "inc", 2, flUseLabel, OH_Direct }, /* $e6 */ + { "smb6", 2, flUseLabel, OH_Direct, }, /* $e7 */ + { "inx", 1, flNone, OH_Implicit }, /* $e8 */ + { "sbc", 2, flNone, OH_Immediate }, /* $e9 */ + { "nop", 1, flNone, OH_Implicit }, /* $ea */ + { "", 1, flIllegal, OH_Illegal, }, /* $eb */ + { "cpx", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ec */ + { "sbc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ed */ + { "inc", 3, flUseLabel|flAbsOverride, OH_Absolute }, /* $ee */ + { "bbs6", 3, flUseLabel, OH_BitBranch }, /* $ef */ + { "beq", 2, flLabel, OH_Relative }, /* $f0 */ + { "sbc", 2, flUseLabel, OH_DirectIndirectY }, /* $f1 */ + { "sbc", 2, flUseLabel, OH_DirectIndirect }, /* $f2 */ + { "", 1, flIllegal, OH_Illegal, }, /* $f3 */ + { "", 1, flIllegal, OH_Illegal, }, /* $f4 */ + { "sbc", 2, flUseLabel, OH_DirectX }, /* $f5 */ + { "inc", 2, flUseLabel, OH_DirectX }, /* $f6 */ + { "smb7", 2, flUseLabel, OH_Direct, }, /* $f7 */ + { "sed", 1, flNone, OH_Implicit }, /* $f8 */ + { "sbc", 3, flUseLabel, OH_AbsoluteY }, /* $f9 */ + { "plx", 1, flNone, OH_Implicit }, /* $fa */ + { "", 1, flIllegal, OH_Illegal, }, /* $fb */ + { "", 1, flIllegal, OH_Illegal, }, /* $fc */ + { "sbc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fd */ + { "inc", 3, flUseLabel|flAbsOverride, OH_AbsoluteX }, /* $fe */ + { "bbs7", 3, flUseLabel, OH_BitBranch }, /* $ff */ +}; diff --git a/src/da65/opcw65c02.h b/src/da65/opcw65c02.h new file mode 100644 index 000000000..0805ce5dd --- /dev/null +++ b/src/da65/opcw65c02.h @@ -0,0 +1,58 @@ +/*****************************************************************************/ +/* */ +/* opcw65c02.h */ +/* */ +/* W65C02 opcode description table */ +/* */ +/* */ +/* */ +/* (C) 2003 Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef OPCW65C02_H +#define OPCW65C02_H + + + +#include "opcdesc.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Descriptions for all opcodes */ +extern const OpcDesc OpcTable_W65C02[256]; + + + +/* End of opcw65c02.h */ + +#endif From b38422ef9f40cf5b5240d3164ea599153a2fc853 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 00:55:41 +0200 Subject: [PATCH 648/707] 65CE02 has phz and asw --- src/ca65/instr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index b920755d3..aed6966bf 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -732,7 +732,7 @@ static const struct { /* Instruction table for the 65CE02 */ static const struct { unsigned Count; - InsDesc Ins[131]; + InsDesc Ins[133]; } InsTab65CE02 = { /* CAUTION: table must be sorted for bsearch */ sizeof (InsTab65CE02.Ins) / sizeof (InsTab65CE02.Ins[0]), @@ -742,6 +742,7 @@ static const struct { { "AND", 0x080A66C, 0x20, 0, PutAll }, { "ASL", 0x000006e, 0x02, 1, PutAll }, { "ASR", 0x0000026, 0x43, 0, Put4510 }, + { "ASW", 0x0000008, 0xcb, 6, PutAll }, { "BBR0", 0x0000000, 0x0F, 0, PutBitBranch }, { "BBR1", 0x0000000, 0x1F, 0, PutBitBranch }, { "BBR2", 0x0000000, 0x2F, 0, PutBitBranch }, @@ -819,6 +820,7 @@ static const struct { { "PHW", 0x8000008, 0xf4, 1, PutAll }, { "PHX", 0x0000001, 0xda, 0, PutAll }, { "PHY", 0x0000001, 0x5a, 0, PutAll }, + { "PHZ", 0x0000001, 0xdb, 0, PutAll }, { "PLA", 0x0000001, 0x68, 0, PutAll }, { "PLP", 0x0000001, 0x28, 0, PutAll }, { "PLX", 0x0000001, 0xfa, 0, PutAll }, From f09aaeb085de461918a9792c833ce9cb1b7d4fca Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 00:58:44 +0200 Subject: [PATCH 649/707] update docs a bit, create a seperate CPU page --- doc/ca65.sgml | 99 ++------------- doc/cpus.sgml | 342 ++++++++++++++++++++++++++++++++++++++++++++++++++ doc/da65.sgml | 12 +- 3 files changed, 364 insertions(+), 89 deletions(-) create mode 100644 doc/cpus.sgml diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 7b36abec5..6886e48bd 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -459,6 +459,8 @@ The assembler accepts <tt><ref id=".PM740" name=".PM740"></tt> command was given). </itemize> +for more details on the various CPUs, see <tt><htmlurl url="cpus.html" name="here"></tt>. + On 6502-derived platforms the <tt/BRK/ instruction has an optional signature byte. If omitted, the assembler will only produce only 1 byte. @@ -535,58 +537,22 @@ Supported undocumented instructions: <sect2>65SC02 mode<label id="65SC02-mode"><p> -65SC02 mode supports all regular 6502 instructions, plus the following: - -<tscreen><verb> -$04 tsb zp -$0c tsb abs16 -$12 ora (zp) -$14 trb zp -$1a inc -$1c trb abs16 -$32 and (zp) -$34 bit zp, x -$3a dec -$3c bit abs16, x -$52 eor (zp) -$5a phy -$64 stz zp -$72 adc (zp) -$74 stz zp, x -$7a ply -$7c jmp (abs16, x) -$80 bra rel8 -$89 bit #imm8 -$92 sta (zp) -$9c stz abs16 -$9e stz abs16, x -$b2 lda (zp) -$d2 cmp (zp) -$da phx -$f2 sbc (zp) -$fa plx -</verb></tscreen> +65SC02 mode supports all regular 6502 instructions, plus the original CMOS +instructions. -<sect2>65C02 mode<label id="65C02-mode"><p> +<sect2>65C02 mode (CMOS with Rockwell extensions)<label id="65C02-mode"><p> -65C02 mode supports all "official" W65C02 opcodes. +65C02 mode supports all original CMOS instructions, plus the Rockwell (bit +manipulation instructions) extensions. -The R65C02 adds bit manipulation instructions: -<tscreen><verb> -smbB zp set bit in zp location -rmbB zp reset bit in zp location -bbsB zp, rel8 branch if bit is set in zp location -bbrB zp, rel8 branch if bit is reset in zp location -</verb></tscreen> +<sect2>W65C02 mode (CMOS with WDC extensions)<label id="W65C02-mode"><p> -And the W65C02 adds those: +W65C02 mode supports the Rockwell extensions, plus wai and stp. -<tscreen><verb> -$cb wai wait for interrupt -$db stp wait for reset -</verb></tscreen> + +<sect2>65CE02 mode<label id="65CE02-mode"><p> <sect2>4510 mode<label id="4510-mode"><p> @@ -595,14 +561,6 @@ The 4510 is a microcontroller that is the core of the Commodore C65 aka C64DX. It contains among other functions a slightly modified 65CE02/4502 CPU, to allow address mapping for 20 bits of address space (1 megabyte addressable area). -The 4510 mode supports the complete (legal) 65CE02 instruction set, plus these -three, which were changed/added: -<tscreen><verb> -$5c map "4-byte NOP reserved for future expansion" on 65CE02 -$cb asw $1234 wai on W65C02 -$db phz stp on W65C02 -</verb></tscreen> - As compared to the description of the CPU in the <url url="http://www.zimmers.net/anonftp/pub/cbm/c65/c65manualupdated.txt.gz" name="C65 System Specification"> @@ -626,40 +584,9 @@ The 45GS02 is a microcontroller that is the core of the MEGA65. It is an extension of the 4510 CPU and adds 32-bit addressing and a 32-bit pseudo register Q that is comprised of the four registers A, X, Y, and Z. -<sect2>HUC6280 mode<label id="HUC6280-mode"><p> +<sect2>HUC6280 mode (CMOS with Hudson extensions)<label id="HUC6280-mode"><p> -The HUC6280 is a superset of the R65C02. It adds some other instructions: - -<tscreen><verb> -$02 sxy -$03 st0 #{imm} -$13 st1 #{imm} -$22 sax -$23 st2 #{imm} -$42 say -$43 tma #{imm} -$44 bsr {rel} -$53 tam #{imm} -$54 csl -$62 cla -$73 tii {addr}, {addr}, {addr} -$82 clx -$83 tst #{imm}, {zp} -$82 clx -$83 tst #{imm}, {zp} -$93 tst #{imm}, {addr} -$a3 tst #{imm}, {zp}, x -$b3 tst #{imm}, {addr}, x -$c2 cly -$c3 tdd {addr}, {addr}, {addr} -$d3 tin {addr}, {addr}, {addr} -$d4 csh -$e3 tia {addr}, {addr}, {addr} -$f3 tai {addr}, {addr}, {addr} -$f4 set -</verb></tscreen> - -Note that this CPU does not implement <tt>wai</tt> and <tt>stp</tt>. +The HUC6280 is a superset of 65C02, used in the PC Engine. <sect2>M740 mode<label id="M740-mode"><p> diff --git a/doc/cpus.sgml b/doc/cpus.sgml new file mode 100644 index 000000000..ec6c550ee --- /dev/null +++ b/doc/cpus.sgml @@ -0,0 +1,342 @@ +<!doctype linuxdoc system> + +<article> +<title>ca65/da65 Users Guide +<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> +<url url="mailto:groepaz@gmx.net" name="Groepaz"> + +<abstract> +An Overview on all supported CPUs +</abstract> + +<!-- Table of contents --> +<toc> + +<!-- Begin the document --> + +<sect>Overview<p> + + +<sect1>Supported CPUs<p> + + <itemize> + <item><ref id="6502-mode" name="6502"> - NMOS 6502 (all legal instructions) + <item><ref id="6502X-mode" name="6502X"> - NMOS 6502 with all undocumented instructions + <item><ref id="DTV-mode" name="6502DTV"> - the emulated CPU of the C64DTV device + <item><ref id="65SC02-mode" name="65SC02"> - first CMOS instruction set (no bit manipulation) + <item><ref id="65C02-mode" name="65C02"> - full CMOS instruction set (has bit manipulation) + <item><ref id="W65C02-mode" name="W65C02"> - CMOS with WDC extensions + <item><ref id="65CE02-mode" name="65CE02"> - CMOS with GTE extensions + <item><ref id="65816-mode" name="65816"> - the CPU of the SNES, and the SCPU + <item><ref id="HUC6280-mode" name="HuC6280"> - the CPU of the PC engine + <item><ref id="4510-mode" name="4510"> - the CPU of the Commodore C65 + <item><ref id="45GS02-mode" name="45GS02"> - the CPU of the Commodore MEGA65 + <item><ref id="M740-mode" name="M740"> - a Microcontroller by Mitsubishi + <item><ref id="sweet16-mode" name="Sweet16"> - an interpreter for a pseudo 16 bit CPU + </itemize> + + +<sect2>6502 mode<label id="6502-mode"><p> + +The default (no CPU given on the command line or in the <tt/GLOBAL/ section of +the info file) is the 6502 CPU. The disassembler knows all "official" opcodes +for this CPU. Invalid opcodes are translated into <tt/.byte/ commands. + +<sect2>6502X mode<label id="6502X-mode"><p> + +6502X mode is an extension to the normal 6502 mode. In this mode, several +mnemonics for undocumented instructions of the NMOS 6502 CPUs are accepted. + +Note: Since these instructions are undocumented, there are no official mnemonics +for them. + +<itemize> +<item><tt>ALR: A:=(A and #{imm})/2;</tt> +<item><tt>ANC: A:= A and #{imm};</tt> Generates opcode $0B. +<item><tt>ANE: A:= (A or CONST) and X and #{imm};</tt> +<item><tt>ARR: A:=(A and #{imm})/2;</tt> +<item><tt>AXS: X:=A and X-#{imm};</tt> +<item><tt>DCP: {addr}:={addr}-1; A-{addr};</tt> +<item><tt>ISC: {addr}:={addr}+1; A:=A-{addr};</tt> +<item><tt>JAM:</tt> +<item><tt>LAS: A,X,S:={addr} and S;</tt> +<item><tt>LAX: A,X:={addr};</tt> +<item><tt>NOP: #{imm}; zp; zp,x; abs; abs,x</tt> +<item><tt>RLA: {addr}:={addr}rol; A:=A and {addr};</tt> +<item><tt>RRA: {addr}:={addr}ror; A:=A adc {addr};</tt> +<item><tt>SAX: {addr}:=A and X;</tt> +<item><tt>SHA: {addr}:=A and X and {addr hi +1};</tt> +<item><tt>SHX: {addr}:=X and {addr hi +1};</tt> +<item><tt>SHY: {addr}:=Y and {addr hi +1};</tt> +<item><tt>SLO: {addr}:={addr}*2; A:=A or {addr};</tt> +<item><tt>SRE: {addr}:={addr}/2; A:=A xor {addr};</tt> +<item><tt>TAS: {addr}:=A and X and {addr hi +1}; SP:=A and X;</tt> +</itemize> + + +<sect2>DTV mode<label id="DTV-mode"><p> + +The C64DTV CPU is based on the 6510, but adds some instructions, and does not +support all undocumented instructions. + +<itemize> +<item><tt>bra {rel}</tt> Generates opcode $12. +<item><tt>sac #{imm}</tt> Generates opcode $32. +<item><tt>sir #{imm}</tt> Generates opcode $42. +</itemize> + +Supported undocumented instructions: + +<itemize> +<item><tt>ALR: A:=(A and #{imm})/2;</tt> +<item><tt>ANC: A:=A and #{imm};</tt> Generates opcode $0B. +<item><tt>ARR: A:=(A and #{imm})/2;</tt> +<item><tt>AXS: X:=A and X-#{imm};</tt> +<item><tt>LAS: A,X,S:={addr} and S;</tt> +<item><tt>LAX: A,X:={addr};</tt> +<item><tt>NOP: #{imm}; zp; zp,x; abs; abs,x</tt> +<item><tt>RLA: {addr}:={addr}rol; A:=A and {addr};</tt> +<item><tt>RRA: {addr}:={addr}ror; A:=A adc {addr};</tt> +<item><tt>SHX: {addr}:=X and {addr hi +1};</tt> +<item><tt>SHY: {addr}:=y and {addr hi +1};</tt> +</itemize> + + +<sect2>65SC02 (Original CMOS)<label id="65SC02-mode"><p> + +The first CMOS instruction set, without bit manipulation or wai/stp. + +<tscreen><verb> +$04 tsb zp +$0c tsb abs16 +$12 ora (zp) +$14 trb zp +$1a inc +$1c trb abs16 +$32 and (zp) +$34 bit zp, x +$3a dec +$3c bit abs16, x +$52 eor (zp) +$5a phy +$64 stz zp +$72 adc (zp) +$74 stz zp, x +$7a ply +$7c jmp (abs16, x) +$80 bra rel8 +$89 bit #imm8 +$92 sta (zp) +$9c stz abs16 +$9e stz abs16, x +$b2 lda (zp) +$d2 cmp (zp) +$da phx +$f2 sbc (zp) +$fa plx +</verb></tscreen> + + +<sect2>65C02 (CMOS with Rockwell extensions)<label id="65C02-mode"><p> + +The 65C02 understands the same opcodes as the 65SC02, plus 16 additional bit +manipulation and bit test-and-branch commands. + +The R65C02 adds bit manipulation instructions: + +<tscreen><verb> +smbB zp set bit in zp location +rmbB zp reset bit in zp location +bbsB zp, rel8 branch if bit is set in zp location +bbrB zp, rel8 branch if bit is reset in zp location +</verb></tscreen> + + +<sect2>W65C02 (CMOS with WDC extensions)<label id="W65C02-mode"><p> + +This mode also supports wai/stp. + +<tscreen><verb> +$cb wai wait for interrupt +$db stp wait for reset +</verb></tscreen> + + +<sect2>65CE02 (CMOS with GTE extensions)<label id="65CE02-mode"><p> + +<tscreen><verb> +$02 cle clear stack extend disable +$03 see set stack extend disable +$0b tsy transfer stack_ptr_high to Y +$12 ora (zp), z +$13 lbpl rel16 +$1b inz increment Z +$22 jsr (abs16) +$23 jsr (abs16, x) +$2b tys transfer Y to stack_ptr_high +$32 and (zp), z +$33 lbmi rel16 +$3b dez decrement Z +$42 neg negate A +$43 asr +$44 asr zp +$4b taz transfer A to Z +$52 eor (zp), z +$53 lbvc rel16 +$54 asr zp, x +$5b tab +$5c aug "4-byte NOP reserved for future expansion" +$62 rtn #imm8 +$63 lbsr rel16 relative jsr, "branch to subroutine" +$64 stz zp store Z +$6b tza transfer Z to A +$72 adc (zp), z +$73 lbvs rel16 +$74 stz zp, x store Z +$7b tba +$82 sta (off8, s), y +$83 lbra rel16 relative jmp +$8b sty abs16, x +$92 sta (zp), z +$93 lbcc rel16 +$9b stx abs16, y +$9c stz abs16 store Z +$9e stz abs16, x store Z +$a3 ldz #imm8 +$ab ldz abs16 +$b2 lda (zp), z +$b3 lbcs rel16 +$bb ldz abs16, x +$c2 cpz #imm8 +$c3 dew zp +$cb asw abs16 +$d2 cmp (zp), z +$d3 lbne rel16 +$d4 cpz zp +$db phz push Z +$dc cpz abs16 +$e2 lda (off8, s), y +$e3 inw zp +$eb row abs16 +$f2 sbc (zp), z +$f3 lbeq rel16 +$f4 phw #imm16 +$fb plz pull Z +$fc phw abs16 +</verb></tscreen> + + +<sect2>4510 mode<label id="4510-mode"><p> + +The 4510 is a microcontroller that is the core of the Commodore C65 aka C64DX. +It contains among other functions a slightly modified 65CE02/4502 CPU, to allow +address mapping for 20 bits of address space (1 megabyte addressable area). + +The 4510 mode supports the complete (legal) 65CE02 instruction set, but changes +the 4-Byte NOP into the "map" instruction: + +<tscreen><verb> +$5c map "4-byte NOP reserved for future expansion" on 65CE02 +</verb></tscreen> + +For more information about the Commodore C65/C64DX and the 4510 CPU, see +<url url="http://www.zimmers.net/anonftp/pub/cbm/c65/"> and +<url url="https://en.wikipedia.org/wiki/Commodore_65" name="Wikipedia">. + + +<sect2>45GS02 mode<label id="45GS02-mode"><p> + +The 45GS02 is a microcontroller that is the core of the MEGA65. +It is an extension of the 4510 CPU and adds 32-bit addressing and a 32-bit +pseudo register Q that is comprised of the four registers A, X, Y, and Z. + + +<sect2>HUC6280 mode<label id="HUC6280-mode"><p> + +The HUC6280 is a superset of 65C02. It adds some other instructions: + +<tscreen><verb> +$02 sxy +$03 st0 #{imm} +$13 st1 #{imm} +$22 sax +$23 st2 #{imm} +$42 say +$43 tma #{imm} +$44 bsr {rel} +$53 tam #{imm} +$54 csl +$62 cla +$73 tii {addr}, {addr}, {addr} +$82 clx +$83 tst #{imm}, {zp} +$82 clx +$83 tst #{imm}, {zp} +$93 tst #{imm}, {addr} +$a3 tst #{imm}, {zp}, x +$b3 tst #{imm}, {addr}, x +$c2 cly +$c3 tdd {addr}, {addr}, {addr} +$d3 tin {addr}, {addr}, {addr} +$d4 csh +$e3 tia {addr}, {addr}, {addr} +$f3 tai {addr}, {addr}, {addr} +$f4 set +</verb></tscreen> + + +<sect2>M740 mode<label id="M740-mode"><p> + +The M740 is a microcontroller by Mitsubishi, which was marketed for embedded +devices in the mid 80s. It is a superset of 6502, and a subset of 65SC02, plus +some new instructions. + +For more information about the M740 Controllers, see +<url url="https://en.wikipedia.org/wiki/Mitsubishi_740" name="Wikipedia">. + + + +<sect2>65816 mode<label id="65816-mode"><p><p> + +The 65816 support requires annotating ranges with the M and X flag states. +This can be recorded with an emulator that supports Code and Data Logging, +for example. Disassemble one bank at a time. + + +<sect2>Sweet16<label id="sweet16-mode"><p><p> + +SWEET 16 is an interpreter for a pseudo 16 bit CPU written by Steve Wozniak +for the Apple ][ machines. It is available in the Apple ][ ROM. + +For more information about SWEET 16, see +<url url="http://www.6502.org/source/interpreters/sweet16.htm">. + + +<sect>Copyright<p> + +ca65 (and all cc65 binutils) are (C) Copyright 1998-2003 Ullrich von +Bassewitz. For usage of the binaries and/or sources the following +conditions do apply: + +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> diff --git a/doc/da65.sgml b/doc/da65.sgml index 314e552a9..e2c6d7e90 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -270,8 +270,10 @@ disassembler may be told which CPU to support: <item><ref id="6502-mode" name="6502"> - NMOS 6502 (all legal instructions) <item><ref id="6502X-mode" name="6502X"> - NMOS 6502 with all undocumented instructions <item><ref id="DTV-mode" name="6502DTV"> - the emulated CPU of the C64DTV device - <item><ref id="65SC02-mode" name="65SC02"> - first CMOS instruction set (no bit manipulation, no wai/stp) - <item><ref id="65C02-mode" name="65C02"> - full CMOS instruction set (has bit manipulation and wai/stp) + <item><ref id="65SC02-mode" name="65SC02"> - first CMOS instruction set (no bit manipulation) + <item><ref id="65C02-mode" name="65C02"> - full CMOS instruction set (has bit manipulation) + <item><ref id="W65C02-mode" name="W65C02"> - CMOS with WDC extensions + <item><ref id="65CE02-mode" name="65CE02"> - CMOS with GTE extensions <item><ref id="65816-mode" name="65816"> - the CPU of the SNES, and the SCPU <item><ref id="HUC6280-mode" name="HuC6280"> - the CPU of the PC engine <item><ref id="4510-mode" name="4510"> - the CPU of the Commodore C65 @@ -279,7 +281,7 @@ disassembler may be told which CPU to support: <item><ref id="M740-mode" name="M740"> - a Microcontroller by Mitsubishi </itemize> -for more details on the various CPUs, see <tt><htmlurl url="ca65.html#6502-mode" name="here"></tt>. +for more details on the various CPUs, see <tt><htmlurl url="cpus.html" name="here"></tt>. <sect2>6502 mode<label id="6502-mode"><p> @@ -308,8 +310,12 @@ The first CMOS instruction set, without bit manipulation or wai/stp. The 65C02 understands the same opcodes as the 65SC02, plus 16 additional bit manipulation and bit test-and-branch commands. +<sect2>W65C02 mode<label id="W65C02-mode"><p> + This mode also supports wai/stp. +<sect2>65CE02 mode<label id="65CE02-mode"><p> + <sect2>4510 mode<label id="4510-mode"><p> From 0b49d66f05a08068eb286ecd8a4b184aab4a9636 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 01:06:37 +0200 Subject: [PATCH 650/707] sort table --- src/ca65/instr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index aed6966bf..ce45adfd6 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -743,6 +743,7 @@ static const struct { { "ASL", 0x000006e, 0x02, 1, PutAll }, { "ASR", 0x0000026, 0x43, 0, Put4510 }, { "ASW", 0x0000008, 0xcb, 6, PutAll }, + { "AUG", 0x0000001, 0x5C, 0, PutAll }, { "BBR0", 0x0000000, 0x0F, 0, PutBitBranch }, { "BBR1", 0x0000000, 0x1F, 0, PutBitBranch }, { "BBR2", 0x0000000, 0x2F, 0, PutBitBranch }, @@ -810,7 +811,6 @@ static const struct { { "LDY", 0x080006C, 0xa0, 1, PutAll }, { "LDZ", 0x0800048, 0xa3, 1, Put4510 }, { "LSR", 0x000006F, 0x42, 1, PutAll }, - { "AUG", 0x0000001, 0x5C, 0, PutAll }, { "NEG", 0x0000001, 0x42, 0, PutAll }, { "NOP", 0x0000001, 0xea, 0, PutAll }, /* == EOM */ { "ORA", 0x080A66C, 0x00, 0, PutAll }, From d472ac8fc0ddbb797a7c22d0ab607ffcb3772992 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 01:44:40 +0200 Subject: [PATCH 651/707] fix table --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index 31fa8d7bf..30ace1817 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -63,7 +63,7 @@ const char* CPUNames[CPU_COUNT] = { "huc6280", "m740", "4510", - "45GS02" + "45GS02", "W65C02", /* CMOS with WDC extensions */ "65CE02", /* CMOS with GTE extensions */ }; From b05e418e0b941b807eb2dea29669b2d82d8db413 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 01:45:26 +0200 Subject: [PATCH 652/707] rp6502 actually uses W65C02 --- src/common/target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/target.c b/src/common/target.c index 51e015adc..a12f69bf9 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -246,7 +246,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "sym1", CPU_6502, BINFMT_BINARY, CTNone }, { "mega65", CPU_45GS02, BINFMT_BINARY, CTPET }, { "kim1", CPU_6502, BINFMT_BINARY, CTNone }, - { "rp6502", CPU_65C02, BINFMT_BINARY, CTNone }, + { "rp6502", CPU_W65C02, BINFMT_BINARY, CTNone }, { "agat", CPU_6502, BINFMT_BINARY, CTAgat }, }; From f6becd1b27210c3abb8a884e73b0da453c8c1d7f Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 01:51:13 +0200 Subject: [PATCH 653/707] compiler should know about W65C02/65CE02 as well --- src/cc65/codegen.c | 2 ++ src/cc65/main.c | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 42be0099a..04340af67 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -200,6 +200,8 @@ void g_preamble (void) case CPU_6502DTV: AddTextLine ("\t.setcpu\t\t\"6502DTV\""); break; case CPU_65SC02: AddTextLine ("\t.setcpu\t\t\"65SC02\""); break; case CPU_65C02: AddTextLine ("\t.setcpu\t\t\"65C02\""); break; + case CPU_W65C02: AddTextLine ("\t.setcpu\t\t\"W65C02\""); break; + case CPU_65CE02: AddTextLine ("\t.setcpu\t\t\"65CE02\""); break; case CPU_65816: AddTextLine ("\t.setcpu\t\t\"65816\""); break; case CPU_HUC6280: AddTextLine ("\t.setcpu\t\t\"HUC6280\""); break; case CPU_4510: AddTextLine ("\t.setcpu\t\t\"4510\""); break; diff --git a/src/cc65/main.c b/src/cc65/main.c index 648c603cd..5fc6ea343 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -373,10 +373,18 @@ static void DefineCpuMacros (void) DefineNumericMacro ("__CPU_65C02__", 1); break; + case CPU_65CE02: + DefineNumericMacro ("__CPU_65CE02__", 1); + break; + case CPU_65816: DefineNumericMacro ("__CPU_65816__", 1); break; + case CPU_W65C02: + DefineNumericMacro ("__CPU_W65C02__", 1); + break; + case CPU_HUC6280: DefineNumericMacro ("__CPU_HUC6280__", 1); break; @@ -402,6 +410,8 @@ static void DefineCpuMacros (void) DefineNumericMacro ("__CPU_ISET_6502DTV__", CPU_ISET_6502DTV); DefineNumericMacro ("__CPU_ISET_65SC02__", CPU_ISET_65SC02); DefineNumericMacro ("__CPU_ISET_65C02__", CPU_ISET_65C02); + DefineNumericMacro ("__CPU_ISET_W65C02__", CPU_ISET_W65C02); + DefineNumericMacro ("__CPU_ISET_65CE02__", CPU_ISET_65CE02); DefineNumericMacro ("__CPU_ISET_65816__", CPU_ISET_65816); DefineNumericMacro ("__CPU_ISET_HUC6280__", CPU_ISET_HUC6280); DefineNumericMacro ("__CPU_ISET_4510__", CPU_ISET_4510); From b08f306fde3ebc5c82d378756419f6c10ee3c8dc Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 02:05:08 +0200 Subject: [PATCH 654/707] fix test --- test/asm/val/ismnemonic.s | 101 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/test/asm/val/ismnemonic.s b/test/asm/val/ismnemonic.s index 2d131e7a9..e644bdb76 100644 --- a/test/asm/val/ismnemonic.s +++ b/test/asm/val/ismnemonic.s @@ -415,6 +415,107 @@ test_Ismnemonic smb5 test_Ismnemonic smb6 test_Ismnemonic smb7 test_Ismnemonic sta +test_Ismnemonic stx +test_Ismnemonic sty +test_Ismnemonic stz +test_Ismnemonic tax +test_Ismnemonic tay +test_Ismnemonic trb +test_Ismnemonic tsb +test_Ismnemonic tsx +test_Ismnemonic txa +test_Ismnemonic txs +test_Ismnemonic tya + + +.setcpu "W65C02" +test_Ismnemonic adc +test_Ismnemonic and +test_Ismnemonic asl +test_Ismnemonic bbr0 +test_Ismnemonic bbr1 +test_Ismnemonic bbr2 +test_Ismnemonic bbr3 +test_Ismnemonic bbr4 +test_Ismnemonic bbr5 +test_Ismnemonic bbr6 +test_Ismnemonic bbr7 +test_Ismnemonic bbs0 +test_Ismnemonic bbs1 +test_Ismnemonic bbs2 +test_Ismnemonic bbs3 +test_Ismnemonic bbs4 +test_Ismnemonic bbs5 +test_Ismnemonic bbs6 +test_Ismnemonic bbs7 +test_Ismnemonic bcc +test_Ismnemonic bcs +test_Ismnemonic beq +test_Ismnemonic bit +test_Ismnemonic bmi +test_Ismnemonic bne +test_Ismnemonic bpl +test_Ismnemonic bra +test_Ismnemonic brk +test_Ismnemonic bvc +test_Ismnemonic bvs +test_Ismnemonic clc +test_Ismnemonic cld +test_Ismnemonic cli +test_Ismnemonic clv +test_Ismnemonic cmp +test_Ismnemonic cpx +test_Ismnemonic cpy +test_Ismnemonic dea +test_Ismnemonic dec +test_Ismnemonic dex +test_Ismnemonic dey +test_Ismnemonic eor +test_Ismnemonic ina +test_Ismnemonic inc +test_Ismnemonic inx +test_Ismnemonic iny +test_Ismnemonic jmp +test_Ismnemonic jsr +test_Ismnemonic lda +test_Ismnemonic ldx +test_Ismnemonic ldy +test_Ismnemonic lsr +test_Ismnemonic nop +test_Ismnemonic ora +test_Ismnemonic pha +test_Ismnemonic php +test_Ismnemonic phx +test_Ismnemonic phy +test_Ismnemonic pla +test_Ismnemonic plp +test_Ismnemonic plx +test_Ismnemonic ply +test_Ismnemonic rmb0 +test_Ismnemonic rmb1 +test_Ismnemonic rmb2 +test_Ismnemonic rmb3 +test_Ismnemonic rmb4 +test_Ismnemonic rmb5 +test_Ismnemonic rmb6 +test_Ismnemonic rmb7 +test_Ismnemonic rol +test_Ismnemonic ror +test_Ismnemonic rti +test_Ismnemonic rts +test_Ismnemonic sbc +test_Ismnemonic sec +test_Ismnemonic sed +test_Ismnemonic sei +test_Ismnemonic smb0 +test_Ismnemonic smb1 +test_Ismnemonic smb2 +test_Ismnemonic smb3 +test_Ismnemonic smb4 +test_Ismnemonic smb5 +test_Ismnemonic smb6 +test_Ismnemonic smb7 +test_Ismnemonic sta test_Ismnemonic stp test_Ismnemonic stx test_Ismnemonic sty From c16b8dcf43aa29438073e09780858b35bfc1c716 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 02:08:01 +0200 Subject: [PATCH 655/707] add new files --- src/da65.vcxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/da65.vcxproj b/src/da65.vcxproj index 6610f907c..65dc3fccf 100644 --- a/src/da65.vcxproj +++ b/src/da65.vcxproj @@ -101,6 +101,8 @@ <ClCompile Include="da65\opc65816.c" /> <ClCompile Include="da65\opc65c02.c" /> <ClCompile Include="da65\opc65sc02.c" /> + <ClCompile Include="da65\opc65ce02.c" /> + <ClCompile Include="da65\opcw65c02.c" /> <ClCompile Include="da65\opchuc6280.c" /> <ClCompile Include="da65\opcm740.c" /> <ClCompile Include="da65\opctable.c" /> From c359cd92510ea3642c22ac462e3299472a7531f8 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 02:27:04 +0200 Subject: [PATCH 656/707] update test --- test/asm/cpudetect/allinst.inc | 71 +++++++++++++--------------------- 1 file changed, 27 insertions(+), 44 deletions(-) diff --git a/test/asm/cpudetect/allinst.inc b/test/asm/cpudetect/allinst.inc index 8e27a5429..423e7b74a 100644 --- a/test/asm/cpudetect/allinst.inc +++ b/test/asm/cpudetect/allinst.inc @@ -359,9 +359,9 @@ LABEL: ;------------------------------------------------------------------------------ -; The 65c02 is the CMOS re-design of the 6502. It has a few improvements: +; The 65sc02 is the original CMOS re-design of the 6502. ; -; 65C02 65ce02 +; 65SC02 65ce02 ; ; $04 tsb zp ; $0c tsb abs16 @@ -391,68 +391,61 @@ LABEL: ; $f2 sbc (zp) (-> sbc (zp), z) ; $fa plx -; FIXME: currently CPU_ISET_65SC02 and CPU_65SC02 really means "65C02" - -; FIXME: should really check for 65C02 - .if (.cpu .bitand CPU_ISET_65SC02) .scope ; 65c02 instruction set adds some extra legal instructions to 6502 tsb $12 ; $04 tsb $1234 ; $0c - ;ora ($12) ; $12 FIXME: not working with 4510:ora (zp), z + ora ($12) ; $12 FIXME: not working with 4510:ora (zp), z trb $12 ; $14 inc a ; $1a trb $1234 ; $1c - ;and ($12) ; $32 FIXME: not working with 4510:and (zp), z + and ($12) ; $32 FIXME: not working with 4510:and (zp), z bit $12,x ; $34 dec a ; $3a bit $1234,x ; $3c - ;eor ($12) ; $52 FIXME: not working with 4510:eor (zp), z + eor ($12) ; $52 FIXME: not working with 4510:eor (zp), z phy ; $5a stz $12 ; $64 - ;adc ($12) ; $72 FIXME: not working with 4510:adc (zp), z + adc ($12) ; $72 FIXME: not working with 4510:adc (zp), z stz $12,x ; $74 ply ; $7a jmp ($1234) ; $7c LABEL: bra LABEL ; $80 bit #$12 ; $89 - ;sta ($12) ; $92 FIXME: not working with 4510:sta (zp), z + sta ($12) ; $92 FIXME: not working with 4510:sta (zp), z stz $1234 ; $9c stz $1234,x ; $9e - ;lda ($12) ; $b2 FIXME: not working with 4510:lda (zp), z - ;cmp ($12) ; $d2 FIXME: not working with 4510:cmp (zp), z + lda ($12) ; $b2 FIXME: not working with 4510:lda (zp), z + cmp ($12) ; $d2 FIXME: not working with 4510:cmp (zp), z phx ; $da - ;sbc ($12) ; $f2 FIXME: not working with 4510:sbc (zp), z + sbc ($12) ; $f2 FIXME: not working with 4510:sbc (zp), z plx ; $fa .endscope .endif -; FIXME: hack so these opcodes get tested anyway, while 4510 is still quirky -.if (.cpu .bitand CPU_ISET_65SC02) -.if (.not .cpu = CPU_4510) - ora ($12) ; $12 - and ($12) ; $32 - eor ($12) ; $52 - adc ($12) ; $72 - sta ($12) ; $92 - lda ($12) ; $b2 - cmp ($12) ; $d2 - sbc ($12) ; $f2 -.endif -.endif -; TODO: R65C02 +; Rockwell Datasheet "R65C02, R65C102, R65C112 R65C00 Microprocessors (CPU)" 1987,rev6: +; +; The 8-bit R65C00 microprocessor family of devices are produced using CMOS [...] +; technology which provides advanced [...] performance speed and [...] over their +; NMOS counterparts, the R6500 family of microprocessor devices. [...] +; The CMOS family ... has been designed with many enhancements over the R6502 +; NMOS device [...] +; ; The R65C02 is a superset of the 65C02. It adds bit manipulation instructions: +; ; smbB zp set bit in zp location ; rmbB zp reset bit in zp location ; bbsB zp, rel8 branch if bit is set in zp location ; bbrB zp, rel8 branch if bit is reset in zp location - -; FIXME: currently CPU_ISET_65C02 and CPU_65C02 really means "W65C02" - -; FIXME: should really check for R65C02 +; +; 12 new instructions for a total of 68 +; 59 new op ocdes, for a total of 210 +; two new addressing modes +; seven software/operational enhancements +; two hardware enhancements .if (.cpu .bitand CPU_ISET_65C02) @@ -494,23 +487,17 @@ LABEL3: .endif -; TODO: W65C02 ; The W65C02 is a superset of the R65C02. It only adds two instructions: ; ; $cb wai wait for interrupt ; $db stp wait for reset -; FIXME: currently CPU_ISET_65C02 and CPU_65C02 really means "W65C02" - -; FIXME: should really check for W65C02 - -.if (.cpu = CPU_65C02) +.if (.cpu .bitand CPU_ISET_W65C02) wai ; $cb stp ; $db .endif -; TODO: 65CE02 ; The 65CE02 is another superset of the R65C02. It has several improvements: ; ; $02 cle clear stack extend disable @@ -572,9 +559,7 @@ LABEL3: ; $fb plz pull Z ; $fc phw abs16 -; FIXME: should really check for 65CE02 - -.if (.cpu .bitand CPU_ISET_4510) +.if (.cpu .bitand CPU_ISET_65CE02) .scope ; 65CE02 adds the following: cle ; $02 @@ -649,8 +634,6 @@ LABEL3: ; added to 65CE02 map ; $5c ("4-byte NOP reserved for future expansion" on 65CE02) - asw $1234 ; $cb (wai on W65C02) - phz ; $db (stp on W65C02) eom ; $ea "end of mapping" - but really just a NOP .endscope From e74bdab313368e12c39a130368839a0b754ad47a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 02:27:24 +0200 Subject: [PATCH 657/707] add compound instructions --- doc/cpus.sgml | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/doc/cpus.sgml b/doc/cpus.sgml index ec6c550ee..59eb940c2 100644 --- a/doc/cpus.sgml +++ b/doc/cpus.sgml @@ -250,6 +250,86 @@ The 45GS02 is a microcontroller that is the core of the MEGA65. It is an extension of the 4510 CPU and adds 32-bit addressing and a 32-bit pseudo register Q that is comprised of the four registers A, X, Y, and Z. +<tscreen><verb> +$42 $42 $05 orq $12 +$42 $42 $06 aslq $12 +$42 $42 $0a aslq +$42 $42 $0d orq $1234 +$42 $42 $0e aslq $1234 +$42 $42 $12 orq ($12) +$42 $42 $16 aslq $12,x +$42 $42 $1a inq +$42 $42 $1e aslq $1234,x +$42 $42 $24 bitq $12 +$42 $42 $25 andq $12 +$42 $42 $26 rolq $12 +$42 $42 $2a rolq +$42 $42 $2c bitq $1234 +$42 $42 $2d andq $1234 +$42 $42 $2e rolq $1234 +$42 $42 $32 andq ($12) +$42 $42 $36 rolq $12, x +$42 $42 $3a deq +$42 $42 $3e rolq $1234, x +$42 $42 $43 asrq +$42 $42 $44 asrq $12 +$42 $42 $45 eorq $12 +$42 $42 $46 lsrq $12 +$42 $42 $4a lsrq +$42 $42 $4d eorq $1234 +$42 $42 $4e lsrq $1234 +$42 $42 $52 eorq ($12) +$42 $42 $54 asrq $12, x +$42 $42 $56 lsrq $12, x +$42 $42 $5e lsrq $1234, x +$42 $42 $65 adcq $12 +$42 $42 $66 rorq $12 +$42 $42 $6a rorq +$42 $42 $6d adcq $1234 +$42 $42 $6e rorq $1234 +$42 $42 $72 adcq ($12) +$42 $42 $76 rorq $12, x +$42 $42 $7e rorq $1234, x +$42 $42 $85 stq $12 +$42 $42 $8d stq $1234 +$42 $42 $92 stq ($12) +$42 $42 $a5 ldq $12 +$42 $42 $ad ldq $1234 +$42 $42 $b2 ldq ($12), z +$42 $42 $c5 cmpq $12 +$42 $42 $c6 deq $12 +$42 $42 $cd cmpq $1234 +$42 $42 $ce deq $1234 +$42 $42 $d2 cmpq ($12) +$42 $42 $d6 deq $12, x +$42 $42 $de deq $1234, x +$42 $42 $e5 sbcq $12 +$42 $42 $e6 inq $12 +$42 $42 $ed sbcq $1234 +$42 $42 $ee inq $1234 +$42 $42 $f2 sbcq ($12) +$42 $42 $f6 inq $12, x +$42 $42 $fe inq $1234, x + +$ea $12 ora [$12], z +$ea $32 and [$12], z +$ea $52 eor [$12], z +$ea $72 adc [$12], z +$ea $92 sta [$12], z +$ea $b2 lda [$12], z +$ea $d2 cmp [$12], z +$ea $f2 sbc [$12], z + +$42 $42 $ea $12 orq [$12] +$42 $42 $ea $32 andq [$12] +$42 $42 $ea $52 eorq [$12] +$42 $42 $ea $72 adcq [$12] +$42 $42 $ea $92 stq [$12] +$42 $42 $ea $b2 ldq [$12], z +$42 $42 $ea $d2 cmpq [$12] +$42 $42 $ea $f2 sbcq [$12] +</verb></tscreen> + <sect2>HUC6280 mode<label id="HUC6280-mode"><p> From 8e4936d68d6bcf6ce3eca75681cd40e35214ff30 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 18:15:57 +0200 Subject: [PATCH 658/707] add related pseudos --- src/ca65/condasm.c | 22 ++++++++++++++++++++++ src/ca65/pseudo.c | 22 +++++++++++++++++++++- src/ca65/scanner.c | 4 ++++ src/ca65/token.h | 4 ++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index c63e54e3a..61d93ba98 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -474,6 +474,26 @@ void DoConditionals (void) CalcOverallIfCond (); break; + case TOK_IFPWC02: + D = AllocIf (".IFPWC02", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_W65C02); + } + ExpectSep (); + CalcOverallIfCond (); + break; + + case TOK_IFPCE02: + D = AllocIf (".IFPCE02", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_65CE02); + } + ExpectSep (); + CalcOverallIfCond (); + break; + case TOK_IFREF: D = AllocIf (".IFREF", 1); NextTok (); @@ -520,9 +540,11 @@ int CheckConditionals (void) case TOK_IFP45GS02: case TOK_IFP816: case TOK_IFPC02: + case TOK_IFPCE02: case TOK_IFPDTV: case TOK_IFPM740: case TOK_IFPSC02: + case TOK_IFPWC02: case TOK_IFREF: DoConditionals (); return 1; diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 7e52ecb5e..604eabb92 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1578,6 +1578,22 @@ static void DoPC02 (void) +static void DoPWC02 (void) +/* Switch to W65C02 CPU */ +{ + SetCPU (CPU_W65C02); +} + + + +static void DoPCE02 (void) +/* Switch to 65CE02 CPU */ +{ + SetCPU (CPU_65CE02); +} + + + static void DoP816 (void) /* Switch to 65816 CPU */ { @@ -2162,9 +2178,11 @@ static CtrlDesc CtrlCmdTab [] = { { ccKeepToken, DoConditionals }, /* .IFP45GS02 */ { ccKeepToken, DoConditionals }, /* .IFP816 */ { ccKeepToken, DoConditionals }, /* .IFPC02 */ + { ccKeepToken, DoConditionals }, /* .IFPCE02 */ { ccKeepToken, DoConditionals }, /* .IFPDTV */ { ccKeepToken, DoConditionals }, /* .IFPM740 */ { ccKeepToken, DoConditionals }, /* .IFPSC02 */ + { ccKeepToken, DoConditionals }, /* .IFPWC02 */ { ccKeepToken, DoConditionals }, /* .IFREF */ { ccNone, DoImport }, /* .IMPORT */ { ccNone, DoImportZP }, /* .IMPORTZP */ @@ -2199,7 +2217,8 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoP816 }, /* .P816 */ { ccNone, DoPageLength }, /* .PAGELEN, .PAGELENGTH */ { ccNone, DoUnexpected }, /* .PARAMCOUNT */ - { ccNone, DoPC02 }, /* .PSC02 */ + { ccNone, DoPC02 }, /* .PC02 */ + { ccNone, DoPCE02 }, /* .PCE02 */ { ccNone, DoPDTV }, /* .PDTV */ { ccNone, DoPM740 }, /* .PM740 */ { ccNone, DoPopCharmap }, /* .POPCHARMAP */ @@ -2210,6 +2229,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoPushCharmap }, /* .PUSHCHARMAP */ { ccNone, DoPushCPU }, /* .PUSHCPU */ { ccNone, DoPushSeg }, /* .PUSHSEG */ + { ccNone, DoPWC02 }, /* .PWC02 */ { ccNone, DoUnexpected }, /* .REF, .REFERENCED */ { ccNone, DoReferTo }, /* .REFTO, .REFERTO */ { ccNone, DoReloc }, /* .RELOC */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index dd0209856..143e83981 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -226,9 +226,11 @@ struct DotKeyword { { ".IFP45GS02", TOK_IFP45GS02 }, { ".IFP816", TOK_IFP816 }, { ".IFPC02", TOK_IFPC02 }, + { ".IFPCE02", TOK_IFPCE02 }, { ".IFPDTV", TOK_IFPDTV }, { ".IFPM740", TOK_IFPM740 }, { ".IFPSC02", TOK_IFPSC02 }, + { ".IFPWC02", TOK_IFPWC02 }, { ".IFREF", TOK_IFREF }, { ".IMPORT", TOK_IMPORT }, { ".IMPORTZP", TOK_IMPORTZP }, @@ -270,6 +272,7 @@ struct DotKeyword { { ".PAGELENGTH", TOK_PAGELENGTH }, { ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PC02", TOK_PC02 }, + { ".PCE02", TOK_PCE02 }, { ".PDTV", TOK_PDTV }, { ".PM740", TOK_PM740 }, { ".POPCHARMAP", TOK_POPCHARMAP }, @@ -280,6 +283,7 @@ struct DotKeyword { { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, + { ".PWC02", TOK_PWC02 }, { ".REF", TOK_REFERENCED }, { ".REFERENCED", TOK_REFERENCED }, { ".REFERTO", TOK_REFERTO }, diff --git a/src/ca65/token.h b/src/ca65/token.h index 9ca7ea657..a87719794 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -199,9 +199,11 @@ typedef enum token_t { TOK_IFP45GS02, TOK_IFP816, TOK_IFPC02, + TOK_IFPCE02, TOK_IFPDTV, TOK_IFPM740, TOK_IFPSC02, + TOK_IFPWC02, TOK_IFREF, TOK_IMPORT, TOK_IMPORTZP, @@ -237,6 +239,7 @@ typedef enum token_t { TOK_PAGELENGTH, TOK_PARAMCOUNT, TOK_PC02, + TOK_PCE02, TOK_PDTV, TOK_PM740, TOK_POPCHARMAP, @@ -247,6 +250,7 @@ typedef enum token_t { TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, + TOK_PWC02, TOK_REFERENCED, TOK_REFERTO, TOK_RELOC, From bf1dbc54fccaff246020cc477cfaae13102d7f29 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 18:17:13 +0200 Subject: [PATCH 659/707] fix instruction bitfields. 65CE02 derivates can not use 65SC02, because of the zp-ind-z clash --- asminc/cpu.mac | 15 +++++++++------ src/common/cpu.c | 7 +++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 728c99262..a006a9882 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -23,15 +23,18 @@ CPU_6502X = CPU_ISET_6502X | CPU_ISET_6502 CPU_6502DTV = CPU_ISET_6502DTV | CPU_ISET_6502 CPU_65SC02 = CPU_ISET_65SC02 | CPU_ISET_6502 CPU_65C02 = CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_65816 = CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_SWEET16 = CPU_ISET_SWEET16 +CPU_W65C02 = CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 + ; FIXME: CPU_ISET_65SC02 does not apply to the following, because the zp-indirect ; addressing was replaced with zp-indirect,z-indexed in 652SCE02 + ; NOTE: HUC6280 removes "wai" ($cb) and "stp" ($db) from the 65C02 instruction set CPU_HUC6280 = CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02 ; NOTE: 4510 replaces "wai" ($cb) and "stp" ($db) of the 65C02 instruction set -CPU_4510 = CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 -CPU_45GS02 = CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_4510 +CPU_4510 = CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 +CPU_45GS02 = CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510 CPU_M740 = CPU_ISET_M740 | CPU_ISET_6502 -CPU_W65C02 = CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 -CPU_65CE02 = CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 +CPU_65CE02 = CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02 + +CPU_65816 = CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 +CPU_SWEET16 = CPU_ISET_SWEET16 diff --git a/src/common/cpu.c b/src/common/cpu.c index 30ace1817..fbfe0a944 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -81,15 +81,14 @@ const unsigned CPUIsets[CPU_COUNT] = { /* FIXME: does 65816 have both wai/stp and indirect-zp (without z)? */ CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, CPU_ISET_SWEET16, - /* FIXME: HUC6280 does not have wai/stp */ CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, CPU_ISET_M740 | CPU_ISET_6502, /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ /* FIXME: 4510 does not have wai/stp */ - CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02, - CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_4510, + CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02, + CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510, CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, - CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; From 0168835456308db664fb024d3b61dde609abf9ee Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 18:17:37 +0200 Subject: [PATCH 660/707] handle extra address mode(s) for 65CE02 in the scanner --- src/ca65/scanner.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 143e83981..1b3673150 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -1285,7 +1285,7 @@ Again: break; case 'S': - if ((CPU == CPU_4510) || (CPU == CPU_45GS02) || (CPU == CPU_65816)) { + if ((CPU == CPU_65CE02) || (CPU == CPU_4510) || (CPU == CPU_45GS02) || (CPU == CPU_65816)) { CurTok.Tok = TOK_S; return; } @@ -1312,7 +1312,7 @@ Again: CurTok.Tok = TOK_OVERRIDE_ZP; return; } else { - if ((CPU == CPU_4510) || (CPU == CPU_45GS02)) { + if ((CPU == CPU_65CE02) || (CPU == CPU_4510) || (CPU == CPU_45GS02)) { CurTok.Tok = TOK_Z; return; } @@ -1324,7 +1324,8 @@ Again: } break; case 2: - if ((CPU == CPU_4510 || CPU == CPU_45GS02) && + /* FIXME: make sure we only alias "sp" to "s" when its really needed */ + if (((CPU == CPU_65CE02) || (CPU == CPU_4510) || (CPU == CPU_45GS02)) && (toupper (SB_AtUnchecked (&CurTok.SVal, 0)) == 'S') && (toupper (SB_AtUnchecked (&CurTok.SVal, 1)) == 'P')) { From ced83d0f4735d4c15ae4df531fc7f4b3a090e593 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 18:18:39 +0200 Subject: [PATCH 661/707] update tests --- test/asm/cpudetect/4510-cpudetect.ref | Bin 44 -> 60 bytes test/asm/cpudetect/45GS02-cpudetect.ref | Bin 64 -> 80 bytes test/asm/cpudetect/65ce02-cpudetect.ref | Bin 0 -> 47 bytes test/asm/cpudetect/cpudetect.s | 19 ++ test/asm/cpudetect/w65c02-cpudetect.ref | Bin 0 -> 63 bytes test/asm/opcodes/65ce02-opcodes.ref | Bin 0 -> 564 bytes test/asm/opcodes/65ce02-opcodes.s | 278 ++++++++++++++++++++++++ test/asm/opcodes/w65c02-opcodes.ref | Bin 0 -> 501 bytes test/asm/opcodes/w65c02-opcodes.s | 258 ++++++++++++++++++++++ 9 files changed, 555 insertions(+) create mode 100644 test/asm/cpudetect/65ce02-cpudetect.ref create mode 100644 test/asm/cpudetect/w65c02-cpudetect.ref create mode 100644 test/asm/opcodes/65ce02-opcodes.ref create mode 100644 test/asm/opcodes/65ce02-opcodes.s create mode 100644 test/asm/opcodes/w65c02-opcodes.ref create mode 100644 test/asm/opcodes/w65c02-opcodes.s diff --git a/test/asm/cpudetect/4510-cpudetect.ref b/test/asm/cpudetect/4510-cpudetect.ref index 484469a79bf38aa6e631fc1f0bc96cdb0ccf61bc..5eba7ec5af0efa1d652e9ee2af09583f5d9481b7 100644 GIT binary patch delta 25 gcmdO~nV=zJX6o!}V8q}Y5E}0p>>3hpVrpmr08Y&YF8}}l delta 9 QcmcD~nV`X9Vrpmr01A2m?*IS* diff --git a/test/asm/cpudetect/45GS02-cpudetect.ref b/test/asm/cpudetect/45GS02-cpudetect.ref index b6e8e797fe3a85e410b0b3ceee7db2a06acebc2c..3936f29027602a5936fa69c2572def662b39c1f5 100644 GIT binary patch delta 12 TcmZ<=n4rUAX6o!ZQ9%I!6!rrZ delta 7 OcmWG=n4mM!Mg#x}b^<N{ diff --git a/test/asm/cpudetect/65ce02-cpudetect.ref b/test/asm/cpudetect/65ce02-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..eca5a2b2a16b50a5ded7261981caf61e1862a096 GIT binary patch literal 47 fcmZ21#NZqd8t)nG8WL}2YG8!Sb4KI38W;fpFewaq literal 0 HcmV?d00001 diff --git a/test/asm/cpudetect/cpudetect.s b/test/asm/cpudetect/cpudetect.s index 545e2fa56..9f62e3ded 100644 --- a/test/asm/cpudetect/cpudetect.s +++ b/test/asm/cpudetect/cpudetect.s @@ -20,6 +20,15 @@ rmb0 $12 .endif +.ifpwc02 + wai + stp +.endif + +.ifpce02 + ldz #$12 +.endif + .ifp816 xba .endif @@ -64,6 +73,14 @@ .byte 0,"CPU_ISET_65C02" .endif +.if (.cpu .bitand CPU_ISET_W65C02) + .byte 0,"CPU_ISET_W65C02" +.endif + +.if (.cpu .bitand CPU_ISET_65CE02) + .byte 0,"CPU_ISET_65CE02" +.endif + .if (.cpu .bitand CPU_ISET_65816) .byte 0,"CPU_ISET_65816" .endif @@ -104,6 +121,8 @@ .p02X .psc02 .pc02 +.pwc02 +.pce02 .p816 .p4510 .p45GS02 diff --git a/test/asm/cpudetect/w65c02-cpudetect.ref b/test/asm/cpudetect/w65c02-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..094210464b1d6a9a4a25c310e4e11929c469b34d GIT binary patch literal 63 jcmX?oo549CG~P4VH6-55)W8Ut7wnA6N8yH>nF9F$Sh^9q literal 0 HcmV?d00001 diff --git a/test/asm/opcodes/65ce02-opcodes.ref b/test/asm/opcodes/65ce02-opcodes.ref new file mode 100644 index 0000000000000000000000000000000000000000..b65b12e616ea7649bc4f0750e57c77870140d231 GIT binary patch literal 564 zcmWN<1$Y%l6b4ZCpX_deJ-D-2aT45inA;XBKDf)`?$F{;q*!oT+=IKjySuv<Noj$g z#T|0Klfbee!eGOJi|`05VWPxLNtlu{g`ku9$sKZ~QXW!>lp+;UrwP0t(xzidZ)64| zGeT!#%4}ybk&!`E6tW^4vLi=MD_8D3OnI5|G3AH$edQEzwNfm86hDcdQLs?p6)sZL z$X|>sW@K^b5+&_YrOUveEXtvL1*>AE%1l+5sxnoBuI|@xYPz+Qsx9h>K-5LO`hnM= zVWY-IHZig(bhGAmi-?v=wL)vOL0hzIZ*}PStBL%LsS{IY=q`R&r<>bdsUD)I=p}wf z?>>Rox8EN@RDUA}7&#DnkU!Xt4n>ECC^ZzrFdQQ=a+EdtPb2?g8pAY}X&m%;e}Xg7 zout%cF-1%bn}+E#0xxD};LT#1ZR8vy=R(i3=GzObh1Mc0#u6;WvgOu_l}xLcRx_<( zS_{3-U+-*iH!8JBY!+L>wqo1%z}vCY$X!P6HgZqk?S<ZF?Y9qD2XP38aRf(k?6`H} zB-1IT(@bZW&O)E_&pQ{~i%MO>WpPDZ#kK2!cjM+QroWB6ZR8#3yVgBBHWVBB2lw$W z{=)-2d}PJNJ!X2s^pxot({tz-{{PNP_mxtwW5VOV5pTsiy#Ek*A3uF&ivPvPuSR}@ F{totBq=Nte literal 0 HcmV?d00001 diff --git a/test/asm/opcodes/65ce02-opcodes.s b/test/asm/opcodes/65ce02-opcodes.s new file mode 100644 index 000000000..ecdd7d747 --- /dev/null +++ b/test/asm/opcodes/65ce02-opcodes.s @@ -0,0 +1,278 @@ +.setcpu "65CE02" + + brk + ora ($05,x) + cle + see + tsb $02 + ora $02 + asl $02 + rmb0 $02 + php + ora #$01 + asl + tsy + tsb $1234 + ora $1234 + asl $1234 + bbr0 $02,*+$34 + + bpl *+$32 + ora ($06),y + ora ($07),z + lbpl *+$3133 ; bpl *+$3133 + trb $02 + ora $03,x + asl $03,x + rmb1 $02 + clc + ora $1456,y + inc + inz + trb $1234 + ora $1345,x + asl $1345,x + bbr1 $02,*+$34 + + jsr $1234 + and ($05,x) + jsr ($2345) + jsr ($2456,x) + bit $02 + and $02 + rol $02 + rmb2 $02 + plp + and #$01 + rol + tys + bit $1234 + and $1234 + rol $1234 + bbr2 $02,*+$34 + + bmi *+$32 + and ($06),y + and ($07),z + lbmi *+$3133 ; bmi *+$3133 + bit $03,x + and $03,x + rol $03,x + rmb3 $02 + sec + and $1456,y + dec + dez + bit $1345,x + and $1345,x + rol $1345,x + bbr3 $02,*+$34 + + rti + eor ($05,x) + neg + asr + asr $02 + eor $02 + lsr $02 + rmb4 $02 + pha + eor #$01 + lsr + taz + jmp $1234 + eor $1234 + lsr $1234 + bbr4 $02,*+$34 + + bvc *+$32 + eor ($06),y + eor ($07),z + lbvc *+$3133 ; bvc *+$3133 + asr $03,x + eor $03,x + lsr $03,x + rmb5 $02 + cli + eor $1456,y + phy + tab + aug + eor $1345,x + lsr $1345,x + bbr5 $02,*+$34 + + rts + adc ($05,x) + rtn #$09 + bsr *+$3133 + stz $02 + adc $02 + ror $02 + rmb6 $02 + pla + adc #$01 + ror + tza + jmp ($2345) + adc $1234 + ror $1234 + bbr6 $02,*+$34 + + bvs *+$32 + adc ($06),y + adc ($07),z + lbvs *+$3133 ; bvs *+$3133 + stz $03,x + adc $03,x + ror $03,x + rmb7 $02 + sei + adc $1456,y + ply + tba + jmp ($2456,x) + adc $1345,x + ror $1345,x + bbr7 $02,*+$34 + + bra *+$32 + sta ($05,x) + sta ($0f,s),y + sta ($0f,sp),y + lbra *+$3133 ; bra *+$3133 + sty $02 + sta $02 + stx $02 + smb0 $02 + dey + bit #$01 + txa + sty $1345,x + sty $1234 + sta $1234 + stx $1234 + bbs0 $02,*+$34 + + bcc *+$32 + sta ($06),y + sta ($07),z + lbcc *+$3133 ; bcc *+$3133 + sty $03,x + sta $03,x + stx $04,y + smb1 $02 + tya + sta $1456,y + txs + stx $1456,y + stz $1234 + sta $1345,x + stz $1345,x + bbs1 $02,*+$34 + + ldy #$01 + lda ($05,x) + ldx #$01 + ldz #$01 + ldy $02 + lda $02 + ldx $02 + smb2 $02 + tay + lda #$01 + tax + ldz $1234 + ldy $1234 + lda $1234 + ldx $1234 + bbs2 $02,*+$34 + + bcs *+$32 + lda ($06),y + lda ($07),z + lbcs *+$3133 ; bcs *+$3133 + ldy $03,x + lda $03,x + ldx $04,y + smb3 $02 + clv + lda $1456,y + tsx + ldz $1345,x + ldy $1345,x + lda $1345,x + ldx $1456,y + bbs3 $02,*+$34 + + cpy #$01 + cmp ($05,x) + cpz #$01 + dew $02 + cpy $02 + cmp $02 + dec $02 + smb4 $02 + iny + cmp #$01 + dex + asw $1234 + cpy $1234 + cmp $1234 + dec $1234 + bbs4 $02,*+$34 + + bne *+$32 + cmp ($06),y + cmp ($07),z + lbne *+$3133 ; bne *+$3133 + cpz $02 + cmp $03,x + dec $03,x + smb5 $02 + cld + cmp $1456,y + phx + phz + cpz $1234 + cmp $1345,x + dec $1345,x + bbs5 $02,*+$34 + + cpx #$01 + sbc ($05,x) + lda ($0f,s),y + lda ($0f,sp),y + inw $02 + cpx $02 + sbc $02 + inc $02 + smb6 $02 + inx + sbc #$01 + eom + nop + row $1234 + cpx $1234 + sbc $1234 + inc $1234 + bbs6 $02,*+$34 + + beq *+$32 + sbc ($06),y + sbc ($07),z + lbeq *+$3133 ; beq *+$3133 + phd #$089a + phw #$089a + sbc $03,x + inc $03,x + smb7 $02 + sed + sbc $1456,y + plx + plz + phd $1234 + phw $1234 + sbc $1345,x + inc $1345,x + bbs7 $02,*+$34 diff --git a/test/asm/opcodes/w65c02-opcodes.ref b/test/asm/opcodes/w65c02-opcodes.ref new file mode 100644 index 0000000000000000000000000000000000000000..2d44045cb59f10594d71353ad54bea406796f1be GIT binary patch literal 501 zcmV~$2LOmw0EN+vtjy2K%--8o_TGfhwPnwy`9G^jQT8lkS7yrIWbeHbWn}NYb<P_x zh#4z3ZxV;N#EVaYw-Q>3ti)ClLeeN1kURw`NkwYjPGhA_m)^=?WwhQQWU?}oC2Kaa zlY^Y(%1xfU`K<g_0jnUPP*j*A6cxpIm-i@M!YWy+v{l9`Yn3CEuRz60m8(#dYE-X5 z&04js_pLfsT|&L+1M1VD;fI(;G;U%wZPvVn)zbQi(5f|U+P0%T9q34>&UESevGs}d zsr4D*^XLn@(Y*&f=|yj%VD;(S&+2atu)ZXG6%Az2*Ms?nZyCbS@A!V$aBGA$(i%k= z9gSfu<Hj?AiTuEildQ>8ezK-o)2!))8O&rBvw!9neq|1G=P`f5LhCnck@Y*_k7zMV zSh|emtY9UpR$FV<uCvx#8?23lKiS0QEnC^fc6P9H7rXcDwf0&2tpkLE(IF0V<mfSu zbApqntiMkGea1R#{X_VdbDY0$k^i{FWv*Q1+VvaOP3x9*n{X$(%RTNtc*r9j^W>@Z N?D>nA)+_5Z;eP^Hutfj> literal 0 HcmV?d00001 diff --git a/test/asm/opcodes/w65c02-opcodes.s b/test/asm/opcodes/w65c02-opcodes.s new file mode 100644 index 000000000..0fe741518 --- /dev/null +++ b/test/asm/opcodes/w65c02-opcodes.s @@ -0,0 +1,258 @@ +.setcpu "W65C02" + + brk + ora ($12,x) + .byte $02 + .byte $03 + tsb $12 + ora $12 + asl $12 + rmb0 $12 + php + ora #$12 + asl a + .byte $0B + tsb $3456 + ora $3456 + asl $3456 + bbr0 $12,*+122 + bpl *+122 + ora ($12),y + ora ($12) + .byte $13 + trb $12 + ora $12,x + asl $12,x + rmb1 $12 + clc + ora $3456,y + inc a + .byte $1B + trb $3456 + ora $3456,x + asl $3456,x + bbr1 $12,*+122 + jsr $3456 + and ($12,x) + .byte $22 + .byte $23 + bit $12 + and $12 + rol $12 + rmb2 $12 + plp + and #$12 + rol a + .byte $2B + bit $3456 + and $3456 + rol $3456 + bbr2 $12,*+122 + bmi *+122 + and ($12),y + and ($12) + .byte $33 + bit $12,x + and $12,x + rol $12,x + rmb3 $12 + sec + and $3456,y + dec a + .byte $3B + bit $3456,x + and $3456,x + rol $3456,x + bbr3 $12,*+122 + rti + eor ($12,x) + .byte $42 + .byte $43 + .byte $44 + eor $12 + lsr $12 + rmb4 $12 + pha + eor #$12 + lsr a + .byte $4B + jmp $3456 + eor $3456 + lsr $3456 + bbr4 $12,*+122 + bvc *+122 + eor ($12),y + eor ($12) + .byte $53 + .byte $54 + eor $12,x + lsr $12,x + rmb5 $12 + cli + eor $3456,y + phy + .byte $5B + .byte $5C + eor $3456,x + lsr $3456,x + bbr5 $12,*+122 + rts + adc ($12,x) + .byte $62 + .byte $63 + stz $12 + adc $12 + ror $12 + rmb6 $12 + pla + adc #$12 + ror a + .byte $6B + jmp ($3456) + adc $3456 + ror $3456 + bbr6 $12,*+122 + bvs *+122 + adc ($12),y + adc ($12) + .byte $73 + stz $12,x + adc $12,x + ror $12,x + rmb7 $12 + sei + adc $3456,y + ply + .byte $7B + jmp ($3456,x) + adc $3456,x + ror $3456,x + bbr7 $12,*+122 + bra *+122 + sta ($12,x) + .byte $82 + .byte $83 + sty $12 + sta $12 + stx $12 + smb0 $12 + dey + bit #$12 + txa + .byte $8B + sty $3456 + sta $3456 + stx $3456 + bbs0 $12,*+122 + bcc *+122 + sta ($12),y + sta ($12) + .byte $93 + sty $12,x + sta $12,x + stx $12,y + smb1 $12 + tya + sta $3456,y + txs + .byte $9B + stz $3456 + sta $3456,x + stz $3456,x + bbs1 $12,*+122 + ldy #$12 + lda ($12,x) + ldx #$12 + .byte $A3 + ldy $12 + lda $12 + ldx $12 + smb2 $12 + tay + lda #$12 + tax + .byte $AB + ldy $3456 + lda $3456 + ldx $3456 + bbs2 $12,*+122 + bcs *+122 + lda ($12),y + lda ($12) + .byte $B3 + ldy $12,x + lda $12,x + ldx $12,y + smb3 $12 + clv + lda $3456,y + tsx + .byte $BB + ldy $3456,x + lda $3456,x + ldx $3456,y + bbs3 $12,*+122 + cpy #$12 + cmp ($12,x) + .byte $C2 + .byte $C3 + cpy $12 + cmp $12 + dec $12 + smb4 $12 + iny + cmp #$12 + dex + wai + cpy $3456 + cmp $3456 + dec $3456 + bbs4 $12,*+122 + bne *+122 + cmp ($12),y + cmp ($12) + .byte $D3 + .byte $D4 + cmp $12,x + dec $12,x + smb5 $12 + cld + cmp $3456,y + phx + stp + .byte $DC + cmp $3456,x + dec $3456,x + bbs5 $12,*+122 + cpx #$12 + sbc ($12,x) + .byte $E2 + .byte $E3 + cpx $12 + sbc $12 + inc $12 + smb6 $12 + inx + sbc #$12 + nop + .byte $EB + cpx $3456 + sbc $3456 + inc $3456 + bbs6 $12,*+122 + beq *+122 + sbc ($12),y + sbc ($12) + .byte $F3 + .byte $F4 + sbc $12,x + inc $12,x + smb7 $12 + sed + sbc $3456,y + plx + .byte $FB + .byte $FC + sbc $3456,x + inc $3456,x + bbs7 $12,*+122 From f45471156b2e857cec91baf919fbbc04e3ba8778 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sat, 28 Jun 2025 18:41:29 +0200 Subject: [PATCH 662/707] update test --- test/asm/val/ismnemonic.s | 290 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) diff --git a/test/asm/val/ismnemonic.s b/test/asm/val/ismnemonic.s index e644bdb76..2b679abbe 100644 --- a/test/asm/val/ismnemonic.s +++ b/test/asm/val/ismnemonic.s @@ -8,7 +8,9 @@ ; "6502DTV" ; "65SC02" ; "65C02" +; "W65C02" ; "4510" +; "45GS02" ; "huc6280" ; "65816" ; "sweet16" @@ -530,6 +532,141 @@ test_Ismnemonic txs test_Ismnemonic tya test_Ismnemonic wai +.setcpu "65CE02" +test_Ismnemonic adc +test_Ismnemonic and +test_Ismnemonic asl +test_Ismnemonic asr +test_Ismnemonic asw +test_Ismnemonic aug +test_Ismnemonic bbr0 +test_Ismnemonic bbr1 +test_Ismnemonic bbr2 +test_Ismnemonic bbr3 +test_Ismnemonic bbr4 +test_Ismnemonic bbr5 +test_Ismnemonic bbr6 +test_Ismnemonic bbr7 +test_Ismnemonic bbs0 +test_Ismnemonic bbs1 +test_Ismnemonic bbs2 +test_Ismnemonic bbs3 +test_Ismnemonic bbs4 +test_Ismnemonic bbs5 +test_Ismnemonic bbs6 +test_Ismnemonic bbs7 +test_Ismnemonic bcc +test_Ismnemonic bcs +test_Ismnemonic beq +test_Ismnemonic bit +test_Ismnemonic bmi +test_Ismnemonic bne +test_Ismnemonic bpl +test_Ismnemonic bra +test_Ismnemonic brk +test_Ismnemonic bsr +test_Ismnemonic bvc +test_Ismnemonic bvs +test_Ismnemonic clc +test_Ismnemonic cld +test_Ismnemonic cle +test_Ismnemonic cli +test_Ismnemonic clv +test_Ismnemonic cmp +test_Ismnemonic cpx +test_Ismnemonic cpy +test_Ismnemonic cpz +test_Ismnemonic dea +test_Ismnemonic dec +test_Ismnemonic dew +test_Ismnemonic dex +test_Ismnemonic dey +test_Ismnemonic dez +test_Ismnemonic eom +test_Ismnemonic eor +test_Ismnemonic ina +test_Ismnemonic inc +test_Ismnemonic inw +test_Ismnemonic inx +test_Ismnemonic iny +test_Ismnemonic inz +test_Ismnemonic jmp +test_Ismnemonic jsr +test_Ismnemonic lbcc +test_Ismnemonic lbcs +test_Ismnemonic lbeq +test_Ismnemonic lbmi +test_Ismnemonic lbne +test_Ismnemonic lbpl +test_Ismnemonic lbra +test_Ismnemonic lbvc +test_Ismnemonic lbvs +test_Ismnemonic lda +test_Ismnemonic ldx +test_Ismnemonic ldy +test_Ismnemonic ldz +test_Ismnemonic lsr +test_Ismnemonic neg +test_Ismnemonic nop +test_Ismnemonic ora +test_Ismnemonic pha +test_Ismnemonic phd +test_Ismnemonic php +test_Ismnemonic phw +test_Ismnemonic phx +test_Ismnemonic phy +test_Ismnemonic phz +test_Ismnemonic pla +test_Ismnemonic plp +test_Ismnemonic plx +test_Ismnemonic ply +test_Ismnemonic plz +test_Ismnemonic rmb0 +test_Ismnemonic rmb1 +test_Ismnemonic rmb2 +test_Ismnemonic rmb3 +test_Ismnemonic rmb4 +test_Ismnemonic rmb5 +test_Ismnemonic rmb6 +test_Ismnemonic rmb7 +test_Ismnemonic rol +test_Ismnemonic ror +test_Ismnemonic row +test_Ismnemonic rti +test_Ismnemonic rtn +test_Ismnemonic rts +test_Ismnemonic sbc +test_Ismnemonic sec +test_Ismnemonic sed +test_Ismnemonic see +test_Ismnemonic sei +test_Ismnemonic smb0 +test_Ismnemonic smb1 +test_Ismnemonic smb2 +test_Ismnemonic smb3 +test_Ismnemonic smb4 +test_Ismnemonic smb5 +test_Ismnemonic smb6 +test_Ismnemonic smb7 +test_Ismnemonic sta +test_Ismnemonic stx +test_Ismnemonic sty +test_Ismnemonic stz +test_Ismnemonic tab +test_Ismnemonic tax +test_Ismnemonic tay +test_Ismnemonic taz +test_Ismnemonic tba +test_Ismnemonic trb +test_Ismnemonic tsb +test_Ismnemonic tsx +test_Ismnemonic tsy +test_Ismnemonic txa +test_Ismnemonic txs +test_Ismnemonic tya +test_Ismnemonic tys +test_Ismnemonic tza + .setcpu "4510" test_Ismnemonic adc test_Ismnemonic and @@ -665,6 +802,159 @@ test_Ismnemonic tya test_Ismnemonic tys test_Ismnemonic tza +.setcpu "45GS02" +test_Ismnemonic adc +test_Ismnemonic and +test_Ismnemonic asl +test_Ismnemonic asr +test_Ismnemonic asw +test_Ismnemonic bbr0 +test_Ismnemonic bbr1 +test_Ismnemonic bbr2 +test_Ismnemonic bbr3 +test_Ismnemonic bbr4 +test_Ismnemonic bbr5 +test_Ismnemonic bbr6 +test_Ismnemonic bbr7 +test_Ismnemonic bbs0 +test_Ismnemonic bbs1 +test_Ismnemonic bbs2 +test_Ismnemonic bbs3 +test_Ismnemonic bbs4 +test_Ismnemonic bbs5 +test_Ismnemonic bbs6 +test_Ismnemonic bbs7 +test_Ismnemonic bcc +test_Ismnemonic bcs +test_Ismnemonic beq +test_Ismnemonic bit +test_Ismnemonic bmi +test_Ismnemonic bne +test_Ismnemonic bpl +test_Ismnemonic bra +test_Ismnemonic brk +test_Ismnemonic bsr +test_Ismnemonic bvc +test_Ismnemonic bvs +test_Ismnemonic clc +test_Ismnemonic cld +test_Ismnemonic cle +test_Ismnemonic cli +test_Ismnemonic clv +test_Ismnemonic cmp +test_Ismnemonic cpx +test_Ismnemonic cpy +test_Ismnemonic cpz +test_Ismnemonic dea +test_Ismnemonic dec +test_Ismnemonic dew +test_Ismnemonic dex +test_Ismnemonic dey +test_Ismnemonic dez +test_Ismnemonic eom +test_Ismnemonic eor +test_Ismnemonic ina +test_Ismnemonic inc +test_Ismnemonic inw +test_Ismnemonic inx +test_Ismnemonic iny +test_Ismnemonic inz +test_Ismnemonic jmp +test_Ismnemonic jsr +test_Ismnemonic lbcc +test_Ismnemonic lbcs +test_Ismnemonic lbeq +test_Ismnemonic lbmi +test_Ismnemonic lbne +test_Ismnemonic lbpl +test_Ismnemonic lbra +test_Ismnemonic lbvc +test_Ismnemonic lbvs +test_Ismnemonic lda +test_Ismnemonic ldx +test_Ismnemonic ldy +test_Ismnemonic ldz +test_Ismnemonic lsr +test_Ismnemonic map +test_Ismnemonic neg +test_Ismnemonic nop +test_Ismnemonic ora +test_Ismnemonic pha +test_Ismnemonic phd +test_Ismnemonic php +test_Ismnemonic phw +test_Ismnemonic phx +test_Ismnemonic phy +test_Ismnemonic phz +test_Ismnemonic pla +test_Ismnemonic plp +test_Ismnemonic plx +test_Ismnemonic ply +test_Ismnemonic plz +test_Ismnemonic rmb0 +test_Ismnemonic rmb1 +test_Ismnemonic rmb2 +test_Ismnemonic rmb3 +test_Ismnemonic rmb4 +test_Ismnemonic rmb5 +test_Ismnemonic rmb6 +test_Ismnemonic rmb7 +test_Ismnemonic rol +test_Ismnemonic ror +test_Ismnemonic row +test_Ismnemonic rti +test_Ismnemonic rtn +test_Ismnemonic rts +test_Ismnemonic sbc +test_Ismnemonic sec +test_Ismnemonic sed +test_Ismnemonic see +test_Ismnemonic sei +test_Ismnemonic smb0 +test_Ismnemonic smb1 +test_Ismnemonic smb2 +test_Ismnemonic smb3 +test_Ismnemonic smb4 +test_Ismnemonic smb5 +test_Ismnemonic smb6 +test_Ismnemonic smb7 +test_Ismnemonic sta +test_Ismnemonic stx +test_Ismnemonic sty +test_Ismnemonic stz +test_Ismnemonic tab +test_Ismnemonic tax +test_Ismnemonic tay +test_Ismnemonic taz +test_Ismnemonic tba +test_Ismnemonic trb +test_Ismnemonic tsb +test_Ismnemonic tsx +test_Ismnemonic tsy +test_Ismnemonic txa +test_Ismnemonic txs +test_Ismnemonic tya +test_Ismnemonic tys +test_Ismnemonic tza + +test_Ismnemonic adcq +test_Ismnemonic andq +test_Ismnemonic aslq +test_Ismnemonic asrq +test_Ismnemonic bitq +test_Ismnemonic cmpq +test_Ismnemonic deq +test_Ismnemonic eorq +test_Ismnemonic inq +test_Ismnemonic ldq +test_Ismnemonic lsrq +test_Ismnemonic orq +test_Ismnemonic sbcq +test_Ismnemonic stq +test_Ismnemonic rolq +test_Ismnemonic rorq + + .setcpu "HuC6280" test_Ismnemonic adc test_Ismnemonic and From 629252c562a57fbadc1ef8252b755a10bbd19e31 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 01:51:10 +0200 Subject: [PATCH 663/707] its CSG extensions, not GTE --- src/ca65/instr.c | 2 +- src/common/cpu.c | 2 +- src/common/cpu.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ca65/instr.c b/src/ca65/instr.c index ce45adfd6..d38a42843 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -1621,7 +1621,7 @@ static const InsTable* InsTabs[CPU_COUNT] = { (const InsTable*) &InsTab4510, (const InsTable*) &InsTab45GS02, (const InsTable*) &InsTabW65C02, /* CMOS with WDC extensions */ - (const InsTable*) &InsTab65CE02, /* CMOS with GTE extensions */ + (const InsTable*) &InsTab65CE02, /* CMOS with CSG extensions */ }; const InsTable* InsTab = (const InsTable*) &InsTab6502; diff --git a/src/common/cpu.c b/src/common/cpu.c index fbfe0a944..272fa4262 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -65,7 +65,7 @@ const char* CPUNames[CPU_COUNT] = { "4510", "45GS02", "W65C02", /* CMOS with WDC extensions */ - "65CE02", /* CMOS with GTE extensions */ + "65CE02", /* CMOS with CSG extensions */ }; /* Tables with CPU instruction sets diff --git a/src/common/cpu.h b/src/common/cpu.h index 0784600f7..4202ed573 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -60,7 +60,7 @@ typedef enum { CPU_4510, /* CPU of C65 */ CPU_45GS02, /* CPU of MEGA65 */ CPU_W65C02, /* CMOS with WDC extensions */ - CPU_65CE02, /* CMOS with GTE extensions */ + CPU_65CE02, /* CMOS with CSG extensions */ CPU_COUNT /* Number of different CPUs */ } cpu_t; From cf8af80dce8ec5331cc97b794da57df984f79b5d Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 01:57:28 +0200 Subject: [PATCH 664/707] add missing pseudo(s) for HUC6280, fix cpudetect for 6280 --- src/ca65/condasm.c | 30 +++++++++++++++-------- src/ca65/pseudo.c | 26 ++++++++++++++------ src/ca65/scanner.c | 2 ++ src/ca65/token.h | 2 ++ test/asm/cpudetect/cpudetect.s | 9 ++++++- test/asm/cpudetect/huc6280-cpudetect.ref | Bin 62 -> 64 bytes 6 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index 61d93ba98..ed170b6d4 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -424,6 +424,16 @@ void DoConditionals (void) CalcOverallIfCond (); break; + case TOK_IFP6280: + D = AllocIf (".IFP6280", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_HUC6280); + } + ExpectSep (); + CalcOverallIfCond (); + break; + case TOK_IFP816: D = AllocIf (".IFP816", 1); NextTok (); @@ -444,6 +454,16 @@ void DoConditionals (void) CalcOverallIfCond (); break; + case TOK_IFPCE02: + D = AllocIf (".IFPCE02", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_65CE02); + } + ExpectSep (); + CalcOverallIfCond (); + break; + case TOK_IFPDTV: D = AllocIf (".IFPDTV", 1); NextTok (); @@ -484,16 +504,6 @@ void DoConditionals (void) CalcOverallIfCond (); break; - case TOK_IFPCE02: - D = AllocIf (".IFPCE02", 1); - NextTok (); - if (IfCond) { - SetIfCond (D, GetCPU() == CPU_65CE02); - } - ExpectSep (); - CalcOverallIfCond (); - break; - case TOK_IFREF: D = AllocIf (".IFREF", 1); NextTok (); diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 604eabb92..27207c84c 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1594,14 +1594,6 @@ static void DoPCE02 (void) -static void DoP816 (void) -/* Switch to 65816 CPU */ -{ - SetCPU (CPU_65816); -} - - - static void DoP4510 (void) /* Switch to 4510 CPU */ { @@ -1618,6 +1610,22 @@ static void DoP45GS02 (void) +static void DoP6280 (void) +/* Switch to HuC6280 CPU */ +{ + SetCPU (CPU_HUC6280); +} + + + +static void DoP816 (void) +/* Switch to 65816 CPU */ +{ + SetCPU (CPU_65816); +} + + + static void DoPDTV (void) /* Switch to C64DTV CPU */ { @@ -2176,6 +2184,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccKeepToken, DoConditionals }, /* .IFP02X */ { ccKeepToken, DoConditionals }, /* .IFP4510 */ { ccKeepToken, DoConditionals }, /* .IFP45GS02 */ + { ccKeepToken, DoConditionals }, /* .IFP6280 */ { ccKeepToken, DoConditionals }, /* .IFP816 */ { ccKeepToken, DoConditionals }, /* .IFPC02 */ { ccKeepToken, DoConditionals }, /* .IFPCE02 */ @@ -2214,6 +2223,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoP02X }, /* .P02X */ { ccNone, DoP4510 }, /* .P4510 */ { ccNone, DoP45GS02 }, /* .P45GS02 */ + { ccNone, DoP6280 }, /* .P6280 */ { ccNone, DoP816 }, /* .P816 */ { ccNone, DoPageLength }, /* .PAGELEN, .PAGELENGTH */ { ccNone, DoUnexpected }, /* .PARAMCOUNT */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 1b3673150..68ff71cc7 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -224,6 +224,7 @@ struct DotKeyword { { ".IFP02X", TOK_IFP02X }, { ".IFP4510", TOK_IFP4510 }, { ".IFP45GS02", TOK_IFP45GS02 }, + { ".IFP6280", TOK_IFP6280 }, { ".IFP816", TOK_IFP816 }, { ".IFPC02", TOK_IFPC02 }, { ".IFPCE02", TOK_IFPCE02 }, @@ -267,6 +268,7 @@ struct DotKeyword { { ".P02X", TOK_P02X }, { ".P4510", TOK_P4510 }, { ".P45GS02", TOK_P45GS02 }, + { ".P6280", TOK_P6280 }, { ".P816", TOK_P816 }, { ".PAGELEN", TOK_PAGELENGTH }, { ".PAGELENGTH", TOK_PAGELENGTH }, diff --git a/src/ca65/token.h b/src/ca65/token.h index a87719794..de80fc910 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -197,6 +197,7 @@ typedef enum token_t { TOK_IFP02X, TOK_IFP4510, TOK_IFP45GS02, + TOK_IFP6280, TOK_IFP816, TOK_IFPC02, TOK_IFPCE02, @@ -235,6 +236,7 @@ typedef enum token_t { TOK_P02X, TOK_P4510, TOK_P45GS02, + TOK_P6280, TOK_P816, TOK_PAGELENGTH, TOK_PARAMCOUNT, diff --git a/test/asm/cpudetect/cpudetect.s b/test/asm/cpudetect/cpudetect.s index 9f62e3ded..86f31f7a3 100644 --- a/test/asm/cpudetect/cpudetect.s +++ b/test/asm/cpudetect/cpudetect.s @@ -45,6 +45,11 @@ sac #$00 .endif +.ifp6280 + sax + cla +.endif + .ifpm740 jsr $ff12 .endif @@ -123,8 +128,10 @@ .pc02 .pwc02 .pce02 -.p816 .p4510 .p45GS02 .pdtv +.p6280 .pm740 +.p816 +; FIXME: sweet16 diff --git a/test/asm/cpudetect/huc6280-cpudetect.ref b/test/asm/cpudetect/huc6280-cpudetect.ref index 646e0f48cfcaf4a1a191b0fe3a508d02423bf0b6..6ae287fdf5673d17e4468a6165c28db3841ee9b3 100644 GIT binary patch delta 7 OcmcC>U{Xq&U<UvOPXW^a delta 5 McmZ>;o5*Ab00c4tPyhe` From 6c6fcea71df832b1a542894d7f078516107ef182 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 02:22:18 +0200 Subject: [PATCH 665/707] docs braindump --- doc/ca65.sgml | 73 +++- doc/cc65.sgml | 38 +++ doc/cpus.sgml | 930 ++++++++++++++++++++++++++++++++++++++++---------- doc/da65.sgml | 24 +- 4 files changed, 870 insertions(+), 195 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 6886e48bd..0b62a045c 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -156,12 +156,14 @@ Here is a description of all the command line options: <item>6502X - NMOS 6502 with all undocumented instructions <item>6502DTV - the emulated CPU of the C64DTV device <item>65SC02 - first CMOS instruction set (no bit manipulation, no wai/stp) - <item>65C02 - full CMOS instruction set (has bit manipulation and wai/stp) - <item>65816 - the CPU of the SNES, and the SCPU - <item>HuC6280 - the CPU of the PC engine + <item>65C02 - CMOS with Rockwell extensions + <item>W65C02 - full CMOS instruction set (has bit manipulation and wai/stp) + <item>65CE02 - CMOS with CSG extensions <item>4510 - the CPU of the Commodore C65 <item>45GS02 - the CPU of the Commodore MEGA65 + <item>HuC6280 - the CPU of the PC engine <item>M740 - a Microcontroller by Mitsubishi + <item>65816 - the CPU of the SNES, and the SCPU <item>sweet16 - an interpreter for a pseudo 16 bit CPU </itemize> @@ -449,14 +451,20 @@ The assembler accepts <tt><ref id=".PSC02" name=".PSC02"></tt> command was given). <item>all valid 65C02 mnemonics when in <ref id="65C02-mode" name="65C02 mode"> (after the <tt><ref id=".PC02" name=".PC02"></tt> command was given). -<item>all valid 65816 mnemonics when in <ref id="65816-mode" name="65816 mode"> (after the - <tt><ref id=".P816" name=".P816"></tt> command was given). +<item>all valid W65C02 mnemonics when in <ref id="W65C02-mode" name="W65C02 mode"> (after the + <tt><ref id=".PWC02" name=".PWC02"></tt> command was given). +<item>all valid 65CE02 mnemonics when in <ref id="65CE02-mode" name="65CE02 mode"> (after the + <tt><ref id=".PCE02" name=".PCE02"></tt> command was given). <item>all valid 4510 mnemonics when in <ref id="4510-mode" name="4510 mode"> (after the <tt><ref id=".P4510" name=".P4510"></tt> command was given). <item>all valid 45GS02 mnemonics when in <ref id="45GS02-mode" name="45GS02 mode"> (after the <tt><ref id=".P45GS02" name=".P45GS02"></tt> command was given). +<item>all valid HuC6280 mnemonics when in <ref id="HUC6280-mode" name="HuC6280 mode"> (after the + <tt><ref id=".P6280" name=".P6280"></tt> command was given). <item>all valid M740 mnemonics when in <ref id="M740-mode" name="M740 mode"> (after the <tt><ref id=".PM740" name=".PM740"></tt> command was given). +<item>all valid 65816 mnemonics when in <ref id="65816-mode" name="65816 mode"> (after the + <tt><ref id=".P816" name=".P816"></tt> command was given). </itemize> for more details on the various CPUs, see <tt><htmlurl url="cpus.html" name="here"></tt>. @@ -554,6 +562,8 @@ W65C02 mode supports the Rockwell extensions, plus wai and stp. <sect2>65CE02 mode<label id="65CE02-mode"><p> +All 65CE02 instructions are accepted, plus the Rockwell extensions. + <sect2>4510 mode<label id="4510-mode"><p> @@ -3350,6 +3360,12 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH (see <tt><ref id=".P45GS02" name=".P45GS02"></tt> command). +<sect1><tt>.IFP6280</tt><label id=".IFP816"><p> + + Conditional assembly: Check if the assembler is currently in HuC6280 mode + (see <tt><ref id=".P6280" name=".P6280"></tt> command). + + <sect1><tt>.IFP816</tt><label id=".IFP816"><p> Conditional assembly: Check if the assembler is currently in 65816 mode @@ -3362,6 +3378,12 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH (see <tt><ref id=".PC02" name=".PC02"></tt> command). +<sect1><tt>.IFPCE02</tt><label id=".IFPCE02"><p> + + Conditional assembly: Check if the assembler is currently in 65CE02 mode + (see <tt><ref id=".PCE02" name=".PCE02"></tt> command). + + <sect1><tt>.IFPDTV</tt><label id=".IFPDTV"><p> Conditional assembly: Check if the assembler is currently in 6502DTV mode @@ -3403,6 +3425,12 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH <tt><ref id=".REFERTO" name=".REFERTO"></tt> +<sect1><tt>.IFPWC02</tt><label id=".IFPWC02"><p> + + Conditional assembly: Check if the assembler is currently in 65WC02 mode + (see <tt><ref id=".PWC02" name=".PWC02"></tt> command). + + <sect1><tt>.IMPORT</tt><label id=".IMPORT"><p> Import a symbol from another module. The command is followed by a comma @@ -3769,6 +3797,18 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" <tt><ref id=".P816" name=".P816"></tt>, and <tt><ref id=".P4510" name=".P4510"></tt> + +<sect1><tt>.P6280</tt><label id=".P6280"><p> + + Enable the HuC6280 instruction set. This is a superset of the 65C02 and + 6502 instruction sets. + + See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02" + name=".PSC02"></tt>, <tt><ref id=".PC02" name=".PC02"></tt>, + <tt><ref id=".P4510" name=".P4510"></tt>, and + <tt><ref id=".P45GS02" name=".P45GS02"></tt> + + <sect1><tt>.P816</tt><label id=".P816"><p> Enable the 65816 instruction set. This is a superset of the 65SC02 and @@ -3779,6 +3819,7 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" <tt><ref id=".P4510" name=".P4510"></tt>, and <tt><ref id=".P45GS02" name=".P45GS02"></tt> + <sect1><tt>.PAGELEN, .PAGELENGTH</tt><label id=".PAGELENGTH"><p> Set the page length for the listing. Must be followed by an integer @@ -3808,6 +3849,17 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" <tt><ref id=".P4510" name=".P4510"></tt>, and <tt><ref id=".P45GS02" name=".P45GS02"></tt> +<sect1><tt>.PCE02</tt><label id=".PCE02"><p> + + Enable the 65CE02 instructions set. This instruction set includes all + 6502 and extended 65CE02 instructions. + + See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02" + name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt>, + <tt><ref id=".P4510" name=".P4510"></tt>, and + <tt><ref id=".P45GS02" name=".P45GS02"></tt> + + <sect1><tt>.PDTV</tt><label id=".PDTV"><p> Enable the 6502DTV instruction set. This is a superset of the 6502 @@ -3961,6 +4013,17 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" See: <tt><ref id=".POPSEG" name=".POPSEG"></tt> +<sect1><tt>.PWC02</tt><label id=".PWC02"><p> + + Enable the W65C02 instructions set. This instruction set includes all + 6502, 65SC02, 65C02 and two extra instructions (wai and stp) + + See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PSC02" + name=".PSC02"></tt>, <tt><ref id=".P816" name=".P816"></tt>, + <tt><ref id=".P4510" name=".P4510"></tt>, and + <tt><ref id=".P45GS02" name=".P45GS02"></tt> + + <sect1><tt>.REFERTO, .REFTO</tt><label id=".REFERTO"><p> Mark a symbol as referenced. diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 166c0fad4..734e4eaf4 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -1212,6 +1212,14 @@ The compiler defines several macros at startup: given, but can be changed using the <tt/<ref id="option--cpu" name="--cpu">/ command line option. + <tag><tt>__CPU_4510__</tt></tag> + + This macro is defined if the code is compiled for a 4510 CPU. + + <tag><tt>__CPU_45GS02__</tt></tag> + + This macro is defined if the code is compiled for a 45GS02 CPU. + <tag><tt>__CPU_6502__</tt></tag> This macro is defined if the code is compiled for a 6502 CPU. @@ -1233,6 +1241,10 @@ The compiler defines several macros at startup: This macro is defined if the code is compiled for a 65C02 CPU. + <tag><tt>__CPU_65CE02__</tt></tag> + + This macro is defined if the code is compiled for a 65CE02 CPU. + <tag><tt>__CPU_65816__</tt></tag> This macro is defined if the code is compiled for a 65816 CPU. @@ -1241,6 +1253,14 @@ The compiler defines several macros at startup: This macro is defined if the code is compiled for a HUC6280 CPU. + <tag><tt>__CPU_M740__</tt></tag> + + This macro is defined if the code is compiled for a M740 CPU. + + <tag><tt>__CPU_W65C02__</tt></tag> + + This macro is defined if the code is compiled for a W65C02 CPU. + <tag><tt>__CPU_ISET_6502__</tt></tag> This macro expands to a numeric constant that can be used to check the @@ -1271,6 +1291,12 @@ The compiler defines several macros at startup: <tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set of the 65C02 CPU. + <tag><tt>__CPU_ISET_65CE02__</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 65CE02 CPU. + <tag><tt>__CPU_ISET_65816__</tt></tag> This macro expands to a numeric constant that can be used to check the @@ -1283,6 +1309,18 @@ The compiler defines several macros at startup: <tt/<ref id="macro-CPU" name="__CPU__">/ macro for the instruction set of the HUC6280 CPU. + <tag><tt>__CPU_ISET_M740__</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 M740 CPU. + + <tag><tt>__CPU_ISET_W65C02__</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 W65C02 CPU. + <tag><tt>__CX16__</tt></tag> This macro is defined if the target is the Commander X16 (-t cx16). diff --git a/doc/cpus.sgml b/doc/cpus.sgml index 59eb940c2..7564a543f 100644 --- a/doc/cpus.sgml +++ b/doc/cpus.sgml @@ -16,33 +16,189 @@ An Overview on all supported CPUs <sect>Overview<p> - -<sect1>Supported CPUs<p> - <itemize> <item><ref id="6502-mode" name="6502"> - NMOS 6502 (all legal instructions) <item><ref id="6502X-mode" name="6502X"> - NMOS 6502 with all undocumented instructions - <item><ref id="DTV-mode" name="6502DTV"> - the emulated CPU of the C64DTV device - <item><ref id="65SC02-mode" name="65SC02"> - first CMOS instruction set (no bit manipulation) - <item><ref id="65C02-mode" name="65C02"> - full CMOS instruction set (has bit manipulation) + <item><ref id="DTV-mode" name="6502DTV"> - the CPU of the C64 DTV device + <item><ref id="65SC02-mode" name="65SC02"> - original CMOS + <item><ref id="65C02-mode" name="65C02"> - CMOS with Rockwell extensions + <item><ref id="65CE02-mode" name="65CE02"> - CMOS with CSG extensions <item><ref id="W65C02-mode" name="W65C02"> - CMOS with WDC extensions - <item><ref id="65CE02-mode" name="65CE02"> - CMOS with GTE extensions - <item><ref id="65816-mode" name="65816"> - the CPU of the SNES, and the SCPU - <item><ref id="HUC6280-mode" name="HuC6280"> - the CPU of the PC engine <item><ref id="4510-mode" name="4510"> - the CPU of the Commodore C65 <item><ref id="45GS02-mode" name="45GS02"> - the CPU of the Commodore MEGA65 + <item><ref id="HUC6280-mode" name="HuC6280"> - the CPU of the PC engine <item><ref id="M740-mode" name="M740"> - a Microcontroller by Mitsubishi + <item><ref id="65816-mode" name="65816"> - the CPU of the SNES, and the SCPU <item><ref id="sweet16-mode" name="Sweet16"> - an interpreter for a pseudo 16 bit CPU </itemize> +<sect>NMOS branch<p> -<sect2>6502 mode<label id="6502-mode"><p> +<sect1>6502<label id="6502-mode"><p> -The default (no CPU given on the command line or in the <tt/GLOBAL/ section of -the info file) is the 6502 CPU. The disassembler knows all "official" opcodes -for this CPU. Invalid opcodes are translated into <tt/.byte/ commands. +The original NMOS 6502 CPU. -<sect2>6502X mode<label id="6502X-mode"><p> +For Example: MOS MCS6502 Rev. D, Rockwell R6502, Synertek SY6502, UMC UM6502 + +(56 instructions, 151 opcodes) + +<tscreen><verb> +$00 brk +$01 ora (zp,x) +$05 ora zp +$06 asl zp +$08 php +$09 ora #imm +$0a asl a +$0d ora addr +$0e asl addr +$10 bpl rel80 +$11 ora (zp),y +$15 ora zp,x +$16 asl zp,x +$18 clc +$19 ora addr,y +$1d ora addr,x +$1e asl addr,x +$20 jsr addr +$21 and (zp,x) +$24 bit zp +$25 and zp +$26 rol zp +$28 plp +$29 and #imm +$2a rol a +$2c bit addr +$2d and addr +$2e rol addr +$30 bmi rel8 +$31 and (zp),y +$35 and zp,x +$36 rol zp,x +$38 sec +$39 and addr,y +$3d and addr,x +$3e rol addr,x +$40 rti +$41 eor (zp,x) +$45 eor zp +$46 lsr zp +$48 pha +$49 eor #imm +$4a lsr a +$4c jmp addr +$4d eor addr +$4e lsr addr +$50 bvc rel8 +$51 eor (zp),y +$55 eor zp,x +$56 lsr zp,x +$58 cli +$59 eor addr,y +$5d eor addr,x +$5e lsr addr,x +$60 rts +$61 adc (zp,x) +$65 adc zp +$66 ror zp +$68 pla +$69 adc #imm +$6a ror a +$6c jmp (addr) +$6d adc addr +$6e ror addr +$70 bvs rel8 +$71 adc (zp),y +$75 adc zp,x +$76 ror zp,x +$78 sei +$79 adc addr,y +$7d adc addr,x +$7e ror addr,x +$81 sta (zp,x) +$84 sty zp +$85 sta zp +$86 stx zp +$88 dey +$8a txa +$8c sty addr +$8d sta addr +$8e stx addr +$90 bcc rel8 +$91 sta (zp),y +$94 sty zp,x +$95 sta zp,x +$96 stx zp,y +$98 tya +$99 sta addr,y +$9a txs +$9d sta addr,x +$a0 ldy #imm +$a1 lda (zp,x) +$a2 ldx #imm +$a4 ldy zp +$a5 lda zp +$a6 ldx zp +$a8 tay +$a9 lda #imm +$aa tax +$ac ldy addr +$ad lda addr +$ae ldx addr +$b0 bcs rel8 +$b1 lda (zp),y +$b4 ldy zp,x +$b5 lda zp,x +$b6 ldx zp,y +$b8 clv +$b9 lda addr,y +$ba tsx +$bc ldy addr,x +$bd lda addr,x +$be ldx addr,y +$c0 cpy #imm +$c1 cmp (zp,x) +$c4 cpy zp +$c5 cmp zp +$c6 dec zp +$c8 iny +$c9 cmp #imm +$ca dex +$cc cpy addr +$cd cmp addr +$ce dec addr +$d0 bne rel8 +$d1 cmp (zp),y +$d5 cmp zp,x +$d6 dec zp,x +$d8 cld +$d9 cmp addr,y +$dd cmp addr,x +$de dec addr,x +$e0 cpx #imm +$e1 sbc (zp,x) +$e4 cpx zp +$e5 sbc zp +$e6 inc zp +$e8 inx +$e9 sbc #imm +$ea nop +$ec cpx addr +$ed sbc addr +$ee inc addr +$f0 beq rel81 +$f1 sbc (zp),y +$f5 sbc zp,x +$f6 inc zp,x +$f8 sed +$f9 sbc addr,y +$fd sbc addr,x +$fe inc addr,x +</verb></tscreen> + + + +<sect1>6502X<label id="6502X-mode"><p> 6502X mode is an extension to the normal 6502 mode. In this mode, several mnemonics for undocumented instructions of the NMOS 6502 CPUs are accepted. @@ -50,61 +206,239 @@ mnemonics for undocumented instructions of the NMOS 6502 CPUs are accepted. Note: Since these instructions are undocumented, there are no official mnemonics for them. +(20 new instructions, 105 new opcodes, 76 instructions/256 opcodes total) + <itemize> -<item><tt>ALR: A:=(A and #{imm})/2;</tt> -<item><tt>ANC: A:= A and #{imm};</tt> Generates opcode $0B. -<item><tt>ANE: A:= (A or CONST) and X and #{imm};</tt> -<item><tt>ARR: A:=(A and #{imm})/2;</tt> -<item><tt>AXS: X:=A and X-#{imm};</tt> -<item><tt>DCP: {addr}:={addr}-1; A-{addr};</tt> -<item><tt>ISC: {addr}:={addr}+1; A:=A-{addr};</tt> +<item><tt>ALR: A:=(A and #imm)/2;</tt> +<item><tt>ANC: A:= A and #imm;</tt> Generates opcode $0B. +<item><tt>ANE: A:= (A or CONST) and X and #imm;</tt> +<item><tt>ARR: A:=(A and #imm)/2;</tt> +<item><tt>AXS: X:=A and X-#imm;</tt> +<item><tt>DCP: addr:=addr-1; A-addr;</tt> +<item><tt>ISC: addr:=addr+1; A:=A-addr;</tt> <item><tt>JAM:</tt> -<item><tt>LAS: A,X,S:={addr} and S;</tt> -<item><tt>LAX: A,X:={addr};</tt> -<item><tt>NOP: #{imm}; zp; zp,x; abs; abs,x</tt> -<item><tt>RLA: {addr}:={addr}rol; A:=A and {addr};</tt> -<item><tt>RRA: {addr}:={addr}ror; A:=A adc {addr};</tt> -<item><tt>SAX: {addr}:=A and X;</tt> -<item><tt>SHA: {addr}:=A and X and {addr hi +1};</tt> -<item><tt>SHX: {addr}:=X and {addr hi +1};</tt> -<item><tt>SHY: {addr}:=Y and {addr hi +1};</tt> -<item><tt>SLO: {addr}:={addr}*2; A:=A or {addr};</tt> -<item><tt>SRE: {addr}:={addr}/2; A:=A xor {addr};</tt> -<item><tt>TAS: {addr}:=A and X and {addr hi +1}; SP:=A and X;</tt> +<item><tt>LAS: A,X,S:=addr and S;</tt> +<item><tt>LAX: A,X:=addr;</tt> +<item><tt>NOP: #imm; zp; zp,x; abs; abs,x</tt> +<item><tt>RLA: addr:=addrrol; A:=A and addr;</tt> +<item><tt>RRA: addr:=addrror; A:=A adc addr;</tt> +<item><tt>SAX: addr:=A and X;</tt> +<item><tt>SHA: addr:=A and X and {addr hi +1};</tt> +<item><tt>SHX: addr:=X and {addr hi +1};</tt> +<item><tt>SHY: addr:=Y and {addr hi +1};</tt> +<item><tt>SLO: addr:=addr*2; A:=A or addr;</tt> +<item><tt>SRE: addr:=addr/2; A:=A xor addr;</tt> +<item><tt>TAS: addr:=A and X and {addr hi +1}; SP:=A and X;</tt> </itemize> - -<sect2>DTV mode<label id="DTV-mode"><p> - -The C64DTV CPU is based on the 6510, but adds some instructions, and does not -support all undocumented instructions. - -<itemize> -<item><tt>bra {rel}</tt> Generates opcode $12. -<item><tt>sac #{imm}</tt> Generates opcode $32. -<item><tt>sir #{imm}</tt> Generates opcode $42. -</itemize> - -Supported undocumented instructions: - -<itemize> -<item><tt>ALR: A:=(A and #{imm})/2;</tt> -<item><tt>ANC: A:=A and #{imm};</tt> Generates opcode $0B. -<item><tt>ARR: A:=(A and #{imm})/2;</tt> -<item><tt>AXS: X:=A and X-#{imm};</tt> -<item><tt>LAS: A,X,S:={addr} and S;</tt> -<item><tt>LAX: A,X:={addr};</tt> -<item><tt>NOP: #{imm}; zp; zp,x; abs; abs,x</tt> -<item><tt>RLA: {addr}:={addr}rol; A:=A and {addr};</tt> -<item><tt>RRA: {addr}:={addr}ror; A:=A adc {addr};</tt> -<item><tt>SHX: {addr}:=X and {addr hi +1};</tt> -<item><tt>SHY: {addr}:=y and {addr hi +1};</tt> -</itemize> +<tscreen><verb> +$02 jam +$03 slo (zp,x) +$04 nop zp +$07 slo zp +$0b anc #imm +$0c nop addr +$0f slo addr +$12 jam +$13 slo (zp),y +$14 nop zp,x +$17 slo zp,y +$1a nop +$1b slo addr,y +$1c nop addr,x +$1f slo addr,x +$22 jam +$23 rla (zp,x) +$27 rla zp +$2b anc #imm +$2f rla addr +$32 jam +$33 rla (zp),y +$34 nop zp,x +$37 rla zp,y +$3a nop +$3b rla addr,y +$3c nop addr,x +$3f rla addr,x +$42 jam +$43 sre (zp,x) +$44 nop zp +$47 sre zp +$4b alr #imm +$4f sre addr +$52 jam +$53 sre (zp),y +$54 nop zp,x +$57 sre zp,y +$5a nop +$5b sre addr,y +$5c nop addr,x +$5f sre addr,x +$62 jam +$63 rra (zp,x) +$64 nop zp +$67 rra zp +$6b arr #imm +$6f rra addr +$72 jam +$73 rra (zp),y +$74 nop zp,x +$77 rra zp,y +$7a nop +$7b rra addr,y +$7c nop addr,x +$7f rra addr,x +$80 nop #imm +$82 nop #imm +$83 sax (zp,x) +$87 sax zp +$89 nop #imm +$8b ane #imm +$8f sax addr +$92 jam +$93 sha (zp),y +$97 sax zp,y +$9b tas addr,y +$9c shy addr,x +$9e shx addr,y +$9f sha addr,y +$a3 lax (zp,x) +$a7 lax zp +$ab lax #imm +$af lax addr +$b2 jam +$b3 lax (zp),y +$b7 lax zp,y +$bb las addr,y +$bf lax addr,y +$c2 nop #imm +$c3 dcp (zp,x) +$c7 dcp zp +$cb axs #imm +$cf dcp addr +$d2 jam +$d3 dcp (zp),y +$d4 nop zp,x +$d7 dcp zp,y +$da nop +$db dcp addr,y +$dc nop addr,x +$df dcp addr,x +$e2 nop #imm +$e3 isc (zp,x) +$e7 isc zp +$eb sbc #imm +$ef isc addr +$f2 jam +$f3 isc (zp),y +$f4 nop zp,x +$f7 isc zp,y +$fa nop +$fb isc addr,y +$fc nop addr,x +$ff isc addr,x +</verb></tscreen> -<sect2>65SC02 (Original CMOS)<label id="65SC02-mode"><p> -The first CMOS instruction set, without bit manipulation or wai/stp. +<sect1>6502DTV<label id="DTV-mode"><p> + +The CPU of the C64 DTV is based on the 6510. It adds some instructions, and does +not support all undocumented 6510 instructions. + +(3+10 new instructions, 3+56 new opcodes, 69 instructions/210 opcodes total) + +Opcodes added over 6502 (these are JAM on 6502): + +<tscreen><verb> +$12 bra rel8 +$32 sac #imm +$42 sir #imm +</verb></tscreen> + +Supported undocumented 6510 instructions (nop, anc, rla, lax, las, alr, arr, +rra, shy, shx, axs, sbc): + +<tscreen><verb> +$04 nop zp +$0b anc #imm +$0c nop addr +$14 nop zp,x +$1a nop +$1c nop addr,x +$23 rla (zp,x) +$27 rla zp +$2b anc #imm +$2f rla addr +$33 rla (zp),y +$34 nop zp,x +$37 rla zp,y +$3a nop +$3b rla addr,y +$3c nop addr,x +$3f rla addr,x +$44 nop zp +$4b alr #imm +$54 nop zp,x +$5a nop +$5c nop addr,x +$63 rra (zp,x) +$64 nop zp +$67 rra zp +$6b arr #imm +$6f rra addr +$73 rra (zp),y +$74 nop zp,x +$77 rra zp,y +$7a nop +$7b rra addr,y +$7c nop addr,x +$7f rra addr,x +$80 nop #imm +$82 nop #imm +$89 nop #imm +$9c shy addr,x +$9e shx addr,y +$a3 lax (zp,x) +$a7 lax zp +$ab lax #imm +$af lax addr +$b3 lax (zp),y +$b7 lax zp,y +$bb las addr,y +$bf lax addr,y +$c2 nop #imm +$cb axs #imm +$d4 nop zp,x +$da nop +$dc nop addr,x +$e2 nop #imm +$eb sbc #imm +$f4 nop zp,x +$fa nop +$fc nop addr,x +</verb></tscreen> + + +<sect>CMOS branch<p> + +The original CMOS version was apparently developed already back in the Commodore +days, but never saw the light of day. It was then licensed by (now) WDC to +different other vendors. Unfortunately some of those named their chips "65C02" +(not SC), which causes a lot of confusion now. So keep that in mind: some chips +that are named "65C02" will only support the original 65SC02 instruction set. + + +<sect1>65SC02 (Original CMOS)<label id="65SC02-mode"><p> + +The first CMOS instruction set, without bit manipulation, nor wai/stp. It adds +8 new instructions (phx, phy, plx, ply, bra, stz, tsb, trb) and two new address +modes (zeropage-indirect, absolute-x-indexed-indirect) to the original (legal) +6502 instructions. + +For example: Synertek SY65C02, GTE G65SC02, CMD G65SC02, NCR 65C02 + +(8 new instructions, 27 new opcodes, 64 instructions/178 opcodes total) <tscreen><verb> $04 tsb zp @@ -137,32 +471,81 @@ $fa plx </verb></tscreen> -<sect2>65C02 (CMOS with Rockwell extensions)<label id="65C02-mode"><p> -The 65C02 understands the same opcodes as the 65SC02, plus 16 additional bit -manipulation and bit test-and-branch commands. +<sect1>65C02 (CMOS with Rockwell extensions)<label id="65C02-mode"><p> -The R65C02 adds bit manipulation instructions: +The Rockwell extensions add additional bit manipulation and bit test-and-branch +commands to the original 65SC02 instruction set. + +For Example: Rockwell R65C02, Ricoh RP65C02, NCR 65CX02 + +(4 new instructions, 32 new opcodes, 68 instructions/210 opcodes total) <tscreen><verb> -smbB zp set bit in zp location -rmbB zp reset bit in zp location -bbsB zp, rel8 branch if bit is set in zp location -bbrB zp, rel8 branch if bit is reset in zp location +$07 rmb0 zp clear bit in zp location +$0f bbr0 zp, rel8 branch if bit is not set in zp location +$17 rmb1 zp +$1f bbr1 zp, rel8 +$27 rmb2 zp +$2f bbr2 zp, rel8 +$37 rmb3 zp +$3f bbr3 zp, rel8 +$47 rmb4 zp +$4f bbr4 zp, rel8 +$57 rmb5 zp +$5f bbr5 zp, rel8 +$67 rmb6 zp +$6f bbr6 zp, rel8 +$77 rmb7 zp +$7f bbr7 zp, rel8 +$87 smb0 zp set bit in zp location +$8f bbs0 zp, rel8 branch if bit is set in zp location +$97 smb1 zp +$9f bbs1 zp, rel8 +$a7 smb2 zp +$af bbs2 zp, rel8 +$b7 smb3 zp +$bf bbs3 zp, rel8 +$c7 smb4 zp +$cf bbs4 zp, rel8 +$d7 smb5 zp +$df bbs5 zp, rel8 +$e7 smb6 zp +$ef bbs6 zp, rel8 +$f7 smb7 zp +$ff bbs7 zp, rel8 </verb></tscreen> +All "illegal" opcodes perform NOP on this CPU. -<sect2>W65C02 (CMOS with WDC extensions)<label id="W65C02-mode"><p> -This mode also supports wai/stp. + +<sect1>W65C02 (CMOS with WDC extensions)<label id="W65C02-mode"><p> + +For their W65C02S WDC took the Rockwell extensions, and added two extra +instructions (which they also added to the 65C816/65C802) + +(2 new instructions, 2 new opcodes, 70 instructions/212 opcodes total) <tscreen><verb> $cb wai wait for interrupt $db stp wait for reset </verb></tscreen> +All "illegal" opcodes perform NOP on this CPU. -<sect2>65CE02 (CMOS with GTE extensions)<label id="65CE02-mode"><p> + + +<sect1>65CE02 (CMOS with CSG extensions)<label id="65CE02-mode"><p> + +CSG took the Rockwell extensions and developed them further. Notable additions +are long relative branches/jumps, and finally a real z register. Note that the +two opcodes used by the WDC extensions have been repurposed for something else, +so the 65CE02 is not 100% compatible with the W65C02. + +For Example: CSG 65CE02 (used on the Amiga A2232 Serial Card) + +(34 new instructions, 46 new opcodes, 102 instructions/256 opcodes total) <tscreen><verb> $02 cle clear stack extend disable @@ -225,18 +608,48 @@ $fb plz pull Z $fc phw abs16 </verb></tscreen> +One notable change is that some instructions of the original CMOS instruction set +were changed from "zeropage indirect" addressing to "zeropage indirect, z indexed". +This could be done, because the z register is initially guaranteed to be zero, +making the CPU binary compatible with older CMOS variants. -<sect2>4510 mode<label id="4510-mode"><p> +<tscreen><verb> +$12 ora (zp) -> ora (zp), z +$32 and (zp) -> and (zp), z +$52 eor (zp) -> eor (zp), z +$72 adc (zp) -> adc (zp), z +$92 sta (zp) -> sta (zp), z +$b2 lda (zp) -> cmp (zp), z +$d2 cmp (zp) -> lda (zp), z +$f2 sbc (zp) -> sbc (zp), z +</verb></tscreen> + +Additional to that, the meaning of the following instruction changes from "store +zero" to "store z register". Again, this makes the CPU binary compatible with +older CMOS variants + +<tscreen><verb> +$64 stz zp +$74 stz zp, x +$9c stz abs16 +$9e stz abs16, x +</verb></tscreen> + +The other 65SC02 instructions (phx, phy, plx, ply, tsb, trb, bra) are unchanged. + + + +<sect1>4510<label id="4510-mode"><p> The 4510 is a microcontroller that is the core of the Commodore C65 aka C64DX. It contains among other functions a slightly modified 65CE02/4502 CPU, to allow address mapping for 20 bits of address space (1 megabyte addressable area). -The 4510 mode supports the complete (legal) 65CE02 instruction set, but changes +The 4510 supports the complete 65CE02 instruction set, but changes the 4-Byte NOP into the "map" instruction: <tscreen><verb> -$5c map "4-byte NOP reserved for future expansion" on 65CE02 +$5c map </verb></tscreen> For more information about the Commodore C65/C64DX and the 4510 CPU, see @@ -244,154 +657,315 @@ For more information about the Commodore C65/C64DX and the 4510 CPU, see <url url="https://en.wikipedia.org/wiki/Commodore_65" name="Wikipedia">. -<sect2>45GS02 mode<label id="45GS02-mode"><p> + +<sect1>45GS02<label id="45GS02-mode"><p> The 45GS02 is a microcontroller that is the core of the MEGA65. It is an extension of the 4510 CPU and adds 32-bit addressing and a 32-bit pseudo register Q that is comprised of the four registers A, X, Y, and Z. <tscreen><verb> -$42 $42 $05 orq $12 -$42 $42 $06 aslq $12 -$42 $42 $0a aslq -$42 $42 $0d orq $1234 -$42 $42 $0e aslq $1234 -$42 $42 $12 orq ($12) -$42 $42 $16 aslq $12,x -$42 $42 $1a inq -$42 $42 $1e aslq $1234,x -$42 $42 $24 bitq $12 -$42 $42 $25 andq $12 -$42 $42 $26 rolq $12 -$42 $42 $2a rolq -$42 $42 $2c bitq $1234 -$42 $42 $2d andq $1234 -$42 $42 $2e rolq $1234 -$42 $42 $32 andq ($12) -$42 $42 $36 rolq $12, x -$42 $42 $3a deq -$42 $42 $3e rolq $1234, x -$42 $42 $43 asrq -$42 $42 $44 asrq $12 -$42 $42 $45 eorq $12 -$42 $42 $46 lsrq $12 -$42 $42 $4a lsrq -$42 $42 $4d eorq $1234 -$42 $42 $4e lsrq $1234 -$42 $42 $52 eorq ($12) -$42 $42 $54 asrq $12, x -$42 $42 $56 lsrq $12, x -$42 $42 $5e lsrq $1234, x -$42 $42 $65 adcq $12 -$42 $42 $66 rorq $12 -$42 $42 $6a rorq -$42 $42 $6d adcq $1234 -$42 $42 $6e rorq $1234 -$42 $42 $72 adcq ($12) -$42 $42 $76 rorq $12, x -$42 $42 $7e rorq $1234, x -$42 $42 $85 stq $12 -$42 $42 $8d stq $1234 -$42 $42 $92 stq ($12) -$42 $42 $a5 ldq $12 -$42 $42 $ad ldq $1234 -$42 $42 $b2 ldq ($12), z -$42 $42 $c5 cmpq $12 -$42 $42 $c6 deq $12 -$42 $42 $cd cmpq $1234 -$42 $42 $ce deq $1234 -$42 $42 $d2 cmpq ($12) -$42 $42 $d6 deq $12, x -$42 $42 $de deq $1234, x -$42 $42 $e5 sbcq $12 -$42 $42 $e6 inq $12 -$42 $42 $ed sbcq $1234 -$42 $42 $ee inq $1234 -$42 $42 $f2 sbcq ($12) -$42 $42 $f6 inq $12, x -$42 $42 $fe inq $1234, x +$42 $42 $05 orq zp +$42 $42 $06 aslq zp +$42 $42 $0a aslq +$42 $42 $0d orq addr +$42 $42 $0e aslq addr +$42 $42 $12 orq (zp) +$42 $42 $16 aslq zp,x +$42 $42 $1a inq +$42 $42 $1e aslq addr,x +$42 $42 $24 bitq zp +$42 $42 $25 andq zp +$42 $42 $26 rolq zp +$42 $42 $2a rolq +$42 $42 $2c bitq addr +$42 $42 $2d andq addr +$42 $42 $2e rolq addr +$42 $42 $32 andq (zp) +$42 $42 $36 rolq zp, x +$42 $42 $3a deq +$42 $42 $3e rolq addr, x +$42 $42 $43 asrq +$42 $42 $44 asrq zp +$42 $42 $45 eorq zp +$42 $42 $46 lsrq zp +$42 $42 $4a lsrq +$42 $42 $4d eorq addr +$42 $42 $4e lsrq addr +$42 $42 $52 eorq (zp) +$42 $42 $54 asrq zp, x +$42 $42 $56 lsrq zp, x +$42 $42 $5e lsrq addr, x +$42 $42 $65 adcq zp +$42 $42 $66 rorq zp +$42 $42 $6a rorq +$42 $42 $6d adcq addr +$42 $42 $6e rorq addr +$42 $42 $72 adcq (zp) +$42 $42 $76 rorq zp, x +$42 $42 $7e rorq addr, x +$42 $42 $85 stq zp +$42 $42 $8d stq addr +$42 $42 $92 stq (zp) +$42 $42 $a5 ldq zp +$42 $42 $ad ldq addr +$42 $42 $b2 ldq (zp), z +$42 $42 $c5 cmpq zp +$42 $42 $c6 deq zp +$42 $42 $cd cmpq addr +$42 $42 $ce deq addr +$42 $42 $d2 cmpq (zp) +$42 $42 $d6 deq zp, x +$42 $42 $de deq addr, x +$42 $42 $e5 sbcq zp +$42 $42 $e6 inq zp +$42 $42 $ed sbcq addr +$42 $42 $ee inq addr +$42 $42 $f2 sbcq (zp) +$42 $42 $f6 inq zp, x +$42 $42 $fe inq addr, x -$ea $12 ora [$12], z -$ea $32 and [$12], z -$ea $52 eor [$12], z -$ea $72 adc [$12], z -$ea $92 sta [$12], z -$ea $b2 lda [$12], z -$ea $d2 cmp [$12], z -$ea $f2 sbc [$12], z +$ea $12 ora [zp], z +$ea $32 and [zp], z +$ea $52 eor [zp], z +$ea $72 adc [zp], z +$ea $92 sta [zp], z +$ea $b2 lda [zp], z +$ea $d2 cmp [zp], z +$ea $f2 sbc [zp], z -$42 $42 $ea $12 orq [$12] -$42 $42 $ea $32 andq [$12] -$42 $42 $ea $52 eorq [$12] -$42 $42 $ea $72 adcq [$12] -$42 $42 $ea $92 stq [$12] -$42 $42 $ea $b2 ldq [$12], z -$42 $42 $ea $d2 cmpq [$12] -$42 $42 $ea $f2 sbcq [$12] +$42 $42 $ea $12 orq [zp] +$42 $42 $ea $32 andq [zp] +$42 $42 $ea $52 eorq [zp] +$42 $42 $ea $72 adcq [zp] +$42 $42 $ea $92 stq [zp] +$42 $42 $ea $b2 ldq [zp], z +$42 $42 $ea $d2 cmpq [zp] +$42 $42 $ea $f2 sbcq [zp] </verb></tscreen> -<sect2>HUC6280 mode<label id="HUC6280-mode"><p> +<sect1>HUC6280<label id="HUC6280-mode"><p> -The HUC6280 is a superset of 65C02. It adds some other instructions: +The HUC6280 is a superset of 65C02. It implements the original CMOS instructions +with Rockwell extensions, plus some other instructions: <tscreen><verb> $02 sxy -$03 st0 #{imm} -$13 st1 #{imm} +$03 st0 #imm +$13 st1 #imm $22 sax -$23 st2 #{imm} +$23 st2 #imm $42 say -$43 tma #{imm} -$44 bsr {rel} -$53 tam #{imm} +$43 tma #imm +$44 bsr rel8 +$53 tam #imm $54 csl $62 cla -$73 tii {addr}, {addr}, {addr} +$73 tii addr, addr, addr $82 clx -$83 tst #{imm}, {zp} +$83 tst #imm, zp $82 clx -$83 tst #{imm}, {zp} -$93 tst #{imm}, {addr} -$a3 tst #{imm}, {zp}, x -$b3 tst #{imm}, {addr}, x +$83 tst #imm, zp +$93 tst #imm, addr +$a3 tst #imm, zp, x +$b3 tst #imm, addr, x $c2 cly -$c3 tdd {addr}, {addr}, {addr} -$d3 tin {addr}, {addr}, {addr} +$c3 tdd addr, addr, addr +$d3 tin addr, addr, addr $d4 csh -$e3 tia {addr}, {addr}, {addr} -$f3 tai {addr}, {addr}, {addr} +$e3 tia addr, addr, addr +$f3 tai addr, addr, addr $f4 set </verb></tscreen> -<sect2>M740 mode<label id="M740-mode"><p> +<sect1>M740<label id="M740-mode"><p> The M740 is a microcontroller by Mitsubishi, which was marketed for embedded -devices in the mid 80s. It is a superset of 6502, and a subset of 65SC02, plus -some new instructions. +devices in the mid 80s. It is a superset of 6502, the added CMOS instructions +seem to be completely custom however: + +<tscreen><verb> +$02 jsr (zp) +$03 bbs0 a, rel8 +$07 bbs0 zp, rel8 +$0b seb0 a +$0f seb0 zp +$12 clt +$13 bbc0 a, rel8 +$17 bbc0 zp, rel8 +$1a inc a +$1b clb0 a +$1f clb0 zp +$22 jsr $ff12 +$23 bbs1 a, rel8 +$27 bbs1 zp, rel8 +$2b seb1 a +$2f seb1 zp +$32 set +$33 bbc1 a, rel8 +$37 bbc1 zp, rel8 +$3a dec a +$3b clb1 a +$3c ldm zp, #imm +$3f clb1 zp +$42 stp +$43 bbs2 a, rel8 +$44 com zp +$47 bbs2 zp, rel8 +$4b seb2 a +$4f seb2 zp +$53 bbc2 a, rel8 +$57 bbc2 zp, rel8 +$5b clb2 a +$5f clb2 zp +$63 bbs3 a, rel8 +$64 tst zp +$67 bbs3 zp, rel8 +$6b seb3 a +$6f seb3 zp +$73 bbc3 a, rel8 +$77 bbc3 zp, rel8 +$7b clb3 a +$7f clb3 zp +$80 bra rel8 +$82 rrf zp +$83 bbs4 a, rel8 +$87 bbs4 zp, rel8 +$8b seb4 a +$8f seb4 zp +$93 bbc4 a, rel8 +$97 bbc4 zp, rel8 +$9b clb4 a +$9f clb4 zp +$a3 bbs5 a, rel8 +$a7 bbs5 zp, rel8 +$ab seb5 a +$af seb5 zp +$b2 lda (zp) +$b3 bbc5 a, rel8 +$b7 bbc5 zp, rel8 +$bb clb5 a +$bf clb5 zp +$c2 slw +$c3 bbs6 a, rel8 +$c7 bbs6 zp, rel8 +$cb seb6 a +$cf seb6 zp +$d3 bbc6 a, rel8 +$d7 bbc6 zp, rel8 +$db clb6 a +$df clb6 zp +$e2 fst +$e3 bbs7 a, rel8 +$e7 bbs7 zp, rel8 +$eb seb7 a +$ef seb7 zp +$f3 bbc7 a, rel8 +$f7 bbc7 zp, rel8 +$fb clb7 a +$ff clb7 zp +</verb></tscreen> + +Four instructions are the same on 65SC02: + +<tscreen><verb> +$1a inc a +$3a dec a +$80 bra rel8 +$b2 lda (zp) +</verb></tscreen> + +These four instructions are different from 65SC02: + +<tscreen><verb> +$12 ora (zp) -> clt +$32 and (zp) -> set +$3c bit addr,x -> ldm zp, #imm +$64 stz zp -> tst zp +</verb></tscreen> + +The following 65SC02 instructions are not implemented: + +<tscreen><verb> +$04 tsb zp +$0c tsb addr +$14 trb zp +$1c trb addr +$34 bit zp,y +$52 eor (zp) +$5a phy +$72 adc (zp) +$74 stz zp,y +$7a ply +$7c jmp (addr) +$89 bit #imm8 +$92 sta (zp) +$9c stz addr +$9e stz addr,x +$d2 cmp (zp) +$da phx +$f2 sbc (zp) +$fa plx +</verb></tscreen> + + For more information about the M740 Controllers, see <url url="https://en.wikipedia.org/wiki/Mitsubishi_740" name="Wikipedia">. -<sect2>65816 mode<label id="65816-mode"><p><p> +<sect1>65816<label id="65816-mode"><p><p> -The 65816 support requires annotating ranges with the M and X flag states. -This can be recorded with an emulator that supports Code and Data Logging, -for example. Disassemble one bank at a time. +The 65816 is a 16bit CPU developed by WDC. +<sect>other<p> -<sect2>Sweet16<label id="sweet16-mode"><p><p> +<sect1>Sweet16<label id="sweet16-mode"><p><p> SWEET 16 is an interpreter for a pseudo 16 bit CPU written by Steve Wozniak for the Apple ][ machines. It is available in the Apple ][ ROM. +It implements the following opcodes: + +<tscreen><verb> +00 1 RTN (Return to 6502 mode) +01 2 BR ea (Branch always) +02 2 BNC ea (Branch if No Carry) +03 2 BC ea (Branch if Carry) +04 2 BP ea (Branch if Plus) +05 2 BM ea (Branch if Minus) +06 2 BZ ea (Branch if Zero) +07 2 BNZ ea (Branch if NonZero) +08 2 BM1 ea (Branch if Minus 1) +09 2 BNM1 ea (Branch if Not Minus 1) +0A 1 BK (Break to Monitor) +0B 1 RS (Return from Subroutine) +0C 1 BS ea (Branch to Subroutine) +1n 3 SET Rn R<-2 byte constant (Set Constant) (load register immediate) +2n 1 LD Rn ACC<-R (Load) +3n 1 ST Rn ACC->R (Store) +4n 1 LD @Rn ACC<-@R, R<-R+1 (Load Indirect) +5n 1 ST @Rn ACC->@R, R<-R+1 (Store Indirect) +6n 1 LDD @Rn ACC<-@R double (Load Double Indirect) +7n 1 STD @Rn ACC->@R double (Store Double Indirect) +8n 1 POP @Rn R<-R-1, ACC<-@R (pop) (Pop Indirect) +9n 1 STP @Rn R<-R-1, ACC->@R (Store POP Indirect) +An 1 ADD Rn ACC<-@R (pop) double (Add) +Bn 1 SUB Rn compare ACC to R (Sub) +Cn 1 POPD @Rn ACC<-ACC+R (Pop Double Indirect) +Dn 1 CPR Rn ACC<-ACC-R (Compare) +En 1 INR Rn R<-R+1 (Increment) +Fn 1 DCR Rn R<-R-1 (Decrement) +</verb></tscreen> + For more information about SWEET 16, see <url url="http://www.6502.org/source/interpreters/sweet16.htm">. + <sect>Copyright<p> ca65 (and all cc65 binutils) are (C) Copyright 1998-2003 Ullrich von diff --git a/doc/da65.sgml b/doc/da65.sgml index e2c6d7e90..ba3ceb165 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -267,18 +267,18 @@ With the command line option <tt><ref id="option--cpu" name="--cpu"></tt>, the disassembler may be told which CPU to support: <itemize> - <item><ref id="6502-mode" name="6502"> - NMOS 6502 (all legal instructions) - <item><ref id="6502X-mode" name="6502X"> - NMOS 6502 with all undocumented instructions - <item><ref id="DTV-mode" name="6502DTV"> - the emulated CPU of the C64DTV device - <item><ref id="65SC02-mode" name="65SC02"> - first CMOS instruction set (no bit manipulation) - <item><ref id="65C02-mode" name="65C02"> - full CMOS instruction set (has bit manipulation) - <item><ref id="W65C02-mode" name="W65C02"> - CMOS with WDC extensions - <item><ref id="65CE02-mode" name="65CE02"> - CMOS with GTE extensions - <item><ref id="65816-mode" name="65816"> - the CPU of the SNES, and the SCPU - <item><ref id="HUC6280-mode" name="HuC6280"> - the CPU of the PC engine - <item><ref id="4510-mode" name="4510"> - the CPU of the Commodore C65 - <item><ref id="45GS02-mode" name="45GS02"> - the CPU of the Commodore MEGA65 - <item><ref id="M740-mode" name="M740"> - a Microcontroller by Mitsubishi + <item>6502 - NMOS 6502 (all legal instructions) + <item>6502X - NMOS 6502 with all undocumented instructions + <item>6502DTV - the emulated CPU of the C64DTV device + <item>65SC02 - first CMOS instruction set (no bit manipulation, no wai/stp) + <item>65C02 - CMOS with Rockwell extensions + <item>W65C02 - full CMOS instruction set (has bit manipulation and wai/stp) + <item>65CE02 - CMOS with CSG extensions + <item>4510 - the CPU of the Commodore C65 + <item>45GS02 - the CPU of the Commodore MEGA65 + <item>HuC6280 - the CPU of the PC engine + <item>M740 - a Microcontroller by Mitsubishi + <item>65816 - the CPU of the SNES, and the SCPU </itemize> for more details on the various CPUs, see <tt><htmlurl url="cpus.html" name="here"></tt>. From b878f05721d9e4a999b26c53b7e4361d0e99a709 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 17:06:32 +0200 Subject: [PATCH 666/707] add 65816 opcodes --- doc/cpus.sgml | 92 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/doc/cpus.sgml b/doc/cpus.sgml index 7564a543f..d25ea3ebf 100644 --- a/doc/cpus.sgml +++ b/doc/cpus.sgml @@ -910,8 +910,6 @@ $f2 sbc (zp) $fa plx </verb></tscreen> - - For more information about the M740 Controllers, see <url url="https://en.wikipedia.org/wiki/Mitsubishi_740" name="Wikipedia">. @@ -919,7 +917,95 @@ For more information about the M740 Controllers, see <sect1>65816<label id="65816-mode"><p><p> -The 65816 is a 16bit CPU developed by WDC. +The W65C816S is a 16bit CPU developed by WDC. The instruction set contains the +complete legal 6502 instructions, the original CMOS instructions (65SC02), plus +some new instructions and addressing modes. It has wai/stp, but it does NOT have +the Rockwell extensions (BBRx, BBSx, RMBx and SMBx bit manipulation instructions). + +(24 new instructions, 77 new opcodes, 88 instructions/256 opcodes total) + +<tscreen><verb> +$02 cop imm8 coprocessor operation +$03 ora offs8, s +$07 ora [dp] +$0b phd push direct page register +$0f ora abs24 +$13 ora (offs8, s), y +$17 ora [dp], y +$1b tcs transfer C to stack pointer +$1f ora abs24, x +$22 jsr abs24 +$23 and offs8, s +$27 and [dp] +$2b pld pull direct page register +$2f and abs24 +$33 and (offs8, s), y +$37 and [dp], y +$3b tsc transfer stack pointer to C +$3f and abs24, x +$42 wdm (reserved for future expansion) +$43 eor offs8, s +$44 mvp src, dst +$47 eor [dp] +$4b phk push program bank register +$4f eor abs24 +$53 eor (offs8, s), y +$54 mvn src, dst +$57 eor [dp], y +$5b tcd transfer C to direct page register +$5c jmp abs24 +$5f eor abs24, x +$62 per rel16 push effective relative address +$63 adc offs8, s +$67 adc [dp] +$6b rtl return long (fetches 24-bit address from stack) +$6f adc abs24 +$73 adc (offs8, s), y +$77 adc [dp], y +$7b tdc transfer direct page register to C +$7f adc abs24, x +$82 brl rel16 branch long (16-bit offset) +$83 sta offs8, s +$87 sta [dp] +$8b phb push data bank register +$8f sta abs24 +$93 sta (offs8, s), y +$97 sta [dp], y +$9b txy transfer X to Y +$9f sta abs24, x +$a3 lda offs8, s +$a7 lda [dp] +$ab plb pull data bank register +$af lda abs24 +$b3 lda (offs8, s), y +$b7 lda [dp], y +$bb tyx transfer Y to X +$bf lda abs24, x +$c2 rep #imm8 clear bits in status register +$c3 cmp offs8, s +$c7 cmp [dp] +$cb wai wait for interrupt +$cf cmp abs24 +$d3 cmp (offs8, s), y +$d4 pei (dp) push effective indirect address +$d7 cmp [dp], y +$db stp wait for reset +$dc jmp [abs16] +$df cmp abs24, x +$e2 sep #imm8 set bits in status register +$e3 sbc offs8, s +$e7 sbc [dp] +$eb xba exchange high and low bytes of accumulator +$ef sbc abs24 +$f3 sbc (offs8, s), y +$f4 pea abs16 push effective absolute address +$f7 sbc [dp], y +$fb xce exchange Carry and Emulation bits +$fc jsr (abs16, x) +$ff sbc abs24, x +</verb></tscreen> + + <sect>other<p> From dd0d908d57f7af7e4a7a1e24830bdb3ad2e6598a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 17:21:22 +0200 Subject: [PATCH 667/707] 65816 does not have Rockwell extensions --- src/common/cpu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index 272fa4262..252283211 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -78,13 +78,12 @@ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_6502DTV | CPU_ISET_6502, CPU_ISET_65SC02 | CPU_ISET_6502, CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02, - /* FIXME: does 65816 have both wai/stp and indirect-zp (without z)? */ - CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* 65816 has wai/stp and NO bit manipulation */ + CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02, CPU_ISET_SWEET16, CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, CPU_ISET_M740 | CPU_ISET_6502, /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ - /* FIXME: 4510 does not have wai/stp */ CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02, CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510, CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, From 51dc9119a973dbbe84ff6d9722229bab52415eb7 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 17:21:40 +0200 Subject: [PATCH 668/707] fix test --- test/asm/cpudetect/65816-cpudetect.ref | Bin 61 -> 46 bytes test/asm/cpudetect/cpudetect.s | 35 +++++++++++++------------ 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/test/asm/cpudetect/65816-cpudetect.ref b/test/asm/cpudetect/65816-cpudetect.ref index 4f6e767b0b9e0d16b239976a71a01268186788b3..e614b34c901fbc0e882052e9ad12c13c09237828 100644 GIT binary patch delta 8 PcmcE3o1o2XVQ2;b2(<yp delta 23 ecmdP1ouDn`Y+%IT91t4s8SEMoZ)R#?Xa)d8Uj@Se diff --git a/test/asm/cpudetect/cpudetect.s b/test/asm/cpudetect/cpudetect.s index 86f31f7a3..603742f78 100644 --- a/test/asm/cpudetect/cpudetect.s +++ b/test/asm/cpudetect/cpudetect.s @@ -70,6 +70,10 @@ .byte 0,"CPU_ISET_6502X" .endif +.if (.cpu .bitand CPU_ISET_6502DTV) + .byte 0,"CPU_ISET_6502DTV" +.endif + .if (.cpu .bitand CPU_ISET_65SC02) .byte 0,"CPU_ISET_65SC02" .endif @@ -86,18 +90,6 @@ .byte 0,"CPU_ISET_65CE02" .endif -.if (.cpu .bitand CPU_ISET_65816) - .byte 0,"CPU_ISET_65816" -.endif - -.if (.cpu .bitand CPU_ISET_SWEET16) - .byte 0,"CPU_ISET_SWEET16" -.endif - -.if (.cpu .bitand CPU_ISET_HUC6280) - .byte 0,"CPU_ISET_HUC6280" -.endif - .if (.cpu .bitand CPU_ISET_4510) .byte 0,"CPU_ISET_4510" .endif @@ -106,19 +98,28 @@ .byte 0,"CPU_ISET_45GS02" .endif -.if (.cpu .bitand CPU_ISET_6502DTV) - .byte 0,"CPU_ISET_6502DTV" +.if (.cpu .bitand CPU_ISET_HUC6280) + .byte 0,"CPU_ISET_HUC6280" .endif .if (.cpu .bitand CPU_ISET_M740) .byte 0,"CPU_ISET_M740" .endif -; FIXME: something with 65816 is quirky -.if (.not .cpu .bitand CPU_ISET_65816) - .include "allinst.inc" +.if (.cpu .bitand CPU_ISET_65816) + .byte 0,"CPU_ISET_65816" .endif +.if (.cpu .bitand CPU_ISET_SWEET16) + .byte 0,"CPU_ISET_SWEET16" +.endif + + +; FIXME: something with 65816 is quirky +;.if (.not .cpu .bitand CPU_ISET_65816) + .include "allinst.inc" +;.endif + ; step 3: switch through all supported cpus to verify the pseudo-op is there From 501dc00c9f4c9ba559697924da64fd1c82d218df Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 18:28:49 +0200 Subject: [PATCH 669/707] fix JSL/JML --- doc/ca65.sgml | 7 +++++++ doc/cpus.sgml | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 0b62a045c..0e3b60516 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -636,6 +636,13 @@ or two far addresses whose high byte will be used. mvp $123456, $789ABC ; bank $12 to $78 </verb></tscreen> +also see <ref id="long_jsr_jmp_rts" name="long_jsr_jmp_rts"> + <ref id=".SMART" name=".SMART"> + <ref id=".A8" name=".A8"> + <ref id=".A16" name=".A16"> + <ref id=".I8" name=".I8"> + <ref id=".I16" name=".I16"> + <sect2>sweet16 mode<label id="sweet16-mode"><p> diff --git a/doc/cpus.sgml b/doc/cpus.sgml index d25ea3ebf..60230408f 100644 --- a/doc/cpus.sgml +++ b/doc/cpus.sgml @@ -934,7 +934,7 @@ $13 ora (offs8, s), y $17 ora [dp], y $1b tcs transfer C to stack pointer $1f ora abs24, x -$22 jsr abs24 +$22 jsl abs24 $23 and offs8, s $27 and [dp] $2b pld pull direct page register @@ -953,7 +953,7 @@ $53 eor (offs8, s), y $54 mvn src, dst $57 eor [dp], y $5b tcd transfer C to direct page register -$5c jmp abs24 +$5c jml abs24 $5f eor abs24, x $62 per rel16 push effective relative address $63 adc offs8, s From 4d73544d6c1358665194e0be8f044b003b21a718 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 18:29:22 +0200 Subject: [PATCH 670/707] cleanup/fix test for 65816 --- test/asm/cpudetect/allinst.inc | 261 ++++++++++++++++++++++----------- test/asm/cpudetect/cpudetect.s | 23 ++- 2 files changed, 186 insertions(+), 98 deletions(-) diff --git a/test/asm/cpudetect/allinst.inc b/test/asm/cpudetect/allinst.inc index 423e7b74a..d604c36b9 100644 --- a/test/asm/cpudetect/allinst.inc +++ b/test/asm/cpudetect/allinst.inc @@ -357,7 +357,6 @@ LABEL: .endscope .endif - ;------------------------------------------------------------------------------ ; The 65sc02 is the original CMOS re-design of the 6502. ; @@ -426,27 +425,7 @@ LABEL: .endif -; Rockwell Datasheet "R65C02, R65C102, R65C112 R65C00 Microprocessors (CPU)" 1987,rev6: -; -; The 8-bit R65C00 microprocessor family of devices are produced using CMOS [...] -; technology which provides advanced [...] performance speed and [...] over their -; NMOS counterparts, the R6500 family of microprocessor devices. [...] -; The CMOS family ... has been designed with many enhancements over the R6502 -; NMOS device [...] -; ; The R65C02 is a superset of the 65C02. It adds bit manipulation instructions: -; -; smbB zp set bit in zp location -; rmbB zp reset bit in zp location -; bbsB zp, rel8 branch if bit is set in zp location -; bbrB zp, rel8 branch if bit is reset in zp location -; -; 12 new instructions for a total of 68 -; 59 new op ocdes, for a total of 210 -; two new addressing modes -; seven software/operational enhancements -; two hardware enhancements - .if (.cpu .bitand CPU_ISET_65C02) ; R65C02 instruction set adds some extra legal instructions to 65C02 @@ -488,10 +467,6 @@ LABEL3: ; The W65C02 is a superset of the R65C02. It only adds two instructions: -; -; $cb wai wait for interrupt -; $db stp wait for reset - .if (.cpu .bitand CPU_ISET_W65C02) wai ; $cb stp ; $db @@ -499,68 +474,9 @@ LABEL3: ; The 65CE02 is another superset of the R65C02. It has several improvements: -; -; $02 cle clear stack extend disable -; $03 see set stack extend disable -; $0b tsy transfer stack_ptr_high to Y -; $12 ora (zp), z -; $13 lbpl rel16 -; $1b inz increment Z -; $22 jsr (abs16) -; $23 jsr (abs16, x) -; $2b tys transfer Y to stack_ptr_high -; $32 and (zp), z -; $33 lbmi rel16 -; $3b dez decrement Z -; $42 neg negate A -; $43 asr -; $44 asr zp -; $4b taz transfer A to Z -; $52 eor (zp), z -; $53 lbvc rel16 -; $54 asr zp, x -; $5b tab -; $5c aug "4-byte NOP reserved for future expansion" -; $62 rtn #imm8 -; $63 lbsr rel16 relative jsr, "branch to subroutine" -; $64 stz zp store Z -; $6b tza transfer Z to A -; $72 adc (zp), z -; $73 lbvs rel16 -; $74 stz zp, x store Z -; $7b tba -; $82 sta (off8, s), y -; $83 lbra rel16 relative jmp -; $8b sty abs16, x -; $92 sta (zp), z -; $93 lbcc rel16 -; $9b stx abs16, y -; $9c stz abs16 store Z -; $9e stz abs16, x store Z -; $a3 ldz #imm8 -; $ab ldz abs16 -; $b2 lda (zp), z -; $b3 lbcs rel16 -; $bb ldz abs16, x -; $c2 cpz #imm8 -; $c3 dew zp -; $cb asw abs16 -; $d2 cmp (zp), z -; $d3 lbne rel16 -; $d4 cpz zp -; $db phz push Z -; $dc cpz abs16 -; $e2 lda (off8, s), y -; $e3 inw zp -; $eb row abs16 -; $f2 sbc (zp), z -; $f3 lbeq rel16 -; $f4 phw #imm16 -; $fb plz pull Z -; $fc phw abs16 - .if (.cpu .bitand CPU_ISET_65CE02) .scope + ; 65CE02 adds the following: cle ; $02 see ; $03 @@ -879,3 +795,178 @@ LABEL: .endscope .endif +.if (.cpu .bitand CPU_ISET_65816) + + .smart - ; Stop being smart + + .A8 ; akku 8 bit + .I8 ; index registers 8 bit + + .scope + cop $12 ; $02 coprocessor operation + ora $12, s ; $03 + ora [$12] ; $07 + phd ; $0b push direct page register + ora $123456 ; $0f + ora ($12, s), y ; $13 + ora [$12], y ; $17 + tcs ; $1b transfer C to stack pointer + ora $123456, x ; $1f + jsl $123456 ; $22 + and $12, s ; $23 + and [$12] ; $27 + pld ; $2b pull direct page register + and $123456 ; $2f + and ($12, s), y ; $33 + and [$12], y ; $37 + tsc ; $3b transfer stack pointer to C + and $123456, x ; $3f + wdm $12 ; $42 (reserved for future expansion) + eor $12, s ; $43 + mvp $1234, $5678 ; $44 + eor [$12] ; $47 + phk ; $4b push program bank register + eor $123456 ; $4f + eor ($12, s), y ; $53 + mvn $1234, $5678 ; $54 + eor [$12], y ; $57 + tcd ; $5b transfer C to direct page register + jml $123456 ; $5c + eor $123456, x ; $5f + per LABEL ; $62 push effective relative address + adc $12, s ; $63 + adc [$12] ; $67 + rtl ; $6b return long (fetches 24-bit address from stack) + adc $123456 ; $6f + adc ($12, s), y ; $73 + adc [$12], y ; $77 + tdc ; $7b transfer direct page register to C + adc $123456, x ; $7f +LABEL: + brl LABEL ; $82 branch long (16-bit offset) + sta $12, s ; $83 + sta [$12] ; $87 + phb ; $8b push data bank register + sta $123456 ; $8f + sta ($12, s), y ; $93 + sta [$12], y ; $97 + txy ; $9b transfer X to Y + sta $123456, x ; $9f + lda $12, s ; $a3 + lda [$12] ; $a7 + plb ; $ab pull data bank register + lda $123456 ; $af + lda ($12, s), y ; $b3 + lda [$12], y ; $b7 + tyx ; $bb transfer Y to X + lda $123456, x ; $bf + rep #$12 ; $c2 clear bits in status register + cmp $12, s ; $c3 + cmp [$12] ; $c7 + wai ; $cb wait for interrupt + cmp $123456 ; $cf + cmp ($12, s), y ; $d3 + pei ($12) ; $d4 push effective indirect address + cmp [$12], y ; $d7 + stp ; $db wait for reset + jmp [$1234] ; $dc + cmp $123456, x ; $df + sep #$12 ; $e2 set bits in status register + sbc $12, s ; $e3 + sbc [$12] ; $e7 + xba ; $eb exchange high and low bytes of accumulator + sbc $123456 ; $ef + sbc ($12, s), y ; $f3 + pea $1234 ; $f4 push effective absolute address + sbc [$12], y ; $f7 + xce ; $fb exchange Carry and Emulation bits + jsr ($1234, x) ; $fc + sbc $123456, x ; $ff + .endscope + + .A16 ; akku 16 bit + .I16 ; index registers 16 bit + + .scope + cop $12 ; $02 coprocessor operation + ora $12, s ; $03 + ora [$12] ; $07 + phd ; $0b push direct page register + ora $123456 ; $0f + ora ($12, s), y ; $13 + ora [$12], y ; $17 + tcs ; $1b transfer C to stack pointer + ora $123456, x ; $1f + jsl $123456 ; $22 + and $12, s ; $23 + and [$12] ; $27 + pld ; $2b pull direct page register + and $123456 ; $2f + and ($12, s), y ; $33 + and [$12], y ; $37 + tsc ; $3b transfer stack pointer to C + and $123456, x ; $3f + wdm $12 ; $42 (reserved for future expansion) + eor $12, s ; $43 + mvp $1234, $5678 ; $44 + eor [$12] ; $47 + phk ; $4b push program bank register + eor $123456 ; $4f + eor ($12, s), y ; $53 + mvn $1234, $5678 ; $54 + eor [$12], y ; $57 + tcd ; $5b transfer C to direct page register + jml $123456 ; $5c + eor $123456, x ; $5f + per LABEL ; $62 push effective relative address + adc $12, s ; $63 + adc [$12] ; $67 + rtl ; $6b return long (fetches 24-bit address from stack) + adc $123456 ; $6f + adc ($12, s), y ; $73 + adc [$12], y ; $77 + tdc ; $7b transfer direct page register to C + adc $123456, x ; $7f +LABEL: + brl LABEL ; $82 branch long (16-bit offset) + sta $12, s ; $83 + sta [$12] ; $87 + phb ; $8b push data bank register + sta $123456 ; $8f + sta ($12, s), y ; $93 + sta [$12], y ; $97 + txy ; $9b transfer X to Y + sta $123456, x ; $9f + lda $12, s ; $a3 + lda [$12] ; $a7 + plb ; $ab pull data bank register + lda $123456 ; $af + lda ($12, s), y ; $b3 + lda [$12], y ; $b7 + tyx ; $bb transfer Y to X + lda $123456, x ; $bf + rep #$12 ; $c2 clear bits in status register + cmp $12, s ; $c3 + cmp [$12] ; $c7 + wai ; $cb wait for interrupt + cmp $123456 ; $cf + cmp ($12, s), y ; $d3 + pei ($12) ; $d4 push effective indirect address + cmp [$12], y ; $d7 + stp ; $db wait for reset + jmp [$1234] ; $dc + cmp $123456, x ; $df + sep #$12 ; $e2 set bits in status register + sbc $12, s ; $e3 + sbc [$12] ; $e7 + xba ; $eb exchange high and low bytes of accumulator + sbc $123456 ; $ef + sbc ($12, s), y ; $f3 + pea $1234 ; $f4 push effective absolute address + sbc [$12], y ; $f7 + xce ; $fb exchange Carry and Emulation bits + jsr ($1234, x) ; $fc + sbc $123456, x ; $ff + .endscope + +.endif diff --git a/test/asm/cpudetect/cpudetect.s b/test/asm/cpudetect/cpudetect.s index 603742f78..414afe68d 100644 --- a/test/asm/cpudetect/cpudetect.s +++ b/test/asm/cpudetect/cpudetect.s @@ -12,6 +12,11 @@ lax #$ea .endif +.ifp6280 + sax + cla +.endif + .ifpsc02 jmp ($1234,x) .endif @@ -29,10 +34,6 @@ ldz #$12 .endif -.ifp816 - xba -.endif - .ifp4510 taz .endif @@ -45,15 +46,14 @@ sac #$00 .endif -.ifp6280 - sax - cla -.endif - .ifpm740 jsr $ff12 .endif +.ifp816 + xba +.endif + ; step 2: check for bitwise compatibility of instructions sets ; (made verbose for better reading with hexdump/hd(1)) @@ -115,10 +115,7 @@ .endif -; FIXME: something with 65816 is quirky -;.if (.not .cpu .bitand CPU_ISET_65816) - .include "allinst.inc" -;.endif +.include "allinst.inc" ; step 3: switch through all supported cpus to verify the pseudo-op is there From af89b222520a8f126b709ad37e363b0d752795c4 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 19:13:56 +0200 Subject: [PATCH 671/707] add missing pseudos for sweet16 --- src/ca65/condasm.c | 10 ++++++++++ src/ca65/pseudo.c | 10 ++++++++++ src/ca65/scanner.c | 2 ++ src/ca65/token.h | 2 ++ 4 files changed, 24 insertions(+) diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index ed170b6d4..8570b355b 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -494,6 +494,16 @@ void DoConditionals (void) CalcOverallIfCond (); break; + case TOK_IFPSWEET16: + D = AllocIf (".IFPSWEET16", 1); + NextTok (); + if (IfCond) { + SetIfCond (D, GetCPU() == CPU_SWEET16); + } + ExpectSep (); + CalcOverallIfCond (); + break; + case TOK_IFPWC02: D = AllocIf (".IFPWC02", 1); NextTok (); diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 27207c84c..e6e10df2c 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -1752,6 +1752,14 @@ static void DoPSC02 (void) +static void DoPSweet16 (void) +/* Switch to Sweet16 CPU */ +{ + SetCPU (CPU_SWEET16); +} + + + static void DoPushCharmap (void) /* Save the current charmap */ { @@ -2191,6 +2199,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccKeepToken, DoConditionals }, /* .IFPDTV */ { ccKeepToken, DoConditionals }, /* .IFPM740 */ { ccKeepToken, DoConditionals }, /* .IFPSC02 */ + { ccKeepToken, DoConditionals }, /* .IFPSWEET16 */ { ccKeepToken, DoConditionals }, /* .IFPWC02 */ { ccKeepToken, DoConditionals }, /* .IFREF */ { ccNone, DoImport }, /* .IMPORT */ @@ -2236,6 +2245,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoPopSeg }, /* .POPSEG */ { ccNone, DoProc }, /* .PROC */ { ccNone, DoPSC02 }, /* .PSC02 */ + { ccNone, DoPSweet16 }, /* .PSWEET16 */ { ccNone, DoPushCharmap }, /* .PUSHCHARMAP */ { ccNone, DoPushCPU }, /* .PUSHCPU */ { ccNone, DoPushSeg }, /* .PUSHSEG */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 68ff71cc7..f3892d32e 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -231,6 +231,7 @@ struct DotKeyword { { ".IFPDTV", TOK_IFPDTV }, { ".IFPM740", TOK_IFPM740 }, { ".IFPSC02", TOK_IFPSC02 }, + { ".IFPSWEET16", TOK_IFPSWEET16 }, { ".IFPWC02", TOK_IFPWC02 }, { ".IFREF", TOK_IFREF }, { ".IMPORT", TOK_IMPORT }, @@ -282,6 +283,7 @@ struct DotKeyword { { ".POPSEG", TOK_POPSEG }, { ".PROC", TOK_PROC }, { ".PSC02", TOK_PSC02 }, + { ".PSWEET16", TOK_PSWEET16 }, { ".PUSHCHARMAP", TOK_PUSHCHARMAP }, { ".PUSHCPU", TOK_PUSHCPU }, { ".PUSHSEG", TOK_PUSHSEG }, diff --git a/src/ca65/token.h b/src/ca65/token.h index de80fc910..e2b223880 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -204,6 +204,7 @@ typedef enum token_t { TOK_IFPDTV, TOK_IFPM740, TOK_IFPSC02, + TOK_IFPSWEET16, TOK_IFPWC02, TOK_IFREF, TOK_IMPORT, @@ -249,6 +250,7 @@ typedef enum token_t { TOK_POPSEG, TOK_PROC, TOK_PSC02, + TOK_PSWEET16, TOK_PUSHCHARMAP, TOK_PUSHCPU, TOK_PUSHSEG, From 91c9e32e4be6af83d387bf39fa39c754d8d9fa8a Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 19:14:28 +0200 Subject: [PATCH 672/707] add sweet16 to the cpudetect test --- test/asm/cpudetect/allinst.inc | 37 +++++++++++++++++++++++ test/asm/cpudetect/cpudetect.s | 6 +++- test/asm/cpudetect/sweet16-cpudetect.ref | Bin 0 -> 18 bytes 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 test/asm/cpudetect/sweet16-cpudetect.ref diff --git a/test/asm/cpudetect/allinst.inc b/test/asm/cpudetect/allinst.inc index d604c36b9..2ba44ff83 100644 --- a/test/asm/cpudetect/allinst.inc +++ b/test/asm/cpudetect/allinst.inc @@ -970,3 +970,40 @@ LABEL: .endscope .endif + +.if (.cpu .bitand CPU_ISET_SWEET16) + + RTN ; $00 Return to 6502 code. + BR LABEL ; $01 ea Unconditional Branch. + BNC LABEL ; $02 ea Branch if Carry=0. + BC LABEL ; $03 ea Branch if Carry=1. + BP LABEL ; $04 ea Branch if last result positive. + BM LABEL ; $0S ea Branch if last result negative. + BZ LABEL ; $06 ea Branch if last result zero. + BNZ LABEL ; $07 ea Branch if last result non-zero. + BM1 LABEL ; $08 ea Branch if last result = -1. + BNM1 LABEL ; $09 ea Branch if last result not -1. + BK ; $0A Execute 6502 BRK instruction. + RS ; $0B Return from SWEET-16 subroutine. + BS LABEL ; $0C ea Call SWEET-16 subroutine. +LABEL: + +.repeat 16, count + SET count,$1234 ; $1n lo hi Rn <-- value. + LD count ; $2n R0 <-- (Rn). + ST count ; $3n Rn <-- (R0). + LD @count ; $4n MA = (Rn), ROL <-- (MA), Rn <-- MA+1, R0H <-- 0. + ST @count ; $5n MA = (Rn), MA <-- (R0L), Rn <-- MA+1. + LDD @count ; $6n MA = (Rn), R0 <-- (MA, MA+1), Rn <-- MA+2. + STD @count ; $7n MA = (Rn), MA,MA+l <-- (R0), Rn <-- MA+2. + POP @count ; $8n MA = (Rn)-1, R0L <-- (MA), R0H <-- 0, Rn <-- MA. + STP @count ; $9n MA <-- (Rn)-1, (MA) <-- R0L, Rn <-- MA. + ADD count ; $An R0 <-- (R0) + (Rn). + SUB count ; $Bn R0 <-- (R0) - (Rn). + POPD @count ; $Cn MA = (Rn)-2, MA,MA+l <-- R0, Rn <-- MA. + CPR count ; $Dn R13 <-- (R0) - (Rn), R14 <-- status flags. + INR count ; $En Rn <-- (Rn) + 1. + DCR count ; $Fn Rn <-- (Rn) - 1. +.endrepeat + +.endif diff --git a/test/asm/cpudetect/cpudetect.s b/test/asm/cpudetect/cpudetect.s index 414afe68d..3022038a2 100644 --- a/test/asm/cpudetect/cpudetect.s +++ b/test/asm/cpudetect/cpudetect.s @@ -54,6 +54,10 @@ xba .endif +.ifpsweet16 + bk +.endif + ; step 2: check for bitwise compatibility of instructions sets ; (made verbose for better reading with hexdump/hd(1)) @@ -132,4 +136,4 @@ .p6280 .pm740 .p816 -; FIXME: sweet16 +.psweet16 diff --git a/test/asm/cpudetect/sweet16-cpudetect.ref b/test/asm/cpudetect/sweet16-cpudetect.ref new file mode 100644 index 0000000000000000000000000000000000000000..98d33127aeb50b9577095ed14649ddac5ad0a2d4 GIT binary patch literal 18 Zcmd;La1IEK_Y8Ioi4P8Ubqz5z0{|-u1l0fl literal 0 HcmV?d00001 From a1a87f74a94ad2cd9150658a03172fe11ac0aabc Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 19:45:29 +0200 Subject: [PATCH 673/707] add pseudos to docs --- doc/ca65.sgml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 0e3b60516..b7e8539af 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -3409,6 +3409,12 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH (see <tt><ref id=".PSC02" name=".PSC02"></tt> command). +<sect1><tt>.IFPSWEET16</tt><label id=".IFPSWEET16"><p> + + Conditional assembly: Check if the assembler is currently in Sweet16 mode + (see <tt><ref id=".PSWEET16" name=".PSWEET16"></tt> command). + + <sect1><tt>.IFREF</tt><label id=".IFREF"><p> Conditional assembly: Check if a symbol is referenced. Must be followed @@ -3972,6 +3978,17 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE" <tt><ref id=".P4510" name=".P4510"></tt>, and <tt><ref id=".P45GS02" name=".P45GS02"></tt> + +<sect1><tt>.PSWEET16</tt><label id=".PSWEET16"><p> + + Enable the Sweet16 instructions set. + + See: <tt><ref id=".P02" name=".P02"></tt>, <tt><ref id=".PC02" + name=".PC02"></tt>, <tt><ref id=".P816" name=".P816"></tt>, + <tt><ref id=".P4510" name=".P4510"></tt>, and + <tt><ref id=".P45GS02" name=".P45GS02"></tt> + + <sect1><tt>.PUSHCHARMAP</tt><label id=".PUSHCHARMAP"><p> Push the currently active character mapping onto a stack. The stack has a size of 16 From e85339dada4cccd18cc64020cb488074bb09b634 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 19:51:22 +0200 Subject: [PATCH 674/707] add sweet16 to the opcodes test as well --- test/asm/opcodes/sweet16-opcodes.ref | Bin 0 -> 295 bytes test/asm/opcodes/sweet16-opcodes.s | 34 +++++++++++++++++++++++++++ test/asm/val/ismnemonic.s | 1 + 3 files changed, 35 insertions(+) create mode 100644 test/asm/opcodes/sweet16-opcodes.ref create mode 100644 test/asm/opcodes/sweet16-opcodes.s diff --git a/test/asm/opcodes/sweet16-opcodes.ref b/test/asm/opcodes/sweet16-opcodes.ref new file mode 100644 index 0000000000000000000000000000000000000000..af128b55f2728a79baab393f2bdd4fa3e73e8a38 GIT binary patch literal 295 zcmV+?0oeWk0Tcof0}uob1q=oX2M7oT2?PoY3;+-`5+E=@P+)L?kf5-@(BSY9G!h{( zK~Z6GfsvuH!O`LI5;PJbGD1>fa)Oegvcl5h@)I-?BQrx&V{?O(qqD=)<MR|W5+pQ4 zRAh97l%%x8)a3LPG!i8>MO9^Wg_WhX#nt8Y7BmtjHbz!vc7~Rww#L@x_7^k~CpSk| zXLpB}r?<z~=l2*i5-2!GSZH{Nn5ekO*y#8fG!iK}Nm*%miJ7Un$=T`o8Z;6rI!an< zdWxE=y2{$>`WrM7D?3YDYkP~EtGmnF>-!uu5-dDSTx@)doUFXe-0b`vG!iX6O<iq$ tjh(H%&E4(&9yAgzK2Bb4evY25zRuq6{vR|FFF#LTZ-0-UufNaV@BbS<gd+d| literal 0 HcmV?d00001 diff --git a/test/asm/opcodes/sweet16-opcodes.s b/test/asm/opcodes/sweet16-opcodes.s new file mode 100644 index 000000000..f283c6093 --- /dev/null +++ b/test/asm/opcodes/sweet16-opcodes.s @@ -0,0 +1,34 @@ +.setcpu "SWEET16" + + RTN ; $00 Return to 6502 code. + BR LABEL ; $01 ea Unconditional Branch. + BNC LABEL ; $02 ea Branch if Carry=0. + BC LABEL ; $03 ea Branch if Carry=1. + BP LABEL ; $04 ea Branch if last result positive. + BM LABEL ; $0S ea Branch if last result negative. + BZ LABEL ; $06 ea Branch if last result zero. + BNZ LABEL ; $07 ea Branch if last result non-zero. + BM1 LABEL ; $08 ea Branch if last result = -1. + BNM1 LABEL ; $09 ea Branch if last result not -1. + BK ; $0A Execute 6502 BRK instruction. + RS ; $0B Return from SWEET-16 subroutine. + BS LABEL ; $0C ea Call SWEET-16 subroutine. +LABEL: + +.repeat 16, count + SET count,$1234 ; $1n lo hi Rn <-- value. + LD count ; $2n R0 <-- (Rn). + ST count ; $3n Rn <-- (R0). + LD @count ; $4n MA = (Rn), ROL <-- (MA), Rn <-- MA+1, R0H <-- 0. + ST @count ; $5n MA = (Rn), MA <-- (R0L), Rn <-- MA+1. + LDD @count ; $6n MA = (Rn), R0 <-- (MA, MA+1), Rn <-- MA+2. + STD @count ; $7n MA = (Rn), MA,MA+l <-- (R0), Rn <-- MA+2. + POP @count ; $8n MA = (Rn)-1, R0L <-- (MA), R0H <-- 0, Rn <-- MA. + STP @count ; $9n MA <-- (Rn)-1, (MA) <-- R0L, Rn <-- MA. + ADD count ; $An R0 <-- (R0) + (Rn). + SUB count ; $Bn R0 <-- (R0) - (Rn). + POPD @count ; $Cn MA = (Rn)-2, MA,MA+l <-- R0, Rn <-- MA. + CPR count ; $Dn R13 <-- (R0) - (Rn), R14 <-- status flags. + INR count ; $En Rn <-- (Rn) + 1. + DCR count ; $Fn Rn <-- (Rn) - 1. +.endrepeat diff --git a/test/asm/val/ismnemonic.s b/test/asm/val/ismnemonic.s index 2b679abbe..831a8a3c7 100644 --- a/test/asm/val/ismnemonic.s +++ b/test/asm/val/ismnemonic.s @@ -8,6 +8,7 @@ ; "6502DTV" ; "65SC02" ; "65C02" +; "65CE02" ; "W65C02" ; "4510" ; "45GS02" From ce99bfb19550dd3fbeda24a37f633fc6a51d9c0b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 21:05:51 +0200 Subject: [PATCH 675/707] forgot some case values /o\ --- src/ca65/condasm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index 8570b355b..7cd3310b3 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -558,12 +558,14 @@ int CheckConditionals (void) case TOK_IFP02X: case TOK_IFP4510: case TOK_IFP45GS02: + case TOK_IFP6280: case TOK_IFP816: case TOK_IFPC02: case TOK_IFPCE02: case TOK_IFPDTV: case TOK_IFPM740: case TOK_IFPSC02: + case TOK_IFPSWEET16: case TOK_IFPWC02: case TOK_IFREF: DoConditionals (); From 3f3039192f8d02957ba5809861081dd52cddc09b Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 21:06:17 +0200 Subject: [PATCH 676/707] adjust comments --- asminc/cpu.mac | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index a006a9882..15b16bad5 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -5,15 +5,15 @@ CPU_ISET_6502 = $0002 CPU_ISET_6502X = $0004 CPU_ISET_6502DTV = $0008 CPU_ISET_65SC02 = $0010 -CPU_ISET_65C02 = $0020 +CPU_ISET_65C02 = $0020 ; Rockwell extensions CPU_ISET_65816 = $0040 CPU_ISET_SWEET16 = $0080 CPU_ISET_HUC6280 = $0100 CPU_ISET_M740 = $0200 CPU_ISET_4510 = $0400 CPU_ISET_45GS02 = $0800 -CPU_ISET_W65C02 = $1000 -CPU_ISET_65CE02 = $2000 +CPU_ISET_W65C02 = $1000 ; WDC extensions +CPU_ISET_65CE02 = $2000 ; CSG extensions ; CPU capabilities ; make sure to only combine the instruction sets that are 100% compatible @@ -28,9 +28,7 @@ CPU_W65C02 = CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_IS ; FIXME: CPU_ISET_65SC02 does not apply to the following, because the zp-indirect ; addressing was replaced with zp-indirect,z-indexed in 652SCE02 -; NOTE: HUC6280 removes "wai" ($cb) and "stp" ($db) from the 65C02 instruction set CPU_HUC6280 = CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02 -; NOTE: 4510 replaces "wai" ($cb) and "stp" ($db) of the 65C02 instruction set CPU_4510 = CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 CPU_45GS02 = CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510 CPU_M740 = CPU_ISET_M740 | CPU_ISET_6502 From 831eedfb58d398fe5730358b351c93be5b158535 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 22:46:42 +0200 Subject: [PATCH 677/707] add some reasonable warnings/errors when PREFIX is empty --- Makefile | 54 +++++++++++++++++++++++++++++++++++++--------------- src/Makefile | 5 +++++ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 21c1b3208..54cdb53de 100644 --- a/Makefile +++ b/Makefile @@ -4,16 +4,27 @@ ifneq ($(SILENT),s) $(info Using Makefile: $(realpath $(firstword $(MAKEFILE_LIST))) $(MAKECMDGOALS)) endif -.PHONY: all mostlyclean clean install zip avail unavail bin lib doc html info samples test util checkstyle check +.PHONY: all mostlyclean clean install zip avail unavail bin lib doc html info samples test util checkstyle check checkprefix .SUFFIXES: -all install zip: - @$(MAKE) -C src --no-print-directory $@ - @$(MAKE) -C libsrc --no-print-directory $@ - @$(MAKE) -C doc --no-print-directory $@ - @$(MAKE) -C util --no-print-directory $@ - @$(MAKE) -C samples --no-print-directory $@ +all zip: + @$(MAKE) -C src --no-print-directory $@ + @$(MAKE) -C libsrc --no-print-directory $@ + @$(MAKE) -C doc --no-print-directory $@ + @$(MAKE) -C util --no-print-directory $@ + @$(MAKE) -C samples --no-print-directory $@ + @$(MAKE) checkprefix --no-print-directory + +install: +ifndef PREFIX + $(error Error: PREFIX must be set for install to work) +endif + @$(MAKE) -C src --no-print-directory $@ + @$(MAKE) -C libsrc --no-print-directory $@ + @$(MAKE) -C doc --no-print-directory $@ + @$(MAKE) -C util --no-print-directory $@ + @$(MAKE) -C samples --no-print-directory $@ mostlyclean clean: @$(MAKE) -C src --no-print-directory $@ @@ -24,26 +35,39 @@ mostlyclean clean: @$(MAKE) -C test --no-print-directory $@ @$(MAKE) -C targettest --no-print-directory $@ -avail unavail bin: - @$(MAKE) -C src --no-print-directory $@ +avail unavail: +# FIXME: actually not true, PREFIX is ignored? +#ifndef PREFIX +# $(error Error: PREFIX must be set for avail/unavail to work) +#endif + @$(MAKE) -C src --no-print-directory $@ + +bin: + @$(MAKE) -C src --no-print-directory $@ + @$(MAKE) checkprefix --no-print-directory lib libtest: - @$(MAKE) -C libsrc --no-print-directory $@ + @$(MAKE) -C libsrc --no-print-directory $@ doc html info: - @$(MAKE) -C doc --no-print-directory $@ + @$(MAKE) -C doc --no-print-directory $@ samples: - @$(MAKE) -C samples --no-print-directory $@ + @$(MAKE) -C samples --no-print-directory $@ util: - @$(MAKE) -C util --no-print-directory $@ + @$(MAKE) -C util --no-print-directory $@ %65: - @$(MAKE) -C src --no-print-directory $@ + @$(MAKE) -C src --no-print-directory $@ %: - @$(MAKE) -C libsrc --no-print-directory $@ + @$(MAKE) -C libsrc --no-print-directory $@ + +checkprefix: +ifndef PREFIX + $(warning Warning: PREFIX is empty - make install will not work) +endif # check the code style checkstyle: diff --git a/src/Makefile b/src/Makefile index bdeaf4bc9..366e50183 100644 --- a/src/Makefile +++ b/src/Makefile @@ -101,6 +101,11 @@ ifdef CROSS_COMPILE endif all bin: $(PROGS) +ifeq ($(MAKELEVEL),0) +ifndef PREFIX + $(warning Warning: PREFIX is empty - make install will not work) +endif +endif mostlyclean: $(call RMDIR,../wrk) From cb4cd114bf4524fffebb0171e1fa4e053115db28 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 22:48:03 +0200 Subject: [PATCH 678/707] handle -s correctly when using these makefiles directly --- targettest/Makefile | 9 ++++++--- test/asm/cpudetect/Makefile | 3 +++ test/asm/err/Makefile | 4 ++++ test/asm/listing/Makefile | 4 ++++ test/asm/misc/Makefile | 4 ++++ test/asm/opcodes/Makefile | 4 ++++ test/asm/val/Makefile | 4 ++++ test/dasm/Makefile | 4 ++++ test/err/Makefile | 4 ++++ test/misc/Makefile | 4 ++++ test/ref/Makefile | 4 ++++ test/standard/Makefile | 4 ++++ test/standard_err/Makefile | 4 ++++ test/todo/Makefile | 4 ++++ test/val/Makefile | 4 ++++ 15 files changed, 61 insertions(+), 3 deletions(-) diff --git a/targettest/Makefile b/targettest/Makefile index 38b44035e..2b9732c67 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -55,6 +55,9 @@ ifdef QUIET .SILENT: PQ = "QUIET=1" PD = --no-print-directory +ifndef CMD_EXE + CATERR = 2> $$@.errlog || (cat $$@.errlog && false) +endif endif ifneq ($(filter disk testcode.%,$(MAKECMDGOALS)),) @@ -131,12 +134,12 @@ DISK_atarixl = testcode.atr .c.o: $(if $(QUIET),echo $(SYS):$*.c) - $(CC) $(CFLAGS) -Ors --codesize 500 -T -g -t $(SYS) $< - $(AS) $(<:.c=.s) + $(CC) $(CFLAGS) -Ors --codesize 500 -T -g -t $(SYS) $< $(CATERR) + $(AS) $(<:.c=.s) $(CATERR) .s.o: $(if $(QUIET),echo $(SYS):$*.s) - $(AS) $(ASFLAGS) -t $(SYS) $< + $(AS) $(ASFLAGS) -t $(SYS) $< $(CATERR) .PRECIOUS: %.o diff --git a/test/asm/cpudetect/Makefile b/test/asm/cpudetect/Makefile index d0077bfd9..27724b9f9 100644 --- a/test/asm/cpudetect/Makefile +++ b/test/asm/cpudetect/Makefile @@ -20,6 +20,9 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif ifdef QUIET .SILENT: diff --git a/test/asm/err/Makefile b/test/asm/err/Makefile index 8b93cd80d..9b6bc7fa9 100644 --- a/test/asm/err/Makefile +++ b/test/asm/err/Makefile @@ -24,6 +24,10 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/asm/listing/Makefile b/test/asm/listing/Makefile index dc2c43d73..202a44011 100644 --- a/test/asm/listing/Makefile +++ b/test/asm/listing/Makefile @@ -28,6 +28,10 @@ else NULLDEV = /dev/null endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/asm/misc/Makefile b/test/asm/misc/Makefile index 3072fa24e..713d57812 100644 --- a/test/asm/misc/Makefile +++ b/test/asm/misc/Makefile @@ -26,6 +26,10 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/asm/opcodes/Makefile b/test/asm/opcodes/Makefile index 2fe046bd9..e9978ee95 100644 --- a/test/asm/opcodes/Makefile +++ b/test/asm/opcodes/Makefile @@ -20,6 +20,10 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/asm/val/Makefile b/test/asm/val/Makefile index fe27f97d1..41df980a9 100644 --- a/test/asm/val/Makefile +++ b/test/asm/val/Makefile @@ -22,6 +22,10 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/dasm/Makefile b/test/dasm/Makefile index 196975857..b86a75416 100644 --- a/test/dasm/Makefile +++ b/test/dasm/Makefile @@ -22,6 +22,10 @@ else NULLDEV = /dev/null endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/err/Makefile b/test/err/Makefile index 5bd198477..60780d27b 100644 --- a/test/err/Makefile +++ b/test/err/Makefile @@ -24,6 +24,10 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/misc/Makefile b/test/misc/Makefile index 8eb360e52..6a5611c68 100644 --- a/test/misc/Makefile +++ b/test/misc/Makefile @@ -26,6 +26,10 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/ref/Makefile b/test/ref/Makefile index 1a5611083..4269c3879 100644 --- a/test/ref/Makefile +++ b/test/ref/Makefile @@ -27,6 +27,10 @@ else COPY = cp $1 $2 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/standard/Makefile b/test/standard/Makefile index f09024b58..903b34221 100644 --- a/test/standard/Makefile +++ b/test/standard/Makefile @@ -22,6 +22,10 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/standard_err/Makefile b/test/standard_err/Makefile index 702ad3f95..989d26d6f 100644 --- a/test/standard_err/Makefile +++ b/test/standard_err/Makefile @@ -24,6 +24,10 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/todo/Makefile b/test/todo/Makefile index 7a0cbfa54..efaca3a25 100644 --- a/test/todo/Makefile +++ b/test/todo/Makefile @@ -24,6 +24,10 @@ else RMDIR = $(RM) -r $1 endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) diff --git a/test/val/Makefile b/test/val/Makefile index 1f6f0ba4c..13b4ca4bd 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -24,6 +24,10 @@ else CATRES = > $(WORKDIR)/$$@.out 2> $(WORKDIR)/$$@.out || (cat $(WORKDIR)/$$@.out && false) endif +ifeq ($(SILENT),s) + QUIET = 1 +endif + ifdef QUIET .SILENT: NULLOUT = >$(NULLDEV) From 13878070e581fd1760da9bea1d1b0a92f5ec82c9 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Sun, 29 Jun 2025 23:24:04 +0200 Subject: [PATCH 679/707] don't check prefix on "zip" --- Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 54cdb53de..1f7af1087 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ endif .SUFFIXES: -all zip: +all: @$(MAKE) -C src --no-print-directory $@ @$(MAKE) -C libsrc --no-print-directory $@ @$(MAKE) -C doc --no-print-directory $@ @@ -16,6 +16,13 @@ all zip: @$(MAKE) -C samples --no-print-directory $@ @$(MAKE) checkprefix --no-print-directory +zip: + @$(MAKE) -C src --no-print-directory $@ + @$(MAKE) -C libsrc --no-print-directory $@ + @$(MAKE) -C doc --no-print-directory $@ + @$(MAKE) -C util --no-print-directory $@ + @$(MAKE) -C samples --no-print-directory $@ + install: ifndef PREFIX $(error Error: PREFIX must be set for install to work) From 483ef7844b3410c6c53708f1413570cb72a07596 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Mon, 30 Jun 2025 16:03:36 +0200 Subject: [PATCH 680/707] also test DESTDIR --- Makefile | 8 ++++++-- src/Makefile | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 1f7af1087..222fea5ac 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,9 @@ zip: install: ifndef PREFIX - $(error Error: PREFIX must be set for install to work) +ifndef DESTDIR + $(error Error: PREFIX or DESTDIR must be set for install to work) +endif endif @$(MAKE) -C src --no-print-directory $@ @$(MAKE) -C libsrc --no-print-directory $@ @@ -73,7 +75,9 @@ util: checkprefix: ifndef PREFIX - $(warning Warning: PREFIX is empty - make install will not work) +ifndef DESTDIR + $(warning Warning: PREFIX and DESTDIR are empty - make install will not work) +endif endif # check the code style diff --git a/src/Makefile b/src/Makefile index 366e50183..f652f6925 100644 --- a/src/Makefile +++ b/src/Makefile @@ -103,7 +103,9 @@ endif all bin: $(PROGS) ifeq ($(MAKELEVEL),0) ifndef PREFIX - $(warning Warning: PREFIX is empty - make install will not work) +ifndef DESTDIR + $(warning Warning: PREFIX and DESTDIR are empty - make install will not work) +endif endif endif From a4a24280f26ddb3e319678db7a531320df7125fe Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Mon, 30 Jun 2025 20:50:30 +0200 Subject: [PATCH 681/707] Do only check .c and .h files. --- .github/checks/sorted.sh | 4 ++-- .github/checks/sorted_codeopt.sh | 4 ++-- .github/checks/sorted_opcodes.sh | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/checks/sorted.sh b/.github/checks/sorted.sh index b5451a21f..e15c04475 100755 --- a/.github/checks/sorted.sh +++ b/.github/checks/sorted.sh @@ -33,7 +33,7 @@ function checkarray_quoted_name } -for N in `grep -rl "BEGIN SORTED.SH" "$CHECK_DIR"`; do - checkarray_quoted_name $N +find "$CHECK_DIR" -name \*.\[ch\] -print | while read N; do + grep -q "BEGIN SORTED.SH" "$N" && checkarray_quoted_name "$N" done exit 0 diff --git a/.github/checks/sorted_codeopt.sh b/.github/checks/sorted_codeopt.sh index cfca028dd..370bbfc9f 100755 --- a/.github/checks/sorted_codeopt.sh +++ b/.github/checks/sorted_codeopt.sh @@ -64,6 +64,6 @@ function checkarray find "$CHECK_DIR" -name \*.\[ch\] -print | while read N; do - grep -q "BEGIN DECL SORTED_CODEOPT.SH" "$N" && checkarray $N + grep -q "BEGIN DECL SORTED_CODEOPT.SH" "$N" && checkarray "$N" done -exit 0 +exit 0 diff --git a/.github/checks/sorted_opcodes.sh b/.github/checks/sorted_opcodes.sh index 34156bde6..8f8764c6a 100755 --- a/.github/checks/sorted_opcodes.sh +++ b/.github/checks/sorted_opcodes.sh @@ -34,7 +34,7 @@ function checkarray_quoted_name rm -rf .a.tmp } -for N in `grep -rl "BEGIN SORTED_OPCODES.SH" "$CHECK_DIR"`; do - checkarray_quoted_name $N +find "$CHECK_DIR" -name \*.\[ch\] -print | while read N; do + grep -q "BEGIN SORTED_OPCODES.SH" "$N" && checkarray_quoted_name "$N" done exit 0 From d4e57278c6f9ce681dc8c263616157226c76cd2f Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Mon, 30 Jun 2025 21:37:43 +0200 Subject: [PATCH 682/707] Add a new .cap pseudo function to the assembler that allows to check for certain capabilities of the CPU or target system. --- doc/ca65.sgml | 54 +++++++++++ src/ca65/expr.c | 76 ++++++++++++++-- src/ca65/pseudo.c | 4 +- src/ca65/scanner.c | 2 + src/ca65/token.h | 1 + src/common/capability.c | 90 +++++++++++++++++++ src/common/capability.h | 78 ++++++++++++++++ src/common/cpu.c | 82 +++++++++++++++++ src/common/cpu.h | 8 ++ test/asm/listing/110-capabilities.s | 39 ++++++++ test/asm/listing/control/110-capabilities.err | 0 .../asm/listing/ref/110-capabilities.err2-ref | 6 ++ 12 files changed, 434 insertions(+), 6 deletions(-) create mode 100644 src/common/capability.c create mode 100644 src/common/capability.h create mode 100644 test/asm/listing/110-capabilities.s create mode 100644 test/asm/listing/control/110-capabilities.err create mode 100644 test/asm/listing/ref/110-capabilities.err2-ref diff --git a/doc/ca65.sgml b/doc/ca65.sgml index b7e8539af..552309ff9 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1423,6 +1423,10 @@ writable. </verb></tscreen> + See also: <tt><ref id=".CAP" name=".CAP"></tt> + + + <sect1><tt>.ISIZE</tt><label id=".ISIZE"><p> Reading this pseudo variable will return the current size of the Index @@ -1594,6 +1598,56 @@ either a string or an expression value. +<sect1><tt>.CAP, .CAPABILITY</tt><label id=".CAP"><p> + + Builtin function. The function allows to check for capabilities of the + currently selected CPU or target system. It must be called with a comma + separated list of identifiers and returns non zero if all of the given + capabilities are available. Otherwise it returns zero. + + Existing capabilities are: + +<descrip> + + <tag><tt>CPU_HAS_BRA8</tt></tag> + Checks for the availability of a short (8 bit) branch. + + <tag><tt>CPU_HAS_INA</tt></tag> + Checks for the availability of accu inc/dec instructions. + + <tag><tt>CPU_HAS_PUSHXY</tt></tag> + Checks for the capability to push and pop the X and Y registers. + + <tag><tt>CPU_HAS_ZPIND</tt></tag> + Checks for the availability of the "zeropage indirect" addressing mode. + + <tag><tt>CPU_HAS_STZ</tt></tag> + Checks for the availability of the "store zero" instruction. + +</descrip> + + Case is ignored when checking the identifiers. The <tt/.cap/ function is + easier to use than checking <tt/.cpu/ and requires no intimate knowledge + of all instruction sets. For more detailed checking <tt/.cpu/ is still + available. + + Example: + + <tscreen><verb> + .if .cap(CPU_HAS_BRA, CPU_HAS_PUSHXY) + phx + bra L1 + .else + txa + pha + jmp L1 + .endif + </verb></tscreen> + + See also: <tt><ref id=".CPU" name=".CPU"></tt> + + + <sect1><tt>.CONCAT</tt><label id=".CONCAT"><p> Builtin string function. The function allows to concatenate a list of string diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 5dcf5ca71..42b1a369b 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -37,6 +37,7 @@ #include <time.h> /* common */ +#include "capability.h" #include "check.h" #include "cpu.h" #include "exprdefs.h" @@ -405,6 +406,66 @@ static ExprNode* FuncBlank (void) +static ExprNode* FuncCapability (void) +/* Handle the .CAPABILITY builtin function */ +{ + int Result = 1; + + /* What follows is a comma separated list of identifiers. An empty list is + ** not allowed. + */ + while (1) { + + const char* Name; + capability_t Cap; + + /* We must have an identifier */ + if (CurTok.Tok != TOK_IDENT) { + Error ("Arguments to .CAPABILITY must be identifiers"); + /* Skip tokens until closing paren or end of line */ + while (CurTok.Tok != TOK_RPAREN && !TokIsSep (CurTok.Tok)) { + NextTok (); + } + return GenLiteral0 (); + } + + /* Search for the capability that matches this identifier. Ignore case + ** on the specified capabilities. + */ + UpcaseSVal (); + SB_Terminate (&CurTok.SVal); + Name = SB_GetConstBuf (&CurTok.SVal); + Cap = FindCapability (Name); + + /* Check if the capability is supported */ + if (Cap == CAP_INVALID) { + Error ("Not a valid capability name: %s", Name); + Result = 0; + } else { + /* The pseudo function result is the logical AND of all capabilities + ** given. + */ + if (!CPUHasCap (Cap)) { + Result = 0; + } + } + + /* Skip the capability name */ + NextTok (); + + /* Handle end of list or next capability */ + if (CurTok.Tok != TOK_COMMA) { + break; + } + NextTok (); + } + + /* Done */ + return GenLiteralExpr (Result); +} + + + static ExprNode* FuncConst (void) /* Handle the .CONST builtin function */ { @@ -484,9 +545,10 @@ static ExprNode* FuncIsMnemonic (void) if (FindMacro (&CurTok.SVal) == 0) { Instr = FindInstruction (&CurTok.SVal); } - } - else { - /* Macros and symbols may NOT use the names of instructions, so just check for the instruction */ + } else { + /* Macros and symbols may NOT use the names of instructions, so + ** just check for the instruction. + */ Instr = FindInstruction (&CurTok.SVal); } } @@ -532,7 +594,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel) token_t Term = GetTokListTerm (TOK_COMMA); while (CurTok.Tok != Term) { - /* We may not end-of-line of end-of-file here */ + /* We may not end-of-line or end-of-file here */ if (TokIsSep (CurTok.Tok)) { Error ("Unexpected end of line"); return GenLiteral0 (); @@ -570,7 +632,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel) Node = Root; while (CurTok.Tok != Term) { - /* We may not end-of-line of end-of-file here */ + /* We may not end-of-line or end-of-file here */ if (TokIsSep (CurTok.Tok)) { Error ("Unexpected end of line"); return GenLiteral0 (); @@ -1129,6 +1191,10 @@ static ExprNode* Factor (void) N = Function (FuncBlank); break; + case TOK_CAP: + N = Function (FuncCapability); + break; + case TOK_CONST: N = Function (FuncConst); break; diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index e6e10df2c..301129583 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -2114,7 +2114,8 @@ struct CtrlDesc { }; /* NOTE: .AND, .BITAND, .BITNOT, .BITOR, .BITXOR, .MOD, .NOT, .OR, .SHL, .SHR - and .XOR do NOT go into this table */ +** and .XOR do NOT go into this table. +*/ #define PSEUDO_COUNT (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0])) static CtrlDesc CtrlCmdTab [] = { { ccNone, DoA16 }, /* .A16 */ @@ -2132,6 +2133,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoUnexpected }, /* .BLANK */ { ccNone, DoBss }, /* .BSS */ { ccNone, DoByte }, /* .BYT, .BYTE */ + { ccNone, DoUnexpected }, /* .CAP */ { ccNone, DoCase }, /* .CASE */ { ccNone, DoCharMap }, /* .CHARMAP */ { ccNone, DoCode }, /* .CODE */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index f3892d32e..a2a72a149 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -158,6 +158,8 @@ struct DotKeyword { { ".BSS", TOK_BSS }, { ".BYT", TOK_BYTE }, { ".BYTE", TOK_BYTE }, + { ".CAP", TOK_CAP }, + { ".CAPABILITY", TOK_CAP }, { ".CASE", TOK_CASE }, { ".CHARMAP", TOK_CHARMAP }, { ".CODE", TOK_CODE }, diff --git a/src/ca65/token.h b/src/ca65/token.h index e2b223880..b40534d79 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -137,6 +137,7 @@ typedef enum token_t { TOK_BLANK, TOK_BSS, TOK_BYTE, + TOK_CAP, TOK_CASE, TOK_CHARMAP, TOK_CODE, diff --git a/src/common/capability.c b/src/common/capability.c new file mode 100644 index 000000000..f66205e7c --- /dev/null +++ b/src/common/capability.c @@ -0,0 +1,90 @@ +/*****************************************************************************/ +/* */ +/* capability.c */ +/* */ +/* Handle CPU or target capabilities */ +/* */ +/* */ +/* */ +/* (C) 2026, Kugelfuhr */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include <stdlib.h> + +/* ca65 */ +#include "capability.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* List of dot keywords with the corresponding ids. */ +/* CAUTION: table must be sorted for bsearch. */ +struct Capability { + const char* Key; + capability_t Cap; +} Capabilities [] = { +/* BEGIN SORTED.SH */ + { "CPU_HAS_BRA8", CAP_CPU_HAS_BRA8 }, + { "CPU_HAS_INA", CAP_CPU_HAS_INA }, + { "CPU_HAS_PUSHXY", CAP_CPU_HAS_PUSHXY }, + { "CPU_HAS_STZ", CAP_CPU_HAS_STZ }, + { "CPU_HAS_ZPIND", CAP_CPU_HAS_ZPIND }, +/* END SORTED.SH */ +}; +#define CAP_TABLE_SIZE (sizeof (Capabilities) / sizeof (Capabilities [0])) + + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static int CmpCapability (const void* K1, const void* K2) +/* Compare function for the capability search */ +{ + return strcmp (((struct Capability*)K1)->Key, ((struct Capability*)K2)->Key); +} + + + +capability_t FindCapability (const char* Name) +/* Find the capability with the given name. Returns CAP_INVALID if there is no +** capability with the given name and a capability code >= 0 instead. The +** capability name is expected in upper case. +*/ +{ + const struct Capability K = { Name, 0 }; + const struct Capability* C = bsearch (&K, Capabilities, CAP_TABLE_SIZE, + sizeof (Capabilities [0]), + CmpCapability); + return (C == 0)? CAP_INVALID : C->Cap; +} diff --git a/src/common/capability.h b/src/common/capability.h new file mode 100644 index 000000000..011e2164f --- /dev/null +++ b/src/common/capability.h @@ -0,0 +1,78 @@ +/*****************************************************************************/ +/* */ +/* capability.h */ +/* */ +/* Handle CPU or target capabilities */ +/* */ +/* */ +/* */ +/* (C) 2026, Kugelfuhr */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef CAPABILITY_H +#define CAPABILITY_H + + + +/* common */ +#include "strbuf.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Numeric codes for capabilities */ +enum capability_t { + CAP_INVALID = -1, + CAP_CPU_HAS_BRA8 = 0, /* CPU has a BRA 8-bit instruction */ + CAP_CPU_HAS_INA = 1, /* CPU has DEA/INA */ + CAP_CPU_HAS_PUSHXY = 2, /* CPU has PHX/PHY/PLX/PLY */ + CAP_CPU_HAS_ZPIND = 3, /* CPU has "(zp)" mode (no offset) */ + CAP_CPU_HAS_STZ = 4, /* CPU has "store zero" (!) instruction */ +}; +typedef enum capability_t capability_t; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +capability_t FindCapability (const char* Name); +/* Find the capability with the given name. Returns CAP_INVALID if there is no +** capability with the given name and a capability code >= 0 instead. The +** capability name is expected in upper case. +*/ + + + +/* End of capability.h */ + +#endif diff --git a/src/common/cpu.c b/src/common/cpu.c index 252283211..cdc8e52cc 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -33,6 +33,8 @@ +#include <stdint.h> + /* common */ #include "addrsize.h" #include "check.h" @@ -90,6 +92,77 @@ const unsigned CPUIsets[CPU_COUNT] = { CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; +/* Defines for capabilities. Currently the entries are uint32_ts but the table +** is deliberately hidden from the outside so it can be extended to 64 bit or +** even more. +*/ +#define CAP_NONE UINT32_C (0) +#define CAP_6502 UINT32_C (0) +#define CAP_6502X UINT32_C (0) +#define CAP_6502DTV UINT32_C (0) +#define CAP_65SC02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_65C02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_65816 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_SWEET16 UINT32_C (0) +#define CAP_HUC6280 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ + (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ + (UINT32_C (1) << CAP_CPU_HAS_STZ)) +#define CAP_M740 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA)) +#define CAP_4510 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_45GS02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_W65C02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) +#define CAP_65CE02 \ + ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ + (UINT32_C (1) << CAP_CPU_HAS_INA) | \ + (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + +/* Table containing one capability entry per CPU */ +static const uint64_t CPUCaps[CPU_COUNT] = { + CAP_NONE, /* CPU_NONE */ + CAP_6502, /* CPU_6502 */ + CAP_6502X, /* CPU_6502X */ + CAP_6502DTV, /* CPU_6502DTV */ + CAP_65SC02, /* CPU_65SC02 */ + CAP_65C02, /* CPU_65C02 */ + CAP_65816, /* CPU_65816 */ + CAP_SWEET16, /* CPU_SWEET16 */ + CAP_HUC6280, /* CPU_HUC6280 */ + CAP_M740, /* CPU_M740 */ + CAP_4510, /* CPU_4510 */ + CAP_45GS02, /* CPU_45GS02 */ + CAP_W65C02, /* CPU_W65C02 */ + CAP_65CE02, /* CPU_65CE02 */ +}; + /*****************************************************************************/ @@ -148,3 +221,12 @@ cpu_t FindCPU (const char* Name) /* Not found */ return CPU_UNKNOWN; } + + + +int CPUHasCap (capability_t Cap) +/* Check if the current CPU has the given capability */ +{ + PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); + return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; +} diff --git a/src/common/cpu.h b/src/common/cpu.h index 4202ed573..0a7c853ac 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -38,6 +38,11 @@ +/* common */ +#include "capability.h" + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -107,6 +112,9 @@ cpu_t FindCPU (const char* Name); ** the given name is no valid target. */ +int CPUHasCap (capability_t Cap); +/* Check if the current CPU has the given capability */ + /* End of cpu.h */ diff --git a/test/asm/listing/110-capabilities.s b/test/asm/listing/110-capabilities.s new file mode 100644 index 000000000..e3e306ca7 --- /dev/null +++ b/test/asm/listing/110-capabilities.s @@ -0,0 +1,39 @@ + +; Error: Arguments to .CAPABILITY must be identifiers +.if .cap() +.endif + +; Error: Arguments to .CAPABILITY must be identifiers +; Error: ')' expected +.if .cap( +.endif + +; Error: Not a valid capability name: CPU_HAS_BR +.if .cap(cpu_has_br) +.endif + +; Error: ')' expected +; Error: Unexpected trailing garbage characters +.if .cap(cpu_has_bra8 cpu_has_bra8) +.endif + +; Ok +.if .cap(cpu_has_bra8, CPU_HAS_PUSHXY, CPU_HAS_STZ, CPU_HAS_INA) +.endif + +.setcpu "65SC02" +.if !.cap(cpu_has_bra8) +.error "Assembler says 65SC02 has no 8 bit bra" +.endif +.if !.cap(cpu_has_PUSHXY) +.error "Assembler says 65SC02 has no phx" +.endif +.if !.cap(cpu_has_STZ) +.error "Assembler says 65SC02 has no stz" +.endif +.if !.cap(cpu_has_INA) +.error "Assembler says 65SC02 has no ina" +.endif + + + diff --git a/test/asm/listing/control/110-capabilities.err b/test/asm/listing/control/110-capabilities.err new file mode 100644 index 000000000..e69de29bb diff --git a/test/asm/listing/ref/110-capabilities.err2-ref b/test/asm/listing/ref/110-capabilities.err2-ref new file mode 100644 index 000000000..e00e60e17 --- /dev/null +++ b/test/asm/listing/ref/110-capabilities.err2-ref @@ -0,0 +1,6 @@ +110-capabilities.s:3: Error: Arguments to .CAPABILITY must be identifiers +110-capabilities.s:8: Error: Arguments to .CAPABILITY must be identifiers +110-capabilities.s:8: Error: ')' expected +110-capabilities.s:12: Error: Not a valid capability name: CPU_HAS_BR +110-capabilities.s:17: Error: ')' expected +110-capabilities.s:17: Error: Unexpected trailing garbage characters From f333b300f1c542b952580420259f6d79db7977f1 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:16:33 +0200 Subject: [PATCH 683/707] Added the CPU_HAS_BITIMM capability. --- doc/ca65.sgml | 3 ++ src/common/capability.c | 1 + src/common/capability.h | 1 + src/common/cpu.c | 81 ++++++++++++++++++++++------------------- 4 files changed, 48 insertions(+), 38 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 552309ff9..cfe73a2f0 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1609,6 +1609,9 @@ either a string or an expression value. <descrip> + <tag><tt>CPU_HAS_BITIMM</tt></tag> + Checks for the availability of the "bit #imm" instruction. + <tag><tt>CPU_HAS_BRA8</tt></tag> Checks for the availability of a short (8 bit) branch. diff --git a/src/common/capability.c b/src/common/capability.c index f66205e7c..19c3ed838 100644 --- a/src/common/capability.c +++ b/src/common/capability.c @@ -50,6 +50,7 @@ struct Capability { capability_t Cap; } Capabilities [] = { /* BEGIN SORTED.SH */ + { "CPU_HAS_BITIMM", CAP_CPU_HAS_BITIMM }, { "CPU_HAS_BRA8", CAP_CPU_HAS_BRA8 }, { "CPU_HAS_INA", CAP_CPU_HAS_INA }, { "CPU_HAS_PUSHXY", CAP_CPU_HAS_PUSHXY }, diff --git a/src/common/capability.h b/src/common/capability.h index 011e2164f..b0332c72e 100644 --- a/src/common/capability.h +++ b/src/common/capability.h @@ -54,6 +54,7 @@ enum capability_t { CAP_CPU_HAS_PUSHXY = 2, /* CPU has PHX/PHY/PLX/PLY */ CAP_CPU_HAS_ZPIND = 3, /* CPU has "(zp)" mode (no offset) */ CAP_CPU_HAS_STZ = 4, /* CPU has "store zero" (!) instruction */ + CAP_CPU_HAS_BITIMM = 5, /* CPU has "bit #imm" instruction */ }; typedef enum capability_t capability_t; diff --git a/src/common/cpu.c b/src/common/cpu.c index cdc8e52cc..d8c0dbd37 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -96,54 +96,59 @@ const unsigned CPUIsets[CPU_COUNT] = { ** is deliberately hidden from the outside so it can be extended to 64 bit or ** even more. */ +#define CAP_BIT(Cap) (UINT32_C (1) << (Cap)) #define CAP_NONE UINT32_C (0) -#define CAP_6502 UINT32_C (0) -#define CAP_6502X UINT32_C (0) -#define CAP_6502DTV UINT32_C (0) +#define CAP_6502 CAP_NONE +#define CAP_6502X CAP_NONE +#define CAP_6502DTV CAP_NONE #define CAP_65SC02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_65C02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_65816 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) -#define CAP_SWEET16 UINT32_C (0) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) +#define CAP_SWEET16 CAP_NONE #define CAP_HUC6280 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY) | \ - (UINT32_C (1) << CAP_CPU_HAS_ZPIND) | \ - (UINT32_C (1) << CAP_CPU_HAS_STZ)) + (CAP_BIT (CAP_CPU_HAS_BITIMM) | \ + CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY) | \ + CAP_BIT (CAP_CPU_HAS_ZPIND) | \ + CAP_BIT (CAP_CPU_HAS_STZ)) #define CAP_M740 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA)) #define CAP_4510 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_45GS02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_W65C02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) #define CAP_65CE02 \ - ((UINT32_C (1) << CAP_CPU_HAS_BRA8) | \ - (UINT32_C (1) << CAP_CPU_HAS_INA) | \ - (UINT32_C (1) << CAP_CPU_HAS_PUSHXY)) + (CAP_BIT (CAP_CPU_HAS_BRA8) | \ + CAP_BIT (CAP_CPU_HAS_INA) | \ + CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ static const uint64_t CPUCaps[CPU_COUNT] = { From c72126e68fc879229b677baf6443ed242b0262f7 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:25:32 +0200 Subject: [PATCH 684/707] Changed most of the library sources to use .CAP instead of .CPU. --- libsrc/cbm/clock.s | 3 +- libsrc/common/_directerrno.s | 4 +- libsrc/common/_heapblocksize.s | 3 +- libsrc/common/_mappederrno.s | 3 +- libsrc/common/_printf.s | 11 ++--- libsrc/common/_time_t_to_tm.s | 4 +- libsrc/common/asctime.s | 6 +-- libsrc/common/atexit.s | 10 ++-- libsrc/common/fgetc.s | 4 +- libsrc/common/fgets.s | 8 ++-- libsrc/common/fread.s | 15 +++--- libsrc/common/fwrite.s | 6 +-- libsrc/common/ltoa.s | 4 +- libsrc/common/strcat.s | 3 +- libsrc/common/strchr.s | 3 +- libsrc/common/strdup.s | 4 +- libsrc/common/strncat.s | 83 +++++++++++++++++----------------- libsrc/conio/cputs.s | 5 +- libsrc/conio/scrsize.s | 4 +- libsrc/conio/vcprintf.s | 3 +- libsrc/runtime/add.s | 4 +- libsrc/runtime/and.s | 4 +- libsrc/runtime/condes.s | 2 - libsrc/runtime/incax1.s | 3 +- libsrc/runtime/incsp2.s | 4 +- libsrc/runtime/ladd.s | 4 +- libsrc/runtime/laddeq.s | 4 +- libsrc/runtime/land.s | 6 +-- libsrc/runtime/ldau0sp.s | 4 +- libsrc/runtime/leave.s | 4 +- libsrc/runtime/lmod.s | 4 +- libsrc/runtime/lmul.s | 6 +-- libsrc/runtime/lor.s | 6 +-- libsrc/runtime/lpop.s | 4 +- libsrc/runtime/lpush.s | 6 +-- libsrc/runtime/lrsub.s | 6 +-- libsrc/runtime/lsub.s | 6 +-- libsrc/runtime/lsubeq.s | 4 +- libsrc/runtime/ludiv.s | 6 +-- libsrc/runtime/lumod.s | 4 +- libsrc/runtime/lxor.s | 6 +-- libsrc/runtime/or.s | 4 +- libsrc/runtime/popa.s | 4 +- libsrc/runtime/popptr1.s | 4 +- libsrc/runtime/popsreg.s | 4 +- libsrc/runtime/pusha.s | 2 - libsrc/runtime/pushax.s | 4 +- libsrc/runtime/pushb.s | 4 +- libsrc/runtime/rsub.s | 4 +- libsrc/runtime/shl.s | 4 +- libsrc/runtime/staxspi.s | 4 +- libsrc/runtime/stkchk.s | 3 +- libsrc/runtime/sub.s | 4 +- libsrc/runtime/swap.s | 4 +- libsrc/runtime/tosint.s | 4 +- libsrc/runtime/toslong.s | 6 +-- libsrc/runtime/umul8x16r24.s | 4 +- libsrc/runtime/xor.s | 4 +- libsrc/tgi/tgi_settextstyle.s | 4 +- 59 files changed, 122 insertions(+), 232 deletions(-) diff --git a/libsrc/cbm/clock.s b/libsrc/cbm/clock.s index 90e4263a8..91fde6f58 100644 --- a/libsrc/cbm/clock.s +++ b/libsrc/cbm/clock.s @@ -9,14 +9,13 @@ .importzp sreg .include "cbm.inc" - .macpack cpu .proc _clock ; Some accelerator adaptors have CMOS ICs. -.if (.cpu & ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg + 1 .else lda #$00 ; Byte 3 always is zero diff --git a/libsrc/common/_directerrno.s b/libsrc/common/_directerrno.s index 20060bdd7..74e2f89cd 100644 --- a/libsrc/common/_directerrno.s +++ b/libsrc/common/_directerrno.s @@ -7,8 +7,6 @@ .include "errno.inc" - .macpack cpu - ; ---------------------------------------------------------------------------- ; int __fastcall__ __directerrno (unsigned char code); ; /* Set errno to a specific error code, clear __oserror, and return -1. Used @@ -18,7 +16,7 @@ ___directerrno: jsr ___seterrno ; Set errno (returns with .A = 0) sta ___oserror ; Clear ___oserror -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) dec a .else lda #$FF ; Return -1 diff --git a/libsrc/common/_heapblocksize.s b/libsrc/common/_heapblocksize.s index e9b0cdad9..774056032 100644 --- a/libsrc/common/_heapblocksize.s +++ b/libsrc/common/_heapblocksize.s @@ -12,7 +12,6 @@ .include "_heap.inc" .macpack generic - .macpack cpu ;----------------------------------------------------------------------------- ; Code @@ -39,7 +38,7 @@ ___heapblocksize: ldy #usedblock::size+1 lda (ptr2),y tax -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr2) .else dey diff --git a/libsrc/common/_mappederrno.s b/libsrc/common/_mappederrno.s index 83565b723..4ea3174b6 100644 --- a/libsrc/common/_mappederrno.s +++ b/libsrc/common/_mappederrno.s @@ -8,7 +8,6 @@ .include "errno.inc" .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- ; int __fastcall__ __mappederrno (unsigned char code); @@ -24,7 +23,7 @@ ___mappederrno: bze ok ; Branch if no jsr ___osmaperrno ; Map OS error into errno code jsr ___seterrno ; Save in errno (returns with .A = 0) -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) dec a .else lda #$FF ; Return -1 if error diff --git a/libsrc/common/_printf.s b/libsrc/common/_printf.s index 40ab0bc64..335485cc6 100644 --- a/libsrc/common/_printf.s +++ b/libsrc/common/_printf.s @@ -13,7 +13,6 @@ .import _strlower, _strlen .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- ; We will store variables into the register bank in the zeropage. Define @@ -38,7 +37,7 @@ FCount = ptr2 GetFormatChar: ldy #0 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (Format) .else lda (Format),y @@ -115,7 +114,7 @@ GetIntArg: lda (ArgList),y tax dey - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (ArgList) .else lda (ArgList),y @@ -274,7 +273,7 @@ Save: lda regbank,y ; Initialize the output counter in the output descriptor to zero lda #0 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (OutData) ldy #$01 sta (OutData),y @@ -353,7 +352,7 @@ MainLoop: sta (c_sp),y dey lda FCount - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (c_sp) .else sta (c_sp),y @@ -570,7 +569,7 @@ CheckCount: jsr GetIntArg sta ptr1 stx ptr1+1 ; Get user supplied pointer - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (OutData) ; Low byte of OutData->ccount sta (ptr1) ldy #1 diff --git a/libsrc/common/_time_t_to_tm.s b/libsrc/common/_time_t_to_tm.s index 9bcf84184..21e662384 100644 --- a/libsrc/common/_time_t_to_tm.s +++ b/libsrc/common/_time_t_to_tm.s @@ -16,8 +16,6 @@ .include "time.inc" - .macpack cpu - __time_t_to_tm: ; Divide number of seconds since epoch, in ptr1:sreg, ; by 86400 to get the number of days since epoch, and @@ -80,7 +78,7 @@ __time_t_to_tm: ; Zero the two high bytes of the divisor and the high byte ; of the dividend. - .if .cpu .bitand CPU_ISET_65SC02 + .if .cap(CPU_HAS_STZ) stz ptr4 stz ptr4+1 stz sreg+1 diff --git a/libsrc/common/asctime.s b/libsrc/common/asctime.s index efcf34b41..b56371594 100644 --- a/libsrc/common/asctime.s +++ b/libsrc/common/asctime.s @@ -9,8 +9,6 @@ .importzp ptr1 .include "time.inc" - .macpack cpu - ; ------------------------------------------------------------------------ ; Special values @@ -24,7 +22,7 @@ MAX_BUF_LEN = 38 _asctime: ; Backup timep - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_PUSHXY) pha phx .else @@ -48,7 +46,7 @@ _asctime: jsr pushax ; Restore timep - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_PUSHXY) plx pla .else diff --git a/libsrc/common/atexit.s b/libsrc/common/atexit.s index 47a1dfd4d..ccbc2e69f 100644 --- a/libsrc/common/atexit.s +++ b/libsrc/common/atexit.s @@ -10,8 +10,6 @@ .include "errno.inc" - .macpack cpu - ; --------------------------------------------------------------------------- .proc _atexit @@ -41,7 +39,7 @@ jsr ___seterrno ldx #$FF ; Return -1 txa - rts +Exit: rts .endproc @@ -54,7 +52,7 @@ .proc doatexit ldy exitfunc_index ; Get index - beq @L9 ; Jump if done + beq _atexit::Exit ; Jump if done dey lda exitfunc_table,y tax @@ -62,14 +60,12 @@ lda exitfunc_table,y sty exitfunc_index jsr callax ; Call the function -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_BRA8) bra doatexit .else jmp doatexit ; Next one .endif -@L9: rts - .endproc diff --git a/libsrc/common/fgetc.s b/libsrc/common/fgetc.s index 34d4df3aa..6d08f69a3 100644 --- a/libsrc/common/fgetc.s +++ b/libsrc/common/fgetc.s @@ -12,8 +12,6 @@ .include "stdio.inc" .include "_file.inc" - .macpack cpu - _fgetc: sta ptr1 stx ptr1+1 @@ -22,7 +20,7 @@ _fgetc: jsr checkferror bne ret_eof - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FPUSHBACK ; Check for pushed back char beq do_read .else diff --git a/libsrc/common/fgets.s b/libsrc/common/fgets.s index c25664f19..fde3a78a9 100644 --- a/libsrc/common/fgets.s +++ b/libsrc/common/fgets.s @@ -14,12 +14,10 @@ .include "stdio.inc" .include "_file.inc" - .macpack cpu - terminate_ptr: lda #$00 tax - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr4) .else tay @@ -41,7 +39,7 @@ _fgets: sta buf stx buf+1 - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_STZ) stz didread .else lda #$00 ; We have read nothing yet @@ -79,7 +77,7 @@ read_loop: ldy #$01 sty didread ; We read at least one char - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr4) .else dey diff --git a/libsrc/common/fread.s b/libsrc/common/fread.s index be06c2a62..beb9e707e 100644 --- a/libsrc/common/fread.s +++ b/libsrc/common/fread.s @@ -20,7 +20,6 @@ .include "_file.inc" .macpack generic - .macpack cpu ; ------------------------------------------------------------------------ ; Code @@ -48,7 +47,7 @@ ldy #_FILE::f_flags lda (file),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FOPEN ; Is the file open? .else and #_FOPEN ; Is the file open? @@ -57,7 +56,7 @@ ; Check if the stream is in an error state - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FERROR .else lda (file),y ; get file->f_flags again @@ -74,17 +73,15 @@ ; Remember if we have a pushed back character and reset the flag. -@L2: .if (.cpu .bitand ::CPU_ISET_65SC02) +@L2: .if .cap(CPU_HAS_BITIMM) ldx #$00 bit #_FPUSHBACK + beq @L3 .else tax ; X = 0 lda (file),y and #_FPUSHBACK - .endif beq @L3 - - .if (.not .cpu .bitand ::CPU_ISET_65SC02) lda (file),y .endif and #<~_FPUSHBACK @@ -135,7 +132,7 @@ ; Copy the buffer pointer into ptr1, and increment the pointer value passed ; to read() by one, so read() starts to store data at buf+1. - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) lda (c_sp) sta ptr1 add #1 @@ -159,7 +156,7 @@ ldy #_FILE::f_pushback lda (file),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) sta (ptr1) ; *buf = file->f_pushback; .else ldy #0 diff --git a/libsrc/common/fwrite.s b/libsrc/common/fwrite.s index e7151da95..6f631b816 100644 --- a/libsrc/common/fwrite.s +++ b/libsrc/common/fwrite.s @@ -16,8 +16,6 @@ .include "errno.inc" .include "_file.inc" - .macpack cpu - ; ------------------------------------------------------------------------ ; Code @@ -34,7 +32,7 @@ ldy #_FILE::f_flags lda (ptr1),y - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_BITIMM) bit #_FOPEN .else and #_FOPEN ; Is the file open? @@ -50,7 +48,7 @@ ; Check if the stream is in an error state -@L2: .if (.not .cpu .bitand ::CPU_ISET_65SC02) +@L2: .if .not .cap(CPU_HAS_BITIMM) lda (ptr1),y ; get file->f_flags again .endif and #_FERROR diff --git a/libsrc/common/ltoa.s b/libsrc/common/ltoa.s index 78e43e23f..7c31d471f 100644 --- a/libsrc/common/ltoa.s +++ b/libsrc/common/ltoa.s @@ -10,8 +10,6 @@ .import __hextab, __longminstr .importzp sreg, ptr1, ptr2, ptr3, tmp1 - .macpack cpu - .code ; @@ -64,7 +62,7 @@ L2: txa ; get high byte bpl ultoa lda #'-' -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (ptr2) .else ldy #0 diff --git a/libsrc/common/strcat.s b/libsrc/common/strcat.s index f9cd94633..963b037b9 100644 --- a/libsrc/common/strcat.s +++ b/libsrc/common/strcat.s @@ -8,7 +8,6 @@ .export _strcat .import popax .importzp ptr1, ptr2, tmp3 - .macpack cpu _strcat: sta ptr1 ; Save src @@ -16,7 +15,7 @@ _strcat: jsr popax ; Get dest sta tmp3 ; Remember for function return tay -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr2 .else lda #0 diff --git a/libsrc/common/strchr.s b/libsrc/common/strchr.s index 206b5160e..ac7f5397a 100644 --- a/libsrc/common/strchr.s +++ b/libsrc/common/strchr.s @@ -8,14 +8,13 @@ .export _strchr .import popax .importzp ptr1, tmp1 - .macpack cpu _strchr: sta tmp1 ; Save c jsr popax ; get s tay ; low byte of pointer to y stx ptr1+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr1 .else lda #0 diff --git a/libsrc/common/strdup.s b/libsrc/common/strdup.s index 94f2cd338..4cf643614 100644 --- a/libsrc/common/strdup.s +++ b/libsrc/common/strdup.s @@ -12,8 +12,6 @@ .import _strlen_ptr4, _malloc, _memcpy, pushax .export _strdup - .macpack cpu - _strdup: ; Get length (and store source in ptr4) sta ptr4 @@ -22,7 +20,7 @@ _strdup: jsr _strlen_ptr4 ; strlen may increment ; Add null byte for terminator -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) inc a .else clc diff --git a/libsrc/common/strncat.s b/libsrc/common/strncat.s index 75572db7c..e4e321591 100644 --- a/libsrc/common/strncat.s +++ b/libsrc/common/strncat.s @@ -8,64 +8,63 @@ .export _strncat .import popax, popptr1 .importzp ptr1, ptr2, ptr3, tmp1, tmp2 -.macpack cpu _strncat: - inx - stx tmp2 - tax - inx - stx tmp1 ; save count with each byte incremented separately + inx + stx tmp2 + tax + inx + stx tmp1 ; save count with each byte incremented separately - jsr popptr1 ; get src + jsr popptr1 ; get src - jsr popax ; get dest - sta ptr3 ; remember for function return - stx ptr3+1 - stx ptr2+1 - tay ; low byte as offset in Y -.if (.cpu .bitand ::CPU_ISET_65SC02) - stz ptr2 + jsr popax ; get dest + sta ptr3 ; remember for function return + stx ptr3+1 + stx ptr2+1 + tay ; low byte as offset in Y +.if .cap(CPU_HAS_STZ) + stz ptr2 .else - ldx #0 - stx ptr2 ; destination on page boundary + ldx #0 + stx ptr2 ; destination on page boundary .endif ; find end of dest -L1: lda (ptr2),y - beq L2 - iny - bne L1 - inc ptr2+1 - bne L1 +L1: lda (ptr2),y + beq L2 + iny + bne L1 + inc ptr2+1 + bne L1 ; end found, apply offset to dest ptr and reset y -L2: sty ptr2 +L2: sty ptr2 ; copy src. We've put the ones complement of the count into the counter, so ; we'll increment the counter on top of the loop -L3: ldy #0 - ldx tmp1 ; low counter byte +L3: ldy #0 + ldx tmp1 ; low counter byte -L4: dex - bne L5 - dec tmp2 - beq L6 ; jump if done -L5: lda (ptr1),y - sta (ptr2),y - beq L7 - iny - bne L4 - inc ptr1+1 - inc ptr2+1 - bne L4 +L4: dex + bne L5 + dec tmp2 + beq L6 ; jump if done +L5: lda (ptr1),y + sta (ptr2),y + beq L7 + iny + bne L4 + inc ptr1+1 + inc ptr2+1 + bne L4 ; done, set the trailing zero and return pointer to dest -L6: lda #0 - sta (ptr2),y -L7: lda ptr3 - ldx ptr3+1 - rts +L6: lda #0 + sta (ptr2),y +L7: lda ptr3 + ldx ptr3+1 + rts diff --git a/libsrc/conio/cputs.s b/libsrc/conio/cputs.s index b822fddee..d6024c0e5 100644 --- a/libsrc/conio/cputs.s +++ b/libsrc/conio/cputs.s @@ -8,13 +8,12 @@ .export _cputsxy, _cputs .import gotoxy, _cputc .importzp ptr1, tmp1 - .macpack cpu _cputsxy: sta ptr1 ; Save s for later stx ptr1+1 jsr gotoxy ; Set cursor, pop x and y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_BRA8) bra L0 ; Same as cputs... .else jmp L0 ; Same as cputs... @@ -24,7 +23,7 @@ _cputs: sta ptr1 ; Save s stx ptr1+1 L0: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; (5) .else ldy #0 ; (2) diff --git a/libsrc/conio/scrsize.s b/libsrc/conio/scrsize.s index 834c14820..fc1691b87 100644 --- a/libsrc/conio/scrsize.s +++ b/libsrc/conio/scrsize.s @@ -10,8 +10,6 @@ .import screensize .importzp ptr1, ptr2 - .macpack cpu - .proc _screensize sta ptr2 ; Store the y pointer @@ -20,7 +18,7 @@ jsr screensize ; Get screensize into X/Y tya ; Get Y size into A -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (ptr2) txa sta (ptr1) diff --git a/libsrc/conio/vcprintf.s b/libsrc/conio/vcprintf.s index c6371f00e..aa7b6aa07 100644 --- a/libsrc/conio/vcprintf.s +++ b/libsrc/conio/vcprintf.s @@ -10,7 +10,6 @@ .importzp c_sp, ptr1, ptr2, ptr3, tmp1 .macpack generic - .macpack cpu .data @@ -74,7 +73,7 @@ out: jsr popax ; count ; Loop outputting characters -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND, CPU_HAS_BRA8) @L1: dec outdesc+6 beq @L4 diff --git a/libsrc/runtime/add.s b/libsrc/runtime/add.s index 85ddd0f25..b841f829d 100644 --- a/libsrc/runtime/add.s +++ b/libsrc/runtime/add.s @@ -11,14 +11,12 @@ .export tosadda0, tosaddax .importzp c_sp, tmp1 - .macpack cpu - tosadda0: ldx #0 tosaddax: clc ; (2) -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; (7) tay ; (9) diff --git a/libsrc/runtime/and.s b/libsrc/runtime/and.s index 8411660ab..303d4e010 100644 --- a/libsrc/runtime/and.s +++ b/libsrc/runtime/and.s @@ -8,12 +8,10 @@ .import addysp1 .importzp c_sp, ptr4 - .macpack cpu - tosanda0: ldx #$00 tosandax: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) and (c_sp) ; 65SC02 version, saves 2 cycles and 1 byte ldy #1 .else diff --git a/libsrc/runtime/condes.s b/libsrc/runtime/condes.s index a99b713f5..fc187040e 100644 --- a/libsrc/runtime/condes.s +++ b/libsrc/runtime/condes.s @@ -18,8 +18,6 @@ .import __CONSTRUCTOR_TABLE__, __CONSTRUCTOR_COUNT__ .import __DESTRUCTOR_TABLE__, __DESTRUCTOR_COUNT__ - .macpack cpu - ; -------------------------------------------------------------------------- ; Initialize library modules diff --git a/libsrc/runtime/incax1.s b/libsrc/runtime/incax1.s index 19c1d0c60..bff94b019 100644 --- a/libsrc/runtime/incax1.s +++ b/libsrc/runtime/incax1.s @@ -7,11 +7,10 @@ .export incax1 .macpack generic - .macpack cpu .proc incax1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) ina ; 65C02 version bne @L9 .else diff --git a/libsrc/runtime/incsp2.s b/libsrc/runtime/incsp2.s index c3260c19d..395ea52cb 100644 --- a/libsrc/runtime/incsp2.s +++ b/libsrc/runtime/incsp2.s @@ -7,8 +7,6 @@ .export popax, incsp2 .importzp c_sp - .macpack cpu - ; Pop a/x from stack. This function will run directly into incsp2 .proc popax @@ -16,7 +14,7 @@ ldy #1 lda (c_sp),y ; get hi byte tax ; into x -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else dey diff --git a/libsrc/runtime/ladd.s b/libsrc/runtime/ladd.s index 6c187f32d..6991e4a7e 100644 --- a/libsrc/runtime/ladd.s +++ b/libsrc/runtime/ladd.s @@ -8,8 +8,6 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - ; EAX = TOS + EAX tosadd0ax: @@ -19,7 +17,7 @@ tosadd0ax: tosaddeax: clc -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else diff --git a/libsrc/runtime/laddeq.s b/libsrc/runtime/laddeq.s index 57bec0629..e5afac9cc 100644 --- a/libsrc/runtime/laddeq.s +++ b/libsrc/runtime/laddeq.s @@ -11,8 +11,6 @@ .export laddeq1, laddeqa, laddeq .importzp sreg, ptr1, tmp1 - .macpack cpu - laddeq1: lda #$01 @@ -24,7 +22,7 @@ laddeqa: laddeq: sty ptr1+1 ; Store high byte of address clc -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (ptr1) sta (ptr1) ldy #$01 ; Address byte 1 diff --git a/libsrc/runtime/land.s b/libsrc/runtime/land.s index 400fede3b..2ad4ae4d7 100644 --- a/libsrc/runtime/land.s +++ b/libsrc/runtime/land.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosand0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosand0ax: .endif tosandeax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) and (c_sp) ; byte 0 ldy #1 .else diff --git a/libsrc/runtime/ldau0sp.s b/libsrc/runtime/ldau0sp.s index a808f6f84..5fbde5b62 100644 --- a/libsrc/runtime/ldau0sp.s +++ b/libsrc/runtime/ldau0sp.s @@ -7,8 +7,6 @@ .export ldau00sp, ldau0ysp .importzp c_sp, ptr1 - .macpack cpu - ldau00sp: ldy #1 ldau0ysp: @@ -18,7 +16,7 @@ ldau0ysp: lda (c_sp),y sta ptr1 ldx #0 -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; Save one cycle for the C02 .else lda (ptr1,x) diff --git a/libsrc/runtime/leave.s b/libsrc/runtime/leave.s index 408fdd159..afb069b1c 100644 --- a/libsrc/runtime/leave.s +++ b/libsrc/runtime/leave.s @@ -14,8 +14,6 @@ .import addysp .importzp c_sp - .macpack cpu - leave00: lda #0 leave0: ldx #0 @@ -28,7 +26,7 @@ leavey0: leavey: jsr addysp ; drop stack frame -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) leave: tay ; save A a sec lda (c_sp) ; that's the pushed arg size diff --git a/libsrc/runtime/lmod.s b/libsrc/runtime/lmod.s index b8e796dea..1cff216f3 100644 --- a/libsrc/runtime/lmod.s +++ b/libsrc/runtime/lmod.s @@ -11,10 +11,8 @@ .import poplsargs, udiv32, negeax .importzp sreg, ptr1, ptr2, tmp1, tmp3, tmp4 - .macpack cpu - tosmod0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else diff --git a/libsrc/runtime/lmul.s b/libsrc/runtime/lmul.s index a68c3e5c1..7124d6abd 100644 --- a/libsrc/runtime/lmul.s +++ b/libsrc/runtime/lmul.s @@ -9,11 +9,9 @@ .import addysp1 .importzp c_sp, sreg, tmp1, tmp2, tmp3, tmp4, ptr1, ptr3, ptr4 - .macpack cpu - tosmul0ax: tosumul0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tosmuleax: tosumuleax: mul32: sta ptr1 stx ptr1+1 ; op2 now in ptr1/sreg -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lor.s b/libsrc/runtime/lor.s index 888a0c611..fa87aa63d 100644 --- a/libsrc/runtime/lor.s +++ b/libsrc/runtime/lor.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosor0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosor0ax: .endif tosoreax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) ora (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lpop.s b/libsrc/runtime/lpop.s index 9690aff24..81dde42d3 100644 --- a/libsrc/runtime/lpop.s +++ b/libsrc/runtime/lpop.s @@ -9,8 +9,6 @@ .import incsp4 .importzp c_sp, sreg - .macpack cpu - popeax: ldy #3 lda (c_sp),y sta sreg+1 @@ -20,7 +18,7 @@ popeax: ldy #3 dey lda (c_sp),y tax -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else dey diff --git a/libsrc/runtime/lpush.s b/libsrc/runtime/lpush.s index ec2c865af..fbc37b78c 100644 --- a/libsrc/runtime/lpush.s +++ b/libsrc/runtime/lpush.s @@ -12,13 +12,11 @@ .import decsp4 .importzp c_sp, sreg - .macpack cpu - pushl0: lda #0 tax push0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -39,7 +37,7 @@ pusheax: txa sta (c_sp),y pla -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) .else dey diff --git a/libsrc/runtime/lrsub.s b/libsrc/runtime/lrsub.s index 456d8d8d5..b88d44f1a 100644 --- a/libsrc/runtime/lrsub.s +++ b/libsrc/runtime/lrsub.s @@ -12,10 +12,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosrsub0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tosrsub0ax: tosrsubeax: sec -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sbc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lsub.s b/libsrc/runtime/lsub.s index 17b225404..f0d34cd5b 100644 --- a/libsrc/runtime/lsub.s +++ b/libsrc/runtime/lsub.s @@ -11,10 +11,8 @@ .import addysp1 .importzp c_sp, sreg - .macpack cpu - tossub0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -26,7 +24,7 @@ tossub0ax: tossubeax: sec eor #$FF -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ; 65SC02 version - saves 2 cycles ldy #1 .else diff --git a/libsrc/runtime/lsubeq.s b/libsrc/runtime/lsubeq.s index b16ab18e1..d2d4ede7f 100644 --- a/libsrc/runtime/lsubeq.s +++ b/libsrc/runtime/lsubeq.s @@ -11,8 +11,6 @@ .export lsubeq1, lsubeqa, lsubeq .importzp sreg, ptr1 - .macpack cpu - lsubeq1: lda #$01 @@ -25,7 +23,7 @@ lsubeq: sty ptr1+1 ; Store high byte of address sec eor #$FF - .if (.cpu .bitand ::CPU_ISET_65SC02) + .if .cap(CPU_HAS_ZPIND) adc (ptr1) ; Subtract byte 0 sta (ptr1) ldy #$01 ; Address byte 1 diff --git a/libsrc/runtime/ludiv.s b/libsrc/runtime/ludiv.s index b47207222..53651c789 100644 --- a/libsrc/runtime/ludiv.s +++ b/libsrc/runtime/ludiv.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4 - .macpack cpu - tosudiv0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -38,7 +36,7 @@ getlop: sta ptr3 ; Put right operand in place lda sreg+1 sta ptr4+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ldy #1 .else diff --git a/libsrc/runtime/lumod.s b/libsrc/runtime/lumod.s index eb6176b35..a43c6d287 100644 --- a/libsrc/runtime/lumod.s +++ b/libsrc/runtime/lumod.s @@ -9,10 +9,8 @@ .import getlop, udiv32 .importzp sreg, tmp3, tmp4, ptr2 - .macpack cpu - tosumod0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else diff --git a/libsrc/runtime/lxor.s b/libsrc/runtime/lxor.s index 6d9f7db3a..abf341e63 100644 --- a/libsrc/runtime/lxor.s +++ b/libsrc/runtime/lxor.s @@ -9,10 +9,8 @@ .import addysp1 .importzp c_sp, sreg, tmp1 - .macpack cpu - tosxor0ax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz sreg stz sreg+1 .else @@ -22,7 +20,7 @@ tosxor0ax: .endif tosxoreax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) eor (c_sp) ; byte 0 ldy #1 .else diff --git a/libsrc/runtime/or.s b/libsrc/runtime/or.s index 04389be5f..09aa93e79 100644 --- a/libsrc/runtime/or.s +++ b/libsrc/runtime/or.s @@ -9,12 +9,10 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - tosora0: ldx #$00 tosorax: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) ora (c_sp) ldy #1 .else diff --git a/libsrc/runtime/popa.s b/libsrc/runtime/popa.s index c1700071d..bc490312e 100644 --- a/libsrc/runtime/popa.s +++ b/libsrc/runtime/popa.s @@ -7,11 +7,9 @@ .export popa .importzp c_sp - .macpack cpu - .proc popa -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else ldy #0 ; (2) diff --git a/libsrc/runtime/popptr1.s b/libsrc/runtime/popptr1.s index 45043dd27..90dca5e22 100644 --- a/libsrc/runtime/popptr1.s +++ b/libsrc/runtime/popptr1.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp, ptr1 - .macpack cpu - .proc popptr1 ; 14 bytes (four usages = at least 2 bytes saved) ldy #1 lda (c_sp),y ; get hi byte sta ptr1+1 ; into ptr hi dey ; dey even for for 65C02 here to have Y=0 at exit! -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else lda (c_sp),y ; get lo byte diff --git a/libsrc/runtime/popsreg.s b/libsrc/runtime/popsreg.s index c7f667246..0f6e5701d 100644 --- a/libsrc/runtime/popsreg.s +++ b/libsrc/runtime/popsreg.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp, sreg - .macpack cpu - popsreg: pha ; save A ldy #1 lda (c_sp),y ; get hi byte sta sreg+1 ; store it -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) ; get lo byte .else dey diff --git a/libsrc/runtime/pusha.s b/libsrc/runtime/pusha.s index 399423077..6c715afb7 100644 --- a/libsrc/runtime/pusha.s +++ b/libsrc/runtime/pusha.s @@ -7,8 +7,6 @@ .export pusha0sp, pushaysp, pusha .importzp c_sp - .macpack cpu - ; Beware: The optimizer knows about this function! pusha0sp: diff --git a/libsrc/runtime/pushax.s b/libsrc/runtime/pushax.s index f77a9bcc3..5177f77b5 100644 --- a/libsrc/runtime/pushax.s +++ b/libsrc/runtime/pushax.s @@ -7,8 +7,6 @@ .export push0, pusha0, pushax .importzp c_sp - .macpack cpu - push0: lda #0 pusha0: ldx #0 @@ -31,7 +29,7 @@ pusha0: ldx #0 sta (c_sp),y ; (27) pla ; (31) dey ; (33) -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; (37) .else sta (c_sp),y ; (38) diff --git a/libsrc/runtime/pushb.s b/libsrc/runtime/pushb.s index 7507ff21a..02d91b156 100644 --- a/libsrc/runtime/pushb.s +++ b/libsrc/runtime/pushb.s @@ -8,8 +8,6 @@ .import pushax .importzp ptr1 - .macpack cpu - pushbidx: sty ptr1 clc @@ -19,7 +17,7 @@ pushbidx: pushb: sta ptr1 stx ptr1+1 ldx #0 ; Load index/high byte -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (ptr1) ; Save one cycle for the C02 .else lda (ptr1,x) diff --git a/libsrc/runtime/rsub.s b/libsrc/runtime/rsub.s index bacb3c7fc..1eedee53e 100644 --- a/libsrc/runtime/rsub.s +++ b/libsrc/runtime/rsub.s @@ -9,8 +9,6 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - ; ; AX = AX - TOS ; @@ -19,7 +17,7 @@ tosrsuba0: ldx #0 tosrsubax: sec -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sbc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/shl.s b/libsrc/runtime/shl.s index c1a4b6ef8..1f11eb5c0 100644 --- a/libsrc/runtime/shl.s +++ b/libsrc/runtime/shl.s @@ -15,8 +15,6 @@ .import popax .importzp tmp1 - .macpack cpu - tosshlax: tosaslax: sta tmp1 ; Save shift count @@ -55,7 +53,7 @@ L2: pla ; Shift count is exactly 8 -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_PUSHXY) L3: plx ; Low byte from stack into X rts ; A is already zero .else diff --git a/libsrc/runtime/staxspi.s b/libsrc/runtime/staxspi.s index aefed428f..e1542881f 100644 --- a/libsrc/runtime/staxspi.s +++ b/libsrc/runtime/staxspi.s @@ -9,8 +9,6 @@ .import incsp2 .importzp c_sp, tmp1, ptr1 - .macpack cpu - .proc staxspidx sty tmp1 ; Save Y @@ -18,7 +16,7 @@ ldy #1 lda (c_sp),y sta ptr1+1 -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else dey diff --git a/libsrc/runtime/stkchk.s b/libsrc/runtime/stkchk.s index a7ca39f21..f6ab28ea6 100644 --- a/libsrc/runtime/stkchk.s +++ b/libsrc/runtime/stkchk.s @@ -21,7 +21,6 @@ ; Use macros for better readability .macpack generic - .macpack cpu ; ---------------------------------------------------------------------------- @@ -39,7 +38,7 @@ lda c_sp+1 sta initialsp+1 sbc #>__STACKSIZE__ -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_INA) ina ; Add 256 bytes safety area .else add #1 ; Add 256 bytes safety area diff --git a/libsrc/runtime/sub.s b/libsrc/runtime/sub.s index 58ffb4c91..7129e2147 100644 --- a/libsrc/runtime/sub.s +++ b/libsrc/runtime/sub.s @@ -8,8 +8,6 @@ .import addysp1 .importzp c_sp - .macpack cpu - ; AX = TOS - AX tossuba0: @@ -17,7 +15,7 @@ tossuba0: tossubax: sec eor #$FF -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) adc (c_sp) ldy #1 .else diff --git a/libsrc/runtime/swap.s b/libsrc/runtime/swap.s index 3796b0a97..72adaa90b 100644 --- a/libsrc/runtime/swap.s +++ b/libsrc/runtime/swap.s @@ -8,8 +8,6 @@ .export swapstk .importzp c_sp, ptr4 - .macpack cpu - swapstk: sta ptr4 stx ptr4+1 @@ -18,7 +16,7 @@ swapstk: tax lda ptr4+1 sta (c_sp),y -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) tay lda ptr4 diff --git a/libsrc/runtime/tosint.s b/libsrc/runtime/tosint.s index 2aaa19ccc..e879fe11f 100644 --- a/libsrc/runtime/tosint.s +++ b/libsrc/runtime/tosint.s @@ -8,14 +8,12 @@ .import incsp2 .importzp c_sp - .macpack cpu - ; Convert TOS from long to int by cutting of the high 16bit .proc tosint pha -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) lda (c_sp) .else ldy #0 diff --git a/libsrc/runtime/toslong.s b/libsrc/runtime/toslong.s index cf8eff031..c8b34d8b0 100644 --- a/libsrc/runtime/toslong.s +++ b/libsrc/runtime/toslong.s @@ -8,8 +8,6 @@ .import decsp2 .importzp c_sp - .macpack cpu - ; Convert TOS from int to long tosulong: @@ -17,7 +15,7 @@ tosulong: jsr decsp2 ; Make room ldy #2 lda (c_sp),y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; 65C02 version iny ; Y = 3 .else @@ -43,7 +41,7 @@ toslong: jsr decsp2 ; Make room ldy #2 lda (c_sp),y -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) sta (c_sp) ; 65C02 version iny ; Y = 3 .else diff --git a/libsrc/runtime/umul8x16r24.s b/libsrc/runtime/umul8x16r24.s index 54d730558..115a3e1a4 100644 --- a/libsrc/runtime/umul8x16r24.s +++ b/libsrc/runtime/umul8x16r24.s @@ -9,8 +9,6 @@ .include "zeropage.inc" - .macpack cpu - ;--------------------------------------------------------------------------- ; 8x16 => 24 unsigned multiplication routine. Because the overhead for a ; 8x16 => 16 unsigned multiplication routine is small, we will tag it with @@ -31,7 +29,7 @@ umul8x16r16: umul8x16r24m: umul8x16r16m: -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_STZ) stz ptr1+1 stz sreg .else diff --git a/libsrc/runtime/xor.s b/libsrc/runtime/xor.s index 15394413c..1236b2c37 100644 --- a/libsrc/runtime/xor.s +++ b/libsrc/runtime/xor.s @@ -9,12 +9,10 @@ .import addysp1 .importzp c_sp, tmp1 - .macpack cpu - tosxora0: ldx #$00 tosxorax: -.if (.cpu .bitand CPU_ISET_65SC02) +.if .cap(CPU_HAS_ZPIND) eor (c_sp) ldy #1 .else diff --git a/libsrc/tgi/tgi_settextstyle.s b/libsrc/tgi/tgi_settextstyle.s index b62d6904c..bb924c048 100644 --- a/libsrc/tgi/tgi_settextstyle.s +++ b/libsrc/tgi/tgi_settextstyle.s @@ -9,8 +9,6 @@ .import umul8x16r24 .import popa, popax - .macpack cpu - ;----------------------------------------------------------------------------- ; void __fastcall__ tgi_settextstyle (unsigned width, unsigned height, ; unsigned char dir, unsigned char font); @@ -82,7 +80,7 @@ process_onedim: ; Disallowing characters larger than 256 pixels, we just drop the high byte ; and remember the low 16 bit as size in 8.8 format. -.if (.cpu .bitand ::CPU_ISET_65SC02) +.if .cap(CPU_HAS_PUSHXY) phy ; Save Y jsr umul8x16r24 ply ; Restore Y From 59e7158512043a18966ca68531a18ba67791afdb Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:29:42 +0200 Subject: [PATCH 685/707] Make the CPU_xxx constants from cpu.mac internal to the assembler and replace cpu.mac by a file that just emits a warning when used. --- asminc/cpu.mac | 42 ++---------- doc/ca65.sgml | 134 ++++++++++++++++++------------------- libsrc/apple2/cputc.s | 2 - libsrc/apple2/lseek.s | 1 - libsrc/apple2/ser/a2.ssc.s | 1 - libsrc/common/strlen.s | 1 - libsrc/sim6502/exehdr.s | 2 - src/ca65/main.c | 50 ++++++++++++++ 8 files changed, 119 insertions(+), 114 deletions(-) diff --git a/asminc/cpu.mac b/asminc/cpu.mac index 15b16bad5..092519173 100644 --- a/asminc/cpu.mac +++ b/asminc/cpu.mac @@ -1,38 +1,4 @@ -; CPU bitmask constants (make sure this matches src/common/cpu.h) - -CPU_ISET_NONE = $0001 -CPU_ISET_6502 = $0002 -CPU_ISET_6502X = $0004 -CPU_ISET_6502DTV = $0008 -CPU_ISET_65SC02 = $0010 -CPU_ISET_65C02 = $0020 ; Rockwell extensions -CPU_ISET_65816 = $0040 -CPU_ISET_SWEET16 = $0080 -CPU_ISET_HUC6280 = $0100 -CPU_ISET_M740 = $0200 -CPU_ISET_4510 = $0400 -CPU_ISET_45GS02 = $0800 -CPU_ISET_W65C02 = $1000 ; WDC extensions -CPU_ISET_65CE02 = $2000 ; CSG extensions - -; CPU capabilities -; make sure to only combine the instruction sets that are 100% compatible -CPU_NONE = CPU_ISET_NONE -CPU_6502 = CPU_ISET_6502 -CPU_6502X = CPU_ISET_6502X | CPU_ISET_6502 -CPU_6502DTV = CPU_ISET_6502DTV | CPU_ISET_6502 -CPU_65SC02 = CPU_ISET_65SC02 | CPU_ISET_6502 -CPU_65C02 = CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_W65C02 = CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 - -; FIXME: CPU_ISET_65SC02 does not apply to the following, because the zp-indirect -; addressing was replaced with zp-indirect,z-indexed in 652SCE02 - -CPU_HUC6280 = CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02 -CPU_4510 = CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 -CPU_45GS02 = CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510 -CPU_M740 = CPU_ISET_M740 | CPU_ISET_6502 -CPU_65CE02 = CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02 - -CPU_65816 = CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 -CPU_SWEET16 = CPU_ISET_SWEET16 +; This file is no longer needed as the symbols that were defined here are now +; internal symbols generated by the assembler. It is kept to avoid breaking +; old sources. +.warning "'.macpack cpu' is no longer required" diff --git a/doc/ca65.sgml b/doc/ca65.sgml index cfe73a2f0..0f996ff64 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1401,16 +1401,76 @@ writable. Reading this pseudo variable will give a constant integer value that tells which CPU is currently enabled. It can also tell which instruction set the CPU is able to translate. The value read from the pseudo variable - should be further examined by using one of the constants defined by the - "cpu" macro package (see <tt/<ref id=".MACPACK" name=".MACPACK">/). + should be further examined by using one of the following constants: - It may be used to replace the .IFPxx pseudo instructions or to construct - even more complex expressions. +<tscreen><verb> + CPU_6502 + CPU_65SC02 + CPU_65C02 + CPU_65816 + CPU_SWEET16 + CPU_HUC6280 + CPU_4510 + CPU_45GS02 + CPU_6502DTV + CPU_M740 +</verb></tscreen> + +Above constants may be used to determine the exact type of the currently +enabled CPU. In addition to that, for each CPU instruction set, another +constant is defined: + +<tscreen><verb> + CPU_ISET_6502 + CPU_ISET_65SC02 + CPU_ISET_65C02 + CPU_ISET_65816 + CPU_ISET_SWEET16 + CPU_ISET_HUC6280 + CPU_ISET_4510 + CPU_ISET_45GS02 + CPU_ISET_6502DTV + CPU_ISET_M740 +</verb></tscreen> + +<!-- Sorry but explaining these with the changes from #2751 is too cringy for + me - must be done by someone else. The remainder is from the old + ".macpack cpu" section" + +The value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable may +be checked with <tt/<ref id="operators" name=".BITAND">/ to determine if the +currently enabled CPU supports a specific instruction set. For example the +65C02 supports all instructions of the 65SC02 CPU, so it has the +<tt/CPU_ISET_65SC02/ bit set in addition to its native <tt/CPU_ISET_65C02/ +bit. Using + +<tscreen><verb> + .if (.cpu .bitand CPU_ISET_65SC02) + lda (c_sp) + .else + ldy #$00 + lda (c_sp),y + .endif +</verb></tscreen> + +it is possible to determine if the + +<tscreen><verb> + lda (c_sp) +</verb></tscreen> + +instruction is supported, which is the case for the 65SC02, 65C02 and 65816 +CPUs (the latter two are upwards compatible to the 65SC02). + +see section <ref id="6502-mode" name="6502 format"> and following. +--> + + <tt/.CPU/ may be used to replace the .IFPxx pseudo instructions or to + construct even more complex expressions. Example: <tscreen><verb> - .macpack cpu .if (.cpu .bitand CPU_ISET_65816) phx phy @@ -1422,7 +1482,6 @@ writable. .endif </verb></tscreen> - See also: <tt><ref id=".CAP" name=".CAP"></tt> @@ -5042,69 +5101,6 @@ This macro package defines a macro named <tt/scrcode/. It takes a string as argument and places this string into memory translated into screen codes. -<sect1><tt>.MACPACK cpu</tt><p> - -This macro package does not define any macros but constants used to examine -the value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable. For -each supported CPU a constant similar to - -<tscreen><verb> - CPU_6502 - CPU_65SC02 - CPU_65C02 - CPU_65816 - CPU_SWEET16 - CPU_HUC6280 - CPU_4510 - CPU_45GS02 - CPU_6502DTV - CPU_M740 -</verb></tscreen> - -is defined. These constants may be used to determine the exact type of the -currently enabled CPU. In addition to that, for each CPU instruction set, -another constant is defined: - -<tscreen><verb> - CPU_ISET_6502 - CPU_ISET_65SC02 - CPU_ISET_65C02 - CPU_ISET_65816 - CPU_ISET_SWEET16 - CPU_ISET_HUC6280 - CPU_ISET_4510 - CPU_ISET_45GS02 - CPU_ISET_6502DTV - CPU_ISET_M740 -</verb></tscreen> - -The value read from the <tt/<ref id=".CPU" name=".CPU">/ pseudo variable may -be checked with <tt/<ref id="operators" name=".BITAND">/ to determine if the -currently enabled CPU supports a specific instruction set. For example the -65C02 supports all instructions of the 65SC02 CPU, so it has the -<tt/CPU_ISET_65SC02/ bit set in addition to its native <tt/CPU_ISET_65C02/ -bit. Using - -<tscreen><verb> - .if (.cpu .bitand CPU_ISET_65SC02) - lda (c_sp) - .else - ldy #$00 - lda (c_sp),y - .endif -</verb></tscreen> - -it is possible to determine if the - -<tscreen><verb> - lda (c_sp) -</verb></tscreen> - -instruction is supported, which is the case for the 65SC02, 65C02 and 65816 -CPUs (the latter two are upwards compatible to the 65SC02). - -see section <ref id="6502-mode" name="6502 format"> and following. - <sect1><tt>.MACPACK module</tt><p> This macro package defines a macro named <tt/module_header/. It takes an diff --git a/libsrc/apple2/cputc.s b/libsrc/apple2/cputc.s index aa4a383b3..5c4bf192e 100644 --- a/libsrc/apple2/cputc.s +++ b/libsrc/apple2/cputc.s @@ -18,8 +18,6 @@ .include "zeropage.inc" .include "apple2.inc" - .macpack cpu - .segment "ONCE" initconio: diff --git a/libsrc/apple2/lseek.s b/libsrc/apple2/lseek.s index be0078c1b..63a2813dc 100644 --- a/libsrc/apple2/lseek.s +++ b/libsrc/apple2/lseek.s @@ -6,7 +6,6 @@ .export _lseek .import popax, popptr1 - .macpack cpu .include "zeropage.inc" .include "errno.inc" diff --git a/libsrc/apple2/ser/a2.ssc.s b/libsrc/apple2/ser/a2.ssc.s index 488a32540..8671d0ad8 100644 --- a/libsrc/apple2/ser/a2.ssc.s +++ b/libsrc/apple2/ser/a2.ssc.s @@ -26,7 +26,6 @@ .include "ser-error.inc" .macpack module - .macpack cpu ; ------------------------------------------------------------------------ ; Header. Includes jump table diff --git a/libsrc/common/strlen.s b/libsrc/common/strlen.s index b28bffe7a..6247d0c51 100644 --- a/libsrc/common/strlen.s +++ b/libsrc/common/strlen.s @@ -10,7 +10,6 @@ .export _strlen, _strlen_ptr4 .importzp ptr4 - .macpack cpu _strlen: sta ptr4 ; Save s diff --git a/libsrc/sim6502/exehdr.s b/libsrc/sim6502/exehdr.s index 224b2af2d..a1b739b5f 100644 --- a/libsrc/sim6502/exehdr.s +++ b/libsrc/sim6502/exehdr.s @@ -9,8 +9,6 @@ .import __MAIN_START__ .import startup - .macpack cpu - .segment "EXEHDR" .byte $73, $69, $6D, $36, $35 ; 'sim65' diff --git a/src/ca65/main.c b/src/ca65/main.c index f113bc812..fb0907df3 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -192,6 +192,53 @@ static void CBMSystem (const char* Sys) +static void DefineCpuSymbols (void) +/* Define all the symbols to evaluate .cpu. These were previously in cpu.mac. */ +{ + NewSymbol ("CPU_ISET_NONE", CPU_ISET_NONE); + NewSymbol ("CPU_ISET_6502", CPU_ISET_6502); + NewSymbol ("CPU_ISET_6502X", CPU_ISET_6502X); + NewSymbol ("CPU_ISET_6502DTV", CPU_ISET_6502DTV); + NewSymbol ("CPU_ISET_65SC02", CPU_ISET_65SC02); + NewSymbol ("CPU_ISET_65C02", CPU_ISET_65C02); + NewSymbol ("CPU_ISET_65816", CPU_ISET_65816); + NewSymbol ("CPU_ISET_SWEET16", CPU_ISET_SWEET16); + NewSymbol ("CPU_ISET_HUC6280", CPU_ISET_HUC6280); + NewSymbol ("CPU_ISET_M740", CPU_ISET_M740); + NewSymbol ("CPU_ISET_4510", CPU_ISET_4510); + NewSymbol ("CPU_ISET_45GS02", CPU_ISET_45GS02); + NewSymbol ("CPU_ISET_W65C02", CPU_ISET_W65C02); + NewSymbol ("CPU_ISET_65CE02", CPU_ISET_65CE02); + + /* Additional ones from cpu.mac. Not sure how useful they are after the + ** changes from #2751. + */ + NewSymbol ("CPU_NONE", CPU_ISET_NONE); + NewSymbol ("CPU_6502", CPU_ISET_6502); + NewSymbol ("CPU_6502X", CPU_ISET_6502X | CPU_ISET_6502); + NewSymbol ("CPU_6502DTV", CPU_ISET_6502DTV | CPU_ISET_6502); + NewSymbol ("CPU_65SC02", CPU_ISET_65SC02 | CPU_ISET_6502); + NewSymbol ("CPU_65C02", CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02); + NewSymbol ("CPU_W65C02", CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | + CPU_ISET_65C02); + + /* FIXME: CPU_ISET_65SC02 does not apply to the following, because the + ** zp-indirect addressing was replaced with zp-indirect,z-indexed in + ** 652SCE02 + */ + NewSymbol ("CPU_HUC6280", CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02); + NewSymbol ("CPU_4510", CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | + CPU_ISET_65CE02); + NewSymbol ("CPU_45GS02", CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | + CPU_ISET_65CE02 | CPU_ISET_4510); + NewSymbol ("CPU_M740", CPU_ISET_M740 | CPU_ISET_6502); + NewSymbol ("CPU_65CE02", CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02); + NewSymbol ("CPU_65816", CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02); + NewSymbol ("CPU_SWEET16", CPU_ISET_SWEET16); +} + + + static void SetSys (const char* Sys) /* Define a target system */ { @@ -363,6 +410,9 @@ static void SetSys (const char* Sys) } + /* Define the symbols for evaluating .cpu */ + DefineCpuSymbols (); + /* Initialize the translation tables for the target system */ TgtTranslateInit (); } From 29c8846f7d4746ceaef7846d253327f458f2d143 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:34:38 +0200 Subject: [PATCH 686/707] Add an additional hook (currently unused) for target specific capabilities. --- src/ca65/expr.c | 3 ++- src/common/target.c | 10 ++++++++++ src/common/target.h | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 42b1a369b..33984610d 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -61,6 +61,7 @@ #include "studyexpr.h" #include "symbol.h" #include "symtab.h" +#include "target.h" #include "toklist.h" #include "ulabel.h" #include "macro.h" @@ -445,7 +446,7 @@ static ExprNode* FuncCapability (void) /* The pseudo function result is the logical AND of all capabilities ** given. */ - if (!CPUHasCap (Cap)) { + if (!CPUHasCap (Cap) && !TargetHasCap (Cap)) { Result = 0; } } diff --git a/src/common/target.c b/src/common/target.c index a12f69bf9..bb67ddf9a 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -37,6 +37,7 @@ #include <string.h> /* common */ +#include "attrib.h" #include "chartype.h" #include "check.h" #include "target.h" @@ -302,3 +303,12 @@ const char* GetTargetName (target_t Target) /* Return the array entry */ return GetTargetProperties (Target)->Name; } + + + +int TargetHasCap (capability_t Cap attribute((unused))) +/* Check if the current target has the given capability */ +{ + /* Currently unused */ + return 0; +} diff --git a/src/common/target.h b/src/common/target.h index c5c8455a0..1dfa66ac7 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -39,6 +39,7 @@ /* common */ +#include "capability.h" #include "cpu.h" @@ -131,6 +132,9 @@ const TargetProperties* GetTargetProperties (target_t Target); const char* GetTargetName (target_t Target); /* Return the name of a target */ +int TargetHasCap (capability_t Cap); +/* Check if the current target has the given capability */ + /* End of target.h */ From 8d3112e24f93053bf8cd92ca5aa54d2f55339821 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 08:47:16 +0200 Subject: [PATCH 687/707] Small code simplification. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index d8c0dbd37..2f239d99d 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -233,5 +233,5 @@ int CPUHasCap (capability_t Cap) /* Check if the current CPU has the given capability */ { PRECONDITION (CPU >= 0 && CPU < CPU_COUNT); - return (CPUCaps[CPU] & (UINT32_C (1) << Cap)) != 0; + return (CPUCaps[CPU] & CAP_BIT (Cap)) != 0; } From c162f6a28636cd9cb04f5812532e53f87922b5f5 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:21:18 +0200 Subject: [PATCH 688/707] Warning fix. --- src/common/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cpu.c b/src/common/cpu.c index 2f239d99d..7988cb4c1 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -151,7 +151,7 @@ const unsigned CPUIsets[CPU_COUNT] = { CAP_BIT (CAP_CPU_HAS_PUSHXY)) /* Table containing one capability entry per CPU */ -static const uint64_t CPUCaps[CPU_COUNT] = { +static const uint32_t CPUCaps[CPU_COUNT] = { CAP_NONE, /* CPU_NONE */ CAP_6502, /* CPU_6502 */ CAP_6502X, /* CPU_6502X */ From 37414199c7f511eeee21a23bc0c1d184871fe92b Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:33:38 +0200 Subject: [PATCH 689/707] Hopefully fix windows build files. --- src/common.vcxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common.vcxproj b/src/common.vcxproj index 6098c98a0..251ea3aeb 100644 --- a/src/common.vcxproj +++ b/src/common.vcxproj @@ -80,6 +80,7 @@ <ClInclude Include="common\assertion.h" /> <ClInclude Include="common\attrib.h" /> <ClInclude Include="common\bitops.h" /> + <ClInclude Include="common\capability.h" /> <ClInclude Include="common\cddefs.h" /> <ClInclude Include="common\chartype.h" /> <ClInclude Include="common\check.h" /> @@ -133,6 +134,7 @@ <ClCompile Include="common\alignment.c" /> <ClCompile Include="common\assertion.c" /> <ClCompile Include="common\bitops.c" /> + <ClCompile Include="common\capability.c" /> <ClCompile Include="common\chartype.c" /> <ClCompile Include="common\check.c" /> <ClCompile Include="common\cmdline.c" /> @@ -171,4 +173,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> \ No newline at end of file +</Project> From 60ec9045fce2c30aa4a24e46c59daaaccfab283a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 13:02:15 +0200 Subject: [PATCH 690/707] Use CPUIsets from cpu.c instead of recreating the CPU_xxx constants. --- src/ca65/main.c | 36 ++++++++++++++---------------------- src/common/cpu.c | 16 ++++++++++++++-- src/common/cpu.h | 2 +- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index fb0907df3..e9b36ee5d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -213,28 +213,20 @@ static void DefineCpuSymbols (void) /* Additional ones from cpu.mac. Not sure how useful they are after the ** changes from #2751. */ - NewSymbol ("CPU_NONE", CPU_ISET_NONE); - NewSymbol ("CPU_6502", CPU_ISET_6502); - NewSymbol ("CPU_6502X", CPU_ISET_6502X | CPU_ISET_6502); - NewSymbol ("CPU_6502DTV", CPU_ISET_6502DTV | CPU_ISET_6502); - NewSymbol ("CPU_65SC02", CPU_ISET_65SC02 | CPU_ISET_6502); - NewSymbol ("CPU_65C02", CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_W65C02", CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | - CPU_ISET_65C02); - - /* FIXME: CPU_ISET_65SC02 does not apply to the following, because the - ** zp-indirect addressing was replaced with zp-indirect,z-indexed in - ** 652SCE02 - */ - NewSymbol ("CPU_HUC6280", CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_4510", CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02); - NewSymbol ("CPU_45GS02", CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | - CPU_ISET_65CE02 | CPU_ISET_4510); - NewSymbol ("CPU_M740", CPU_ISET_M740 | CPU_ISET_6502); - NewSymbol ("CPU_65CE02", CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02); - NewSymbol ("CPU_65816", CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02); - NewSymbol ("CPU_SWEET16", CPU_ISET_SWEET16); + NewSymbol ("CPU_NONE", CPUIsets[CPU_NONE]); + NewSymbol ("CPU_6502", CPUIsets[CPU_6502]); + NewSymbol ("CPU_6502X", CPUIsets[CPU_6502X]); + NewSymbol ("CPU_6502DTV", CPUIsets[CPU_6502DTV]); + NewSymbol ("CPU_65SC02", CPUIsets[CPU_65SC02]); + NewSymbol ("CPU_65C02", CPUIsets[CPU_65C02]); + NewSymbol ("CPU_65816", CPUIsets[CPU_65816]); + NewSymbol ("CPU_SWEET16", CPUIsets[CPU_SWEET16]); + NewSymbol ("CPU_HUC6280", CPUIsets[CPU_HUC6280]); + NewSymbol ("CPU_M740", CPUIsets[CPU_M740]); + NewSymbol ("CPU_4510", CPUIsets[CPU_4510]); + NewSymbol ("CPU_45GS02", CPUIsets[CPU_45GS02]); + NewSymbol ("CPU_W65C02", CPUIsets[CPU_W65C02]); + NewSymbol ("CPU_65CE02", CPUIsets[CPU_65CE02]); } diff --git a/src/common/cpu.c b/src/common/cpu.c index 7988cb4c1..8e9ff827a 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -74,21 +74,33 @@ const char* CPUNames[CPU_COUNT] = { * NOTE: make sure to only combine the instruction sets that are 100% compatible */ const unsigned CPUIsets[CPU_COUNT] = { + /* CPU_NONE */ CPU_ISET_NONE, + /* CPU_6502 */ CPU_ISET_6502, + /* CPU_6502X */ CPU_ISET_6502X | CPU_ISET_6502, + /* CPU_6502DTV */ CPU_ISET_6502DTV | CPU_ISET_6502, + /* CPU_65SC02 */ CPU_ISET_65SC02 | CPU_ISET_6502, + /* CPU_65C02 */ CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02, - /* 65816 has wai/stp and NO bit manipulation */ + /* CPU_65816. 65816 has wai/stp and NO bit manipulation. */ CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02, + /* CPU_SWEET16 */ CPU_ISET_SWEET16, + /* CPU_HUC6280 */ CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_M740 */ CPU_ISET_M740 | CPU_ISET_6502, - /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ + /* CPU_4510. 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */ CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02, + /* CPU_45GS02 */ CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_65CE02 | CPU_ISET_4510, + /* CPU_W65C02 */ CPU_ISET_W65C02 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, + /* CPU_65CE02 */ CPU_ISET_65CE02 | CPU_ISET_6502 | CPU_ISET_65C02, }; diff --git a/src/common/cpu.h b/src/common/cpu.h index 0a7c853ac..bc6260371 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -69,7 +69,7 @@ typedef enum { CPU_COUNT /* Number of different CPUs */ } cpu_t; -/* CPU instruction sets (make sure this matches asminc/cpu.mac) */ +/* CPU instruction sets */ enum { CPU_ISET_NONE = 1 << CPU_NONE, CPU_ISET_6502 = 1 << CPU_6502, From 64d35b6a8697531b7af92ba4b677a7561aa3f9d9 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 17:24:24 +0200 Subject: [PATCH 691/707] Allow comments within _Pragma(). Fixes #2231. --- src/cc65/pragma.c | 94 +++++++++++++++++++++++++--------------------- src/cc65/preproc.c | 37 ++++++++---------- src/cc65/preproc.h | 5 +++ test/val/bug2231.c | 10 +++++ 4 files changed, 83 insertions(+), 63 deletions(-) create mode 100644 test/val/bug2231.c diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 49754fbe8..51f7f3007 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -48,6 +48,7 @@ #include "error.h" #include "global.h" #include "litpool.h" +#include "preproc.h" #include "scanner.h" #include "scanstrbuf.h" #include "symtab.h" @@ -866,24 +867,18 @@ static void NoteMessagePragma (const char* Message) -static void ParsePragmaString (void) +static void ParsePragmaString (StrBuf* B) /* Parse the contents of _Pragma */ { pragma_t Pragma; StrBuf Ident = AUTO_STRBUF_INITIALIZER; - /* Create a string buffer from the string literal */ - StrBuf B = AUTO_STRBUF_INITIALIZER; - - - SB_Append (&B, GetLiteralStrBuf (CurTok.SVal)); - /* Skip the string token */ NextToken (); /* Get the pragma name from the string */ - SB_SkipWhite (&B); - if (!SB_GetSym (&B, &Ident, "-")) { + SB_SkipWhite (B); + if (!SB_GetSym (B, &Ident, "-")) { Error ("Invalid pragma"); goto ExitPoint; } @@ -903,119 +898,119 @@ static void ParsePragmaString (void) } /* Check for an open paren */ - SB_SkipWhite (&B); - if (SB_Get (&B) != '(') { + SB_SkipWhite (B); + if (SB_Get (B) != '(') { Error ("'(' expected"); goto ExitPoint; } /* Skip white space before the argument */ - SB_SkipWhite (&B); + SB_SkipWhite (B); /* Switch for the different pragmas */ switch (Pragma) { case PRAGMA_ALIGN: /* TODO: PES_EXPR (PES_DECL) */ - IntPragma (PES_STMT, Pragma, &B, &DataAlignment, 1, 4096); + IntPragma (PES_STMT, Pragma, B, &DataAlignment, 1, 4096); break; case PRAGMA_ALLOW_EAGER_INLINE: - FlagPragma (PES_STMT, Pragma, &B, &EagerlyInlineFuncs); + FlagPragma (PES_STMT, Pragma, B, &EagerlyInlineFuncs); break; case PRAGMA_BSS_NAME: /* TODO: PES_STMT or even PES_EXPR (PES_DECL) maybe? */ - SegNamePragma (PES_FUNC, PRAGMA_BSS_NAME, &B); + SegNamePragma (PES_FUNC, PRAGMA_BSS_NAME, B); break; case PRAGMA_CHARMAP: - CharMapPragma (PES_IMM, &B); + CharMapPragma (PES_IMM, B); break; case PRAGMA_CHECK_STACK: /* TODO: PES_SCOPE maybe? */ - FlagPragma (PES_FUNC, Pragma, &B, &CheckStack); + FlagPragma (PES_FUNC, Pragma, B, &CheckStack); break; case PRAGMA_CODE_NAME: /* PES_FUNC is the only sensible option so far */ - SegNamePragma (PES_FUNC, PRAGMA_CODE_NAME, &B); + SegNamePragma (PES_FUNC, PRAGMA_CODE_NAME, B); break; case PRAGMA_CODESIZE: /* PES_EXPR would be optimization nightmare */ - IntPragma (PES_STMT, Pragma, &B, &CodeSizeFactor, 10, 1000); + IntPragma (PES_STMT, Pragma, B, &CodeSizeFactor, 10, 1000); break; case PRAGMA_DATA_NAME: /* TODO: PES_STMT or even PES_EXPR (PES_DECL) maybe? */ - SegNamePragma (PES_FUNC, PRAGMA_DATA_NAME, &B); + SegNamePragma (PES_FUNC, PRAGMA_DATA_NAME, B); break; case PRAGMA_INLINE_STDFUNCS: /* TODO: PES_EXPR maybe? */ - FlagPragma (PES_STMT, Pragma, &B, &InlineStdFuncs); + FlagPragma (PES_STMT, Pragma, B, &InlineStdFuncs); break; case PRAGMA_LOCAL_STRINGS: /* TODO: PES_STMT or even PES_EXPR */ - FlagPragma (PES_FUNC, Pragma, &B, &LocalStrings); + FlagPragma (PES_FUNC, Pragma, B, &LocalStrings); break; case PRAGMA_MESSAGE: /* PES_IMM is the only sensible option */ - StringPragma (PES_IMM, &B, NoteMessagePragma); + StringPragma (PES_IMM, B, NoteMessagePragma); break; case PRAGMA_OPTIMIZE: /* TODO: PES_STMT or even PES_EXPR maybe? */ - FlagPragma (PES_STMT, Pragma, &B, &Optimize); + FlagPragma (PES_STMT, Pragma, B, &Optimize); break; case PRAGMA_REGVARADDR: /* TODO: PES_STMT or even PES_EXPR maybe? */ - FlagPragma (PES_FUNC, Pragma, &B, &AllowRegVarAddr); + FlagPragma (PES_FUNC, Pragma, B, &AllowRegVarAddr); break; case PRAGMA_REGISTER_VARS: /* TODO: PES_STMT or even PES_EXPR (PES_DECL) maybe? */ - FlagPragma (PES_FUNC, Pragma, &B, &EnableRegVars); + FlagPragma (PES_FUNC, Pragma, B, &EnableRegVars); break; case PRAGMA_RODATA_NAME: /* TODO: PES_STMT or even PES_EXPR maybe? */ - SegNamePragma (PES_FUNC, PRAGMA_RODATA_NAME, &B); + SegNamePragma (PES_FUNC, PRAGMA_RODATA_NAME, B); break; case PRAGMA_SIGNED_CHARS: /* TODO: PES_STMT or even PES_EXPR maybe? */ - FlagPragma (PES_FUNC, Pragma, &B, &SignedChars); + FlagPragma (PES_FUNC, Pragma, B, &SignedChars); break; case PRAGMA_STATIC_LOCALS: /* TODO: PES_STMT or even PES_EXPR (PES_DECL) maybe? */ - FlagPragma (PES_FUNC, Pragma, &B, &StaticLocals); + FlagPragma (PES_FUNC, Pragma, B, &StaticLocals); break; case PRAGMA_WRAPPED_CALL: /* PES_IMM is the only sensible option */ - WrappedCallPragma (PES_IMM, &B); + WrappedCallPragma (PES_IMM, B); break; case PRAGMA_WARN: /* PES_IMM is the only sensible option */ - WarnPragma (PES_IMM, &B); + WarnPragma (PES_IMM, B); break; case PRAGMA_WRITABLE_STRINGS: /* TODO: PES_STMT or even PES_EXPR maybe? */ - FlagPragma (PES_FUNC, Pragma, &B, &WritableStrings); + FlagPragma (PES_FUNC, Pragma, B, &WritableStrings); break; case PRAGMA_ZPSYM: /* PES_IMM is the only sensible option */ - StringPragma (PES_IMM, &B, MakeZPSym); + StringPragma (PES_IMM, B, MakeZPSym); break; default: @@ -1023,27 +1018,26 @@ static void ParsePragmaString (void) } /* Closing paren expected */ - SB_SkipWhite (&B); - if (SB_Get (&B) != ')') { + SB_SkipWhite (B); + if (SB_Get (B) != ')') { Error ("')' expected"); goto ExitPoint; } - SB_SkipWhite (&B); + SB_SkipWhite (B); /* Allow an optional semicolon to be compatible with the old syntax */ - if (SB_Peek (&B) == ';') { - SB_Skip (&B); - SB_SkipWhite (&B); + if (SB_Peek (B) == ';') { + SB_Skip (B); + SB_SkipWhite (B); } /* Make sure nothing follows */ - if (SB_Peek (&B) != '\0') { + if (SB_Peek (B) != '\0') { Error ("Unexpected input following pragma directive"); } ExitPoint: /* Release the string buffers */ - SB_Done (&B); SB_Done (&Ident); } @@ -1082,8 +1076,24 @@ void ConsumePragma (void) */ PragmaErrorSkip (); } else { + /* Pragmas that have the C99 _Pragma operator in the source code + ** (instead of #pragma that was converted to _Pragma by the + ** preprocessor) have the argument not preprocessed. We need to do + ** that here, since it may contain comments. Weird but legal C. Pragmas + ** that were converted from #pragma are already preprocessed but doing + ** it twice won't harm. + */ + StrBuf In = AUTO_STRBUF_INITIALIZER; + StrBuf Out = AUTO_STRBUF_INITIALIZER; + SB_Append (&In, GetLiteralStrBuf (CurTok.SVal)); + TranslationPhase3 (&In, &Out); + SB_Done (&In); + /* Parse the pragma */ - ParsePragmaString (); + ParsePragmaString (&Out); + + /* Free the string buffer */ + SB_Done (&Out); } --InPragmaParser; diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index bc21a69d1..bc3b532fa 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -157,11 +157,6 @@ struct HiddenMacro { -static void TranslationPhase3 (StrBuf* Source, StrBuf* Target); -/* Mimic Translation Phase 3. Handle old and new style comments. Collapse -** non-newline whitespace sequences. -*/ - static void PreprocessDirective (StrBuf* Source, StrBuf* Target, unsigned ModeFlags); /* Preprocess a single line. Handle specified tokens and operators, remove ** whitespace and comments, then do macro replacement. @@ -3338,7 +3333,22 @@ void HandleSpecialMacro (Macro* M, const char* Name) -static void TranslationPhase3 (StrBuf* Source, StrBuf* Target) +static void PreprocessDirective (StrBuf* Source, StrBuf* Target, unsigned ModeFlags) +/* Preprocess a single line. Handle specified tokens and operators, remove +** whitespace and comments, then do macro replacement. +*/ +{ + MacroExp E; + + SkipWhitespace (0); + InitMacroExp (&E); + ReplaceMacros (Source, Target, &E, ModeFlags | MSM_IN_DIRECTIVE); + DoneMacroExp (&E); +} + + + +void TranslationPhase3 (StrBuf* Source, StrBuf* Target) /* Mimic Translation Phase 3. Handle old and new style comments. Collapse ** non-newline whitespace sequences. */ @@ -3384,21 +3394,6 @@ static void TranslationPhase3 (StrBuf* Source, StrBuf* Target) -static void PreprocessDirective (StrBuf* Source, StrBuf* Target, unsigned ModeFlags) -/* Preprocess a single line. Handle specified tokens and operators, remove -** whitespace and comments, then do macro replacement. -*/ -{ - MacroExp E; - - SkipWhitespace (0); - InitMacroExp (&E); - ReplaceMacros (Source, Target, &E, ModeFlags | MSM_IN_DIRECTIVE); - DoneMacroExp (&E); -} - - - void Preprocess (void) /* Preprocess lines count of which is affected by directives */ { diff --git a/src/cc65/preproc.h b/src/cc65/preproc.h index 44e35f30e..c8fc67ddc 100644 --- a/src/cc65/preproc.h +++ b/src/cc65/preproc.h @@ -68,6 +68,11 @@ struct IFile; void HandleSpecialMacro (Macro* M, const char* Name); /* Handle special "magic" macros that may change */ +void TranslationPhase3 (StrBuf* Source, StrBuf* Target); +/* Mimic Translation Phase 3. Handle old and new style comments. Collapse +** non-newline whitespace sequences. +*/ + void Preprocess (void); /* Preprocess a line */ diff --git a/test/val/bug2231.c b/test/val/bug2231.c new file mode 100644 index 000000000..96a856a8d --- /dev/null +++ b/test/val/bug2231.c @@ -0,0 +1,10 @@ +_Pragma("message/*Comment1*/ ( /*Comment2*/\"test message\" /*Comment3*/)") +/* We have no pragma without parenthesis but if there would be one, the +** following should also work: +*/ +/* _Pragma("once// Comment") */ + +int main(void) +{ + return 0; +} From ec67b49d7d9e95e12c46005650f2c62e14004f76 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 17:37:39 +0200 Subject: [PATCH 692/707] Change notification message used when pointing to the macro an error comes from. --- src/ca65/error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ca65/error.c b/src/ca65/error.c index 7e1457964..78941b5c2 100644 --- a/src/ca65/error.c +++ b/src/ca65/error.c @@ -148,7 +148,7 @@ static void AddNotifications (const Collection* LineInfos) break; case LI_TYPE_MACRO: - Msg = "Macro was defined here"; + Msg = "Expanded from macro here"; break; case LI_TYPE_MACPARAM: From b65ee13e8c005b431638913a438a036630e4f68a Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 17:46:39 +0200 Subject: [PATCH 693/707] Fix the tests. --- test/asm/listing/ref/010-paramcount.err2-ref | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/asm/listing/ref/010-paramcount.err2-ref b/test/asm/listing/ref/010-paramcount.err2-ref index 304c9de61..fee657dbf 100644 --- a/test/asm/listing/ref/010-paramcount.err2-ref +++ b/test/asm/listing/ref/010-paramcount.err2-ref @@ -1,9 +1,9 @@ 010-paramcount.s:18: Warning: User warning: r1 is blank! -010-paramcount.s:14: Note: Macro was defined here -010-paramcount.s:8: Note: Macro was defined here +010-paramcount.s:14: Note: Expanded from macro here +010-paramcount.s:8: Note: Expanded from macro here 010-paramcount.s:19: Warning: User warning: r1 is blank! -010-paramcount.s:14: Note: Macro was defined here -010-paramcount.s:8: Note: Macro was defined here +010-paramcount.s:14: Note: Expanded from macro here +010-paramcount.s:8: Note: Expanded from macro here 010-paramcount.s:20: Warning: User warning: r1 is blank! -010-paramcount.s:14: Note: Macro was defined here -010-paramcount.s:8: Note: Macro was defined here +010-paramcount.s:14: Note: Expanded from macro here +010-paramcount.s:8: Note: Expanded from macro here From 12bc6ff99eef5b798dc0dd9db9df4af64f233bf8 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:14:34 +0200 Subject: [PATCH 694/707] Make the scrcode macros handle identifiers. --- asminc/apple2.mac | 6 ++++++ asminc/atari.mac | 6 ++++++ asminc/cbm.mac | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/asminc/apple2.mac b/asminc/apple2.mac index b9860c092..c0c957102 100644 --- a/asminc/apple2.mac +++ b/asminc/apple2.mac @@ -36,6 +36,12 @@ ; Just output the character _scrcode arg1 + ; Check for an identifier + .elseif .match (.left (1, {arg1}), identifier) + + ; Just output the identifier + _scrcode arg1 + ; Anything else is an error .else diff --git a/asminc/atari.mac b/asminc/atari.mac index 3916254d0..952af8732 100644 --- a/asminc/atari.mac +++ b/asminc/atari.mac @@ -46,6 +46,12 @@ ; Just output the character _scrcode arg1 + ; Check for an identifier + .elseif .match (.left (1, {arg1}), identifier) + + ; Just output the identifier + _scrcode arg1 + ; Anything else is an error .else diff --git a/asminc/cbm.mac b/asminc/cbm.mac index 6d7ac7e8d..5c542b228 100644 --- a/asminc/cbm.mac +++ b/asminc/cbm.mac @@ -40,6 +40,12 @@ ; Just output the character _scrcode arg1 + ; Check for an identifier + .elseif .match (.left (1, {arg1}), identifier) + + ; Just output the identifier + _scrcode arg1 + ; Anything else is an error .else .error "scrcode: invalid argument type" From 070276a1a3baa9fbfca42555b306e0d9caac8436 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Tue, 1 Jul 2025 20:19:19 +0200 Subject: [PATCH 695/707] Add a better description for CPU_HAS_ZPIND and CPU_HAS_STZ. --- doc/ca65.sgml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 0f996ff64..63a1be7e9 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -1681,10 +1681,12 @@ either a string or an expression value. Checks for the capability to push and pop the X and Y registers. <tag><tt>CPU_HAS_ZPIND</tt></tag> - Checks for the availability of the "zeropage indirect" addressing mode. + Checks for the availability of the "zeropage indirect" addressing mode as it + is implemented in the 65SC02 CPU. <tag><tt>CPU_HAS_STZ</tt></tag> - Checks for the availability of the "store zero" instruction. + Checks for the availability of the "store zero" instruction as it is + implemented in the 65SC02 CPU. </descrip> From a820538c2a6966fe79f1c95cf44b192554328672 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 2 Jul 2025 15:50:29 +0200 Subject: [PATCH 696/707] Fixed minor typo --- samples/kim1/subs.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/kim1/subs.asm b/samples/kim1/subs.asm index 5b525749e..64713a148 100644 --- a/samples/kim1/subs.asm +++ b/samples/kim1/subs.asm @@ -775,7 +775,7 @@ _DrawChar: sty tempy sta dest_hi lda #0 ; Get the address in font memory where this - sta src_hi ; Petscii chracter lives (after conversion from + sta src_hi ; Petscii character lives (after conversion from lda tempa ; ascii) sty temp2 From 73fa13a23e28a08faca5e18524673caaaf090314 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 2 Jul 2025 15:51:43 +0200 Subject: [PATCH 697/707] Fixed minor typo --- samples/sym1/symDisplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/sym1/symDisplay.c b/samples/sym1/symDisplay.c index 43d18f911..0dafab33d 100644 --- a/samples/sym1/symDisplay.c +++ b/samples/sym1/symDisplay.c @@ -73,7 +73,7 @@ int main (void) { displayable = 1; // Assume character is mapped - switch ( buffer[l] ) { // Put the typed charaters + switch ( buffer[l] ) { // Put the typed characters case '1': // into the display buffer DISPLAY.d6 = DISP_1; // one at a time break; From 75d6efeabf2d3d65c3d12dbc4147e80e51506613 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 2 Jul 2025 15:54:00 +0200 Subject: [PATCH 698/707] Fixed minor typo --- samples/sim65/trace_example.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/sim65/trace_example.c b/samples/sim65/trace_example.c index cd4ec87d7..ebfd89cb1 100644 --- a/samples/sim65/trace_example.c +++ b/samples/sim65/trace_example.c @@ -1,5 +1,5 @@ /* - * Sim65 trace functionailty example. + * Sim65 trace functionality example. * * Description * ----------- From ce35a816a6cce094b5eab7f8d3c387c3efd79959 Mon Sep 17 00:00:00 2001 From: Stefan <stefan.haubenthal@gmail.com> Date: Wed, 2 Jul 2025 15:59:38 +0200 Subject: [PATCH 699/707] Fixed minor typo --- samples/checkversion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/checkversion.c b/samples/checkversion.c index 0e2359f91..d55a72935 100644 --- a/samples/checkversion.c +++ b/samples/checkversion.c @@ -4,7 +4,7 @@ * macro was fixed some time after 2.19 to (VER_MAJOR * 0x100) + VER_MINOR. * * The following strategy can be used to still compare for less or greater versions, - * should this really be necessary or wanted - it is not recommended afterall. + * should this really be necessary or wanted - it is not recommended after all. */ #include <stdio.h> From b4d034bef7982eb8936994e7e8687292b5e39dc1 Mon Sep 17 00:00:00 2001 From: cc65 Owner <41281059+cc65-github@users.noreply.github.com> Date: Wed, 2 Jul 2025 23:10:29 +0200 Subject: [PATCH 700/707] Initial issue templates These are basically the standard templates GH generated - they might help to automatically tag at least bugs vs features --- .github/ISSUE_TEMPLATE/bug_report.md | 23 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..6f7b99efc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,23 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. do '...' +2. then '....' +3. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..eef13d786 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: feature request +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context about the feature request here. From 7b2632563208554928818f3d165118ff621a8d3d Mon Sep 17 00:00:00 2001 From: cc65 Owner <41281059+cc65-github@users.noreply.github.com> Date: Wed, 2 Jul 2025 23:29:49 +0200 Subject: [PATCH 701/707] Create bug_fix_template.md --- .../PULL_REQUEST_TEMPLATE/bug_fix_template.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE/bug_fix_template.md diff --git a/.github/PULL_REQUEST_TEMPLATE/bug_fix_template.md b/.github/PULL_REQUEST_TEMPLATE/bug_fix_template.md new file mode 100644 index 000000000..c8ef84445 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/bug_fix_template.md @@ -0,0 +1,43 @@ +# Bug Fix PR Template + +## Summary + +Provide a concise description of the bug and the fix. + +## Issue Link + +Link to the issue being addressed. + +## Root Cause Analysis + +Detail the root cause of the bug and how it was identified. + +## Changes + +Outline the changes made to fix the bug. + +## Impact + +Describe any implications this fix may have on other parts of the application. + +## Testing Strategy + +Explain how the fix has been tested to ensure the bug is resolved without introducing new issues. + +## Regression Risk + +Assess the risk of regression caused by this fix and steps taken to mitigate it. + +## Checklist + +- [ ] The fix has been locally tested + +- [ ] The fix meets the codestyle requirements + +- [ ] New unit tests have been added to prevent future regressions + +- [ ] The documentation has been updated if necessary + +## Additional Notes + +Any further information needed to understand the fix or its impact. From 087edc336bb4cb25bfee3f59673bf4b3bb5f0175 Mon Sep 17 00:00:00 2001 From: mrdudz <mrdudz@users.noreply.github.com> Date: Wed, 2 Jul 2025 23:47:53 +0200 Subject: [PATCH 702/707] don't try to use multiple templates for the time being --- .../bug_fix_template.md => PULL_REQUEST_TEMPLATE.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{PULL_REQUEST_TEMPLATE/bug_fix_template.md => PULL_REQUEST_TEMPLATE.md} (100%) diff --git a/.github/PULL_REQUEST_TEMPLATE/bug_fix_template.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from .github/PULL_REQUEST_TEMPLATE/bug_fix_template.md rename to .github/PULL_REQUEST_TEMPLATE.md From dd27ec8696224a782154f2cd3a77a3b0428c2fcd Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Thu, 3 Jul 2025 08:54:10 +0200 Subject: [PATCH 703/707] When creating a VICE label file, replace characters in labels that VICE doesn't understand with '_'. Fixes #836. --- src/ld65/dbgsyms.c | 2 +- src/ld65/exports.c | 34 +++++++++++++++++++++++++++++++++- src/ld65/exports.h | 3 +++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/ld65/dbgsyms.c b/src/ld65/dbgsyms.c index 955f0f76d..082954b07 100644 --- a/src/ld65/dbgsyms.c +++ b/src/ld65/dbgsyms.c @@ -532,7 +532,7 @@ void PrintDbgSymLabels (FILE* F) if (GetDbgSym (D, Val) == 0) { /* Emit the VICE label line */ - fprintf (F, "al %06lX .%s\n", Val, GetString (D->Name)); + PrintLabelLine (F, D->Name, Val); /* Insert the symbol into the table */ InsertDbgSym (D, Val); diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 9fa0e4019..f457b5490 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -39,6 +39,7 @@ /* common */ #include "addrsize.h" +#include "chartype.h" #include "check.h" #include "hashfunc.h" #include "lidefs.h" @@ -1006,6 +1007,36 @@ void PrintImportMap (FILE* F) +void PrintLabelLine (FILE* F, unsigned NameId, long Val) +/* Output one label into a vice label file doing some cleanup on the name. */ +{ + /* Get the name */ + const char* N = GetString (NameId); + + /* Cleanup the name. It might be generated by the assembler when creating + ** internally used labels. Such names contain invalid characters to avoid + ** clashes with user input and cannot be read by VICE. + */ + fprintf (F, "al %06lX .", Val); + if (IsAlpha (*N) || *N == '@' || *N == '?' || *N == '_') { + putc (*N, F); + } else { + putc ('_', F); + } + ++N; + while (*N) { + if (IsAlpha (*N) || IsDigit (*N) || *N == '_') { + putc (*N, F); + } else { + putc ('_', F); + } + ++N; + } + putc ('\n', F); +} + + + void PrintExportLabels (FILE* F) /* Print the exports in a VICE label file */ { @@ -1014,7 +1045,8 @@ void PrintExportLabels (FILE* F) /* Print all exports */ for (I = 0; I < ExpCount; ++I) { const Export* E = ExpPool [I]; - fprintf (F, "al %06lX .%s\n", GetExportVal (E), GetString (E->Name)); + PrintLabelLine (F, E->Name, GetExportVal (E)); + } } diff --git a/src/ld65/exports.h b/src/ld65/exports.h index d69e6d7ad..cc7870bc5 100644 --- a/src/ld65/exports.h +++ b/src/ld65/exports.h @@ -195,6 +195,9 @@ void PrintExportMapByValue (FILE* F); void PrintImportMap (FILE* F); /* Print an import map to the given file */ +void PrintLabelLine (FILE* F, unsigned NameId, long Val); +/* Output one label into a vice label file doing some cleanup on the name. */ + void PrintExportLabels (FILE* F); /* Print the exports in a VICE label file */ From 9240ad37ab7440931777ffe93d9a095d8a833028 Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Thu, 3 Jul 2025 09:39:29 +0200 Subject: [PATCH 704/707] Update PULL_REQUEST_TEMPLATE.md cut it down a lot --- .github/PULL_REQUEST_TEMPLATE.md | 36 +------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c8ef84445..5215c557d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,43 +1,9 @@ -# Bug Fix PR Template - ## Summary -Provide a concise description of the bug and the fix. - -## Issue Link - -Link to the issue being addressed. - -## Root Cause Analysis - -Detail the root cause of the bug and how it was identified. - -## Changes - -Outline the changes made to fix the bug. - -## Impact - -Describe any implications this fix may have on other parts of the application. - -## Testing Strategy - -Explain how the fix has been tested to ensure the bug is resolved without introducing new issues. - -## Regression Risk - -Assess the risk of regression caused by this fix and steps taken to mitigate it. +Provide description of the bug (if an issue exists, link to it) and the fix. ## Checklist -- [ ] The fix has been locally tested - - [ ] The fix meets the codestyle requirements - - [ ] New unit tests have been added to prevent future regressions - - [ ] The documentation has been updated if necessary - -## Additional Notes - -Any further information needed to understand the fix or its impact. From 2c4b3a485e8a1aeb951aaf97237d41f4a5fcdacd Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Thu, 3 Jul 2025 09:44:57 +0200 Subject: [PATCH 705/707] Update bug_report.md cut down --- .github/ISSUE_TEMPLATE/bug_report.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 6f7b99efc..ddde4f5d3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -8,16 +8,7 @@ assignees: '' --- **Describe the bug** -A clear and concise description of what the bug is. +Please tell us what you did, what happened, and what you expected to happen instead. **To Reproduce** -Steps to reproduce the behavior: -1. do '...' -2. then '....' -3. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Additional context** -Add any other context about the problem here. +If it isnt obvious how to reproduce the problem, please give use some detailed instructions on how to reproduce it. Ideally provide a testcase (program) that we can put into the testbench later. From ca329c975b0c1fa852ea5ff577cc7bbd8b599b6e Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Thu, 3 Jul 2025 09:46:43 +0200 Subject: [PATCH 706/707] Update feature_request.md cut down (a lot) --- .github/ISSUE_TEMPLATE/feature_request.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index eef13d786..09cadc0ba 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -12,9 +12,3 @@ A clear and concise description of what the problem is. Ex. I'm always frustrate **Describe the solution you'd like** A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context about the feature request here. From 9194d9e309f0813927f4b4fc27783650abd08f8a Mon Sep 17 00:00:00 2001 From: Bob Andrews <mrdudz@users.noreply.github.com> Date: Thu, 3 Jul 2025 11:09:03 +0200 Subject: [PATCH 707/707] Update bug_report.md --- .github/ISSUE_TEMPLATE/bug_report.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ddde4f5d3..75d9b00d3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -6,6 +6,8 @@ labels: bug assignees: '' --- +**Compiler and OS** +It is important to know what version of the compiler/assembler you used (call it with --version to get this info). Sometimes we also need to know what OS you are using. **Describe the bug** Please tell us what you did, what happened, and what you expected to happen instead.